json_encode()为null,引发的json相关总结

上次使用 json_decode() 解析从前端复制过来的json数据,发现怎么都解析不出来,查看json格式,发现没问题啊!

/*
    注意:
        之前碰过同样的问题,有可能是实体引起的!但那应该是针对从其他地方接收到的变量,而非是复制过来的字符串!
        碰到这种问题,可以使用 html_entity_decode()
 */

下面黏贴下,我复制过的大概的字符串:
    $str = "[{'name':'dongxuemin','age':30},{'name':'yangyaping','age':30}]";
反正让我看,我是真的看不出错误!

下面,揭晓答案:
    上面的错误是:json字符串的格式不正确!
    正确的是:

        ******
            json中的 '键' 和 '值',都必须是双引号("),在json里只能用双引号表示字符串。
        ******

    JSON字符串严格要求!!!说实话,没细看过json,我是真心不知道这个!上面的还是我花了不少时间测出来的。
    先定义一个相同的数组:
        $a = [
            ['name' => 'dongxuemin', 'age' => 30],
            ['name' => 'yangyaping', 'age' => 30],
        ];
        echo json_encode($a);   // 输出:[{"name":"dongxuemin","age":30},{"name":"yangyaping","age":30}]
    然后和之前的字符串一个一个对比,整了好久的!

PHP手册的例子,有一个就指出了几个经常错误的原因:
    <?php

    // the following strings are valid JavaScript but not valid JSON(下面字符是有效的js字符串,但无效的JSON)

    // the name and value must be enclosed in double quotes
    // single quotes are not valid(对象的键和值,必须是 '双引号')
    $bad_json = "{ 'bar': 'baz' }";
    json_decode($bad_json); // null

    // the name must be enclosed in double quotes(对象的键,必须使用双引号,js中可不添加引号,但json不可以)
    $bad_json = '{ bar: "baz" }';
    json_decode($bad_json); // null

    // trailing commas are not allowed(最后面的 ',' 多余)
    $bad_json = '{ bar: "baz", }';
    json_decode($bad_json); // null
    ?>

找到问题后,就想对 JSON 稍微了解一点,就找了点文章看看:
    具体就不总结了,有点晚。其实下面几篇文章总结的都不错(自己看下)


参考文章:
    http://php.net/manual/zh/book.json.php(PHP文档的JSON扩展)
    http://www.faqs.org/rfcs/rfc7159.html(PHP实现的JSON标准)
    http://www.json.org/json-zh.html(JSON官网??)
    http://www.ruanyifeng.com/blog/2009/05/data_types_and_json.html(阮一峰写的博客,真的是精辟!有时间应该全部拜读一遍!)
    http://www.cnblogs.com/jamesbd/p/4185342.html
    http://www.cnblogs.com/pinganzi/p/6229369.html
    http://blog.csdn.net/leedaning/article/details/70210770


PHP官网的JSON,也了解了下:
    4个函数:
        json_encode($value [, $options = 0 [, $depth = 512]])
            $value - 可以是除了 'resource' 类型外的其他7种类型
                     编码必须是 'UTF-8'
            $options - 可以使用多个
                JSON_HEX_QUOT -
                JSON_HEX_TAG - 
                JSON_HEX_AMP - 
                ...
                我们平常说,编码中文,不乱码,可以使用 'JSON_UNESCAPED_UNICODE'
            $depth - 设置最大深度(不用管)

        json_decode($json [, $assoc = false [, $depth = 512 [, $options = []]]])
            $json - 要解析的json字符串
                    编码必须是 'UTF-8'
            $assoc - 是否返回关联数组,默认是false,表示返回对象(assoc - 从单词上就知道是 '关联' 意思)
            $depth - 指定递归深度(不用管)
            $options - 只有2个
                JSON_BIGINT_AS_STRING - 用于将大整数转为字符串而非默认的float类型
                JSON_OBJECT_AS_ARRAY - 与将assoc设置为 TRUE 有相同的效果(返回关联数组)

        // 2个都是,返回json编码或解码时,最后发生的错误
        json_last_error()       // 返回的是 '错误码'
        json_last_error_msg()   // 返回的是 '错误详情'

        // 错误码
        JSON_ERROR_NONE - 无错误
        JSON_ERROR_DEPTH - 到达了最大堆栈深度
        JSON_ERROR_STATE_MISMATCH - 无效或异常的 JSON
        JSON_ERROR_CTRL_CHAR - 控制字符错误,可能是编码不对
        JSON_ERROR_SYNTAX - 语法错误
        JSON_ERROR_UTF8 - 异常的 UTF-8 字符,也许是因为不正确的编码
        ... 还有更多,自己看文档 ...

    JsonSerializable - JSON序列化接口
        /*
            注意:
                这个才是要解释的重点!
         */
        接口定义:
            JsonSerializable {
                // 指定需要被序列化成 JSON 的数据(指定传递给 json_encode($value) 的$value内容)
                abstract public mixed jsonSerialize ( void )
            }
        解释下这个接口存在的意义:
            默认情况下,json_encode()一个对象,会将对象的所有属性,编码为一个json对象。例如:
                class prev {
                    $name = 'dongxuemin';
                    $age = 30;
                    function a(){

                    }
                    ...
                }
                json_encode(new prev());        // 输出 "{'name': 'dongxuemin', 'age': 30}"
            如果定义一个类,实现了该接口,并定义了方法
                class now implements JsonSerializable{
                    $name = 'dongxuemin';
                    $age = 30;
                    public function jsonSerialize(){
                        return '我才是要编码的数据';
                    }
                    ...
                }
                json_encode(new now());        // 输出 "我才是要编码的数据"
            以上2个例子,我们很明显就知道区别了。实现了 JsonSerializable 接口的类,json_encode()时,会去查找 'jsonSerialize()' 方法,有的话,会将返回的内容,作为json_encode()的输入,而不是之前默认的将对象的属性作为json_encode()的输入

        laravel的数据库对象就使用了它(好多优秀的框架,应该都实现了它),toJson()方法就是
    参考文章:
        http://www.laruence.com/2011/10/10/2204.html(PHP国内第一人)
        https://segmentfault.com/a/1190000010449725


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值