php json字符串解析中的引號問題


背景

json字符串的解析非常常見,但是php中單雙引號含義不同以及各種字符串處理函數對json字符串的處理常常會導致json_decode()函數解析失敗。這里借着工作中遇到的一個問題整理一下相關的知識點,做個沉淀。

php中的單雙引號

區別

單引號中的內容會被認為就是純文本。雙引號中的內容則會經過解析,其中的變量、斜杠轉義符等會被處理為對應的值。

關於用法

在php7以前的版本中使用單引號處理速度比使用雙引號速度要快,但是php7以后兩者已經沒有區別。對於需要進行變量替換的字符串只能使用雙引號,對於純字符串鳥哥在他的PHP單引號和雙引號的區別文章中還是建議大家使用雙引號,理由是C/C++中雙引號表示字符串以及HTML中屬性值需要使用雙引號包裹,與別的語言習慣保持一致。

問題說明

解析一個前端通過post form表單提交過來的json字符串,但是一直報json_decode()返回NULL,調用ljson_last_error()返回4,調用json_last_error_msg()返回Syntax error,但是json字符串能夠被在線的json解析器正確處理。

排查

前端輸入的字符串如下

[{"name":"測試添加車主","mobile":"13322232214"},{"name":"測試添加車主2","mobile":"13322232215"}]

將接收到的字符串使用var_dump()打印出來

string '[{\"name\":\"測試添加車主\",\"mobile\":\"13322232214\"},{\"name\":\"測試添加車主2\",\"mobile\":\"13322232215\"}]' (length=124)

打印出的字符串是單引號包含並且內部包含了轉義字符串\"

將字符串復制出來,使用雙引號包裹在進行解析

<?php
$str = "[{\"name\":\"測試添加車主\",\"mobile\":\"13322232214\"},{\"name\":\"測試添加車主2\",\"mobile\":\"13322232215\"}]";
var_dump($str);
$array = json_decode($str, true);
var_dump($array);
var_dump(json_last_error());
var_dump(json_last_error_msg());

測試結果如下

PS D:\php\WWW> php .\test.php
string(108) "[{"name":"測試添加車主","mobile":"13322232214"},{"name":"測試添加車主2","mobile":"13322232215"}]"
array(2) {
  [0]=>
  array(2) {
    ["name"]=>
    string(18) "測試添加車主"
    ["mobile"]=>
    string(11) "13322232214"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(19) "測試添加車主2"
    ["mobile"]=>
    string(11) "13322232215"
  }
}
int(0)
string(8) "No error"

這里可以觀察到打印出來的json字符串被雙引號包裹,並且字符串內部的轉義字符\"已經被處理為"json_decode()函數也可以正確解析該json。因此這里可以確定問題就是接收到字符串內部含有轉義字符\"但是外部不是使用雙引號包裹的。

解決

追了一下源代碼發現由於安全原因所有的輸入都經過addslashes()函數處理防止sql注入,這里使用stripcslashes()函數去掉json字符串中的反斜杠就解決了該問題。

總結php json_encode函數解析json字符串中的引號問題

  1. 內層的索引和值必須是雙引號
  2. 外層是單引號時,內層的雙引號不需要轉義(不能是\",必須是"
  3. 外層是雙引號時,內層的雙引號需要轉義(不能是",必須是\"

參考文章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM