以前同事問了我一個有趣的問題,說爲何這個 json 字符串從緩存裏讀出來能夠解析,可是做爲一個 php 變量卻解析錯誤呢?php
先看一個我已經簡化了的例子json
$str = "\\"; $j = json_encode($str); echo $j, PHP_EOL; echo json_decode($j), PHP_EOL;
輸出緩存
"\\" \
若是你直接把輸出的 json 字符串賦值給一個 php 字符串變量的話,好玩的事情就發生了架構
$conf = <<<EOD "\\" EOD; // heredoc // $conf = '"\\"'; // 單引號 // $conf = "\"\\\""; // 雙引號 var_dump(json_decode($conf, true)); echo json_last_error_msg(), PHP_EOL;
輸出.net
NULL Control character error, possibly incorrectly encoded
你就會發現,無論怎麼搞,json_decode 老是失敗的,而後我慢慢的把 json 字符串抽繭剝絲,最後只剩下「\\」,發現問題出在這裏。code
乍一看,這個字符串並無什麼特別之處,可是在我把它 echo 以後,終於搞明白到底爲何一直 json_decode 失敗了字符串
$conf = <<<EOD "\\" EOD; echo $conf,PHP_EOL;
輸出get
\
「\\」 這貨被轉義了,而後這就再也不是一個正常的 json 字符串了,因此 json_decode 就會失敗,那麼才能讓它正確的被 decode 呢?看下面這段代碼string
$conf = <<<'EOD' "\\" EOD; // nowdoc var_dump(json_decode($conf, true)); echo json_last_error_msg(), PHP_EOL;
輸出ast
string(1) "\" No error
咱們使用 nowdoc (http://php.net/manual/zh/language.types.string.php#language.types.string.syntax.nowdoc),這樣就不會被轉義了。
就象 heredoc 結構相似於雙引號字符串,Nowdoc 結構是相似於單引號字符串的。Nowdoc 結構很象 heredoc 結構,可是 nowdoc 中不進行解析操做。這種結構很適合用於嵌入 PHP 代碼或其它大段文本而無需對其中的特殊字符進行轉義。
更多架構、PHP、GO相關踩坑實踐技巧請關注個人公衆號:PHP架構師