开发过程当中常常碰到要把前端的json格式的数据传递到后端php,php作一些业务处理后把数据存到mysql,而后,php再从mysql中取出数据返回到前端。虽然这是一个再基础不过的处理过程,但仍是有很多问题须要认真研究。下面从几个环节看看可能出现的各类问题。php
假设前端传入的数据是: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中有哪些特殊字符,看下图:
解决这个问题的思路是在进行urlencode以前,先在这些特殊字符前加上反斜杠,这样urldecode以后就有了转义的反斜杠。
$str = str_replace(array("\\", '"', "\n", "\r", "\t"), array("\\\\", '\"', "\\n", "\\r", "\\t"), $str);
执行这个操做时要注意,必须先替换反斜杠,再替换其它特殊字符,不然,给特殊字符添加的反斜杠又会被再加上反斜杠。另外一个问题注意要用双引号,php中单引号的内容不会转义,双引号才会。
总结:经过上述3个方面的处理,应该能够正确的处理json的问题了。可是,也许应该直接写一个拼接json串的方法,完全不用json_encode,这样效率更高些,之后有机会试试。