天天看点

***在PHP语言中使用JSON和将json还原成数组(json_decode()的常见错误)

从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码。

一、json_encode()

<code>&lt;?php</code>

<code>$arr</code> <code>= </code><code>array</code> <code>(</code><code>'a'</code><code>=&gt;1,</code><code>'b'</code><code>=&gt;2,</code><code>'c'</code><code>=&gt;3,</code><code>'d'</code><code>=&gt;4,</code><code>'e'</code><code>=&gt;5);</code>

<code>echo</code> <code>json_encode(</code><code>$arr</code><code>);</code>

<code>?&gt;</code>

输出

<code>{</code><code>"a"</code><code>:1,</code><code>"b"</code><code>:2,</code><code>"c"</code><code>:3,</code><code>"d"</code><code>:4,</code><code>"e"</code><code>:5}</code>

再看一个对象转换的例子:

<code>$obj</code><code>-&gt;body           = </code><code>'another post'</code><code>;</code>

<code>$obj</code><code>-&gt;id             = 21;</code>

<code>$obj</code><code>-&gt;approved       = true;</code>

<code>$obj</code><code>-&gt;favorite_count = 1;</code>

<code>$obj</code><code>-&gt;status         = NULL;</code>

<code>echo</code> <code>json_encode(</code><code>$obj</code><code>);</code>

 输出

<code>{</code>

<code>   </code><code>"body"</code><code>:</code><code>"another post"</code><code>,</code>

<code> </code>

<code>   </code><code>"id"</code><code>:21,</code>

<code>   </code><code>"approved"</code><code>:true,</code>

<code>   </code><code>"favorite_count"</code><code>:1,</code>

<code>   </code><code>"status"</code><code>:null</code>

<code> }</code>

 由于json只接受utf-8编码的字符,所以json_encode()的参数必须是utf-8编码,否则会得到空字符或者null。当中文使用GB2312编码,或者外文使用ISO-8859-1编码的时候,这一点要特别注意。

二、索引数组和关联数组

PHP支持两种数组,一种是只保存"值"(value)的索引数组(indexed array),另一种是保存"名值对"(name/value)的关联数组(associative array)。

由于javascript不支持关联数组,所以json_encode()只将索引数组(indexed array)转为数组格式,而将关联数组(associative array)转为对象格式。

比如,现在有一个索引数组

<code>$arr</code> <code>= Array(</code><code>'one'</code><code>, </code><code>'two'</code><code>, </code><code>'three'</code><code>);</code>

<code>[</code><code>"one"</code><code>,</code><code>"two"</code><code>,</code><code>"three"</code><code>]</code>

 如果将它改为关联数组:

<code>$arr</code> <code>= Array(</code><code>'1'</code><code>=&gt;</code><code>'one'</code><code>, </code><code>'2'</code><code>=&gt;</code><code>'two'</code><code>, </code><code>'3'</code><code>=&gt;</code><code>'three'</code><code>);</code>

 输出变为

<code>{</code><code>"1"</code><code>:</code><code>"one"</code><code>,</code><code>"2"</code><code>:</code><code>"two"</code><code>,</code><code>"3"</code><code>:</code><code>"three"</code><code>}</code>

 注意,数据格式从"[]"(数组)变成了"{}"(对象)。

如果你需要将"索引数组"强制转化成"对象",可以这样写

<code>json_encode( (object)</code><code>$arr</code> <code>);</code>

 或者

<code>json_encode ( </code><code>$arr</code><code>, JSON_FORCE_OBJECT );</code>

 三、类(class)的转换

下面是一个PHP的类:

<code>class</code> <code>Foo {</code>

<code>  </code><code>const</code>     <code>ERROR_CODE = </code><code>'404'</code><code>;</code>

<code>  </code><code>public</code>    <code>$public_ex</code> <code>= </code><code>'this is public'</code><code>;</code>

<code>  </code><code>private</code>   <code>$private_ex</code> <code>= </code><code>'this is private!'</code><code>;</code>

<code>  </code><code>protected</code> <code>$protected_ex</code> <code>= </code><code>'this should be protected'</code><code>;</code>

<code>  </code><code>public</code> <code>function</code> <code>getErrorCode() {</code>

<code>    </code><code>return</code> <code>self::ERROR_CODE;</code>

<code>  }</code>

<code>}</code>

 现在,对这个类的实例进行json转换:

<code>$foo</code> <code>= </code><code>new</code> <code>Foo;</code>

<code>$foo_json</code> <code>= json_encode(</code><code>$foo</code><code>);</code>

<code>echo</code> <code>$foo_json</code><code>;</code>

 输出结果是

<code>{</code><code>"public_ex"</code><code>:</code><code>"this is public"</code><code>}</code>

 可以看到,除了公开变量(public),其他东西(常量、私有变量、方法等等)都遗失了。

四、json_decode()

该函数用于将json文本转换为相应的PHP数据结构。下面是一个例子:

<code>$json</code> <code>= </code><code>'{"foo": 12345}'</code><code>;</code>

<code>$obj</code> <code>= json_decode(</code><code>$json</code><code>);</code>

<code>print</code> <code>$obj</code><code>-&gt;{</code><code>'foo'</code><code>}; </code><code>// 12345</code>

 通常情况下,json_decode()总是返回一个PHP对象,而不是数组。比如:

<code>$json</code> <code>= </code><code>'{"a":1,"b":2,"c":3,"d":4,"e":5}'</code><code>;</code>

<code>var_dump(json_decode(</code><code>$json</code><code>));</code>

 结果就是生成一个PHP对象:

<code>object(stdClass)#1 (5) {</code>

<code>  [</code><code>"a"</code><code>] =&gt; int(1)</code>

<code>  [</code><code>"b"</code><code>] =&gt; int(2)</code>

<code>  [</code><code>"c"</code><code>] =&gt; int(3)</code>

<code>  [</code><code>"d"</code><code>] =&gt; int(4)</code>

<code>  [</code><code>"e"</code><code>] =&gt; int(5)</code>

 如果想要强制生成PHP关联数组,json_decode()需要加一个参数true:

<code>  </code>

<code> var_dump(json_decode(</code><code>$json</code><code>,true));</code>

 结果就生成了一个关联数组:

<code>array</code><code>(5) {</code>

<code> </code><code>  [</code><code>"a"</code><code>] =&gt; int(1)</code>

<code> </code><code>  [</code><code>"b"</code><code>] =&gt; int(2)</code>

<code> </code><code>  [</code><code>"c"</code><code>] =&gt; int(3)</code>

<code> </code><code>  [</code><code>"d"</code><code>] =&gt; int(4)</code>

<code> </code><code>  [</code><code>"e"</code><code>] =&gt; int(5)</code>

五、json_decode()的常见错误

下面三种json写法都是错的,你能看出错在哪里吗?

<code>$bad_json</code> <code>= </code><code>"{ 'bar': 'baz' }"</code><code>;</code>

<code>$bad_json</code> <code>= </code><code>'{ bar: "baz" }'</code><code>;</code>

<code>$bad_json</code> <code>= </code><code>'{ "bar": "baz", }'</code><code>;</code>

 对这三个字符串执行json_decode()都将返回null,并且报错。

第一个的错误是,json的分隔符(delimiter)只允许使用双引号,不能使用单引号。第二个的错误是,json名值对的"名"(冒号左边的部分),任何情况下都必须使用双引号。第三个的错误是,最后一个值之后不能添加逗号(trailing comma)。

另外,json只能用来表示对象(object)和数组(array),如果对一个字符串或数值使用json_decode(),将会返回null。

<code>var_dump(json_decode(</code><code>"Hello World"</code><code>)); </code><code>//null</code>

如何联系我:【万里虎】www.bravetiger.cn

【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起)

【博客】http://www.cnblogs.com/kenshinobiy/