JS+PHP+MYSQL處理JSON的全面總結

開發過程當中常常碰到要把前端的json格式的數據傳遞到後端php,php作一些業務處理後把數據存到mysql,而後,php再從mysql中取出數據返回到前端。雖然這是一個再基礎不過的處理過程,但仍是有很多問題須要認真研究。下面從幾個環節看看可能出現的各類問題。php

存入mysql前

假設前端傳入的數據是:html

{"html":"a"b"}

json_decode後,PHP對象是:前端

object(stdClass)#3 (1) {
  ["html"]=>
  string(3) "a"b"
}

注意要處理的數據中包含了雙引號,這個字符在json中須要轉意,在mysql中也須要轉意。假如要把這個對象轉換爲json串存入mysql,先用json_encode處理:mysql

{"html":"a\"b"}

注意:雙引號前面加上了反斜槓。再用real_escape_string處理:sql

{\"html\":\"a\\\"b\"}

注意:全部的雙引號和反斜槓(json_encode加上的那個)都加上了反斜槓。存入數據庫的內容:數據庫

{"html":"a\"b"}

按照這樣的過程處理數據是正常的,從數據庫取出後,用json_decode能夠恢復原來的數據。可是若是在存入數據庫前沒有作real_escape_string的處理,直接存入數據庫,那麼數據庫的內容:json

{"html":"a"b"}

注意:這時a和b之間的雙引號前面的反斜槓被mysql去掉了,數據庫中的內容已經不是合法的json串。後端

結論1:把json存入mysql數據庫前必須作1次real_escape_string編碼

處理中文

json_encode處理包含中文的字符串時,會將中文字符轉換爲unicode的形式(uXXXX),並且經過json_decode是不能恢復的。例如處理前的對象是:url

object(stdClass)#3 (1) {
  ["html"]=>
  string(6) "你好"
}

json_encode後的json串是:

{"html":"\u4f60\u597d"}

real_escape_string處理後存入mysql數據庫:

{"html":"\u4f60\u597d"}

這樣帶來的問題是在mysql中就沒法直接對這個串作處理,例如:

like '%你%'

解決這個問題的方法是,在進行json_encode前先對要處理的對象的值用urlencode處理一遍,json_encode後再用urldecode恢復回來,這樣的到json串是:

{"html":"你好"}

結論2:經過urlencode解決json_encode將中文字符編碼爲unicode的形式。

處理特殊字符

經過urlencode解決中文問題會帶來新問題,json的特殊字符處理。例如:雙引號會被編碼爲「%22」,json_encode不會對%22特殊處理,【你"好】本應該編碼爲【你\"好】,對雙引號進行轉義,可是結果是【你"好】,已經不是一個合法的json字符串。

解決這個問題前首先要搞清楚json中有哪些特殊字符,看下圖:
clipboard.png

來自:http://www.json.org/

解決這個問題的思路是在進行urlencode以前,先在這些特殊字符前加上反斜槓,這樣urldecode以後就有了轉義的反斜槓。

$str = str_replace(array("\\", '"', "\n", "\r", "\t"), array("\\\\", '\"', "\\n", "\\r", "\\t"), $str);

執行這個操做時要注意,必須先替換反斜槓,再替換其它特殊字符,不然,給特殊字符添加的反斜槓又會被再加上反斜槓。另外一個問題注意要用雙引號,php中單引號的內容不會轉義,雙引號纔會。

總結:經過上述3個方面的處理,應該能夠正確的處理json的問題了。可是,也許應該直接寫一個拼接json串的方法,完全不用json_encode,這樣效率更高些,之後有機會試試。

相關文章
相關標籤/搜索