• 技术文章 >后端开发 >php教程

    json - 如何看待/纠正php的array_key_exists函数bug?

    2016-06-06 20:22:25原创602

    array_key_exists(0或'0',json_decode('{"0":0})===false

    array_key_exists(0或'0',(object)array(0))===true

    不能说这是json_decode的锅,
    因为二者var_dump出来虽然一个索引是数字一个是字符串,但是毕竟都存在,而且->{0或'0'}访问没区别。

    实在不行当然只能用第三方json函数,然而php中空字符串也不能作为索引,而json规则中并没有这一条。

    真的怕了,php坑太无规律,哪天用着用着又可能有新雷。。

    回复内容:

    array_key_exists(0或'0',json_decode('{"0":0})===false

    array_key_exists(0或'0',(object)array(0))===true

    不能说这是json_decode的锅,
    因为二者var_dump出来虽然一个索引是数字一个是字符串,但是毕竟都存在,而且->{0或'0'}访问没区别。

    实在不行当然只能用第三方json函数,然而php中空字符串也不能作为索引,而json规则中并没有这一条。

    真的怕了,php坑太无规律,哪天用着用着又可能有新雷。。

    RTFM

    http://php.net/array_key_exists

    For backward compatibility reasons, array_key_exists() will also
    return TRUE if key is a property defined within an object given as
    array. This behaviour should not be relied upon, and care should be
    taken to ensure that array is an array. To check whether a property
    exists in an object, use property_exists().

    http://php.net/manual/en/language.types.object.php#language.types.object.casting

    An array converts to an object with properties named by keys and
    corresponding values, with the exception of numeric keys which will be
    inaccessible unless iterated.

    呃,陆续有人赞这个回答,但是在评论区交流了一番之后觉得一开始的回答是有问题的,感到有些惭愧,所以编辑这个回答

    如原答案所说,array_key_exists应该是检查数组中某个key是否存在的,但是由于历史原因,array_key_exists支持第二个参数为对象,但这是一个向下兼容的设计,官方文档建议不要依赖这个实现

    This behaviour should not be relied upon, and care should be taken to ensure that array is an array.

    题主在评论里提到了json_decode转换为数组之后再转换成json会面临空数组究竟是对应成javascript的空对象还是空数组的问题,也许可以看看json_encode的时候加上 JSON_FORCE_OBJECT 这个选项:

    php > echo json_encode([]);
    []
    php > echo json_encode([], JSON_FORCE_OBJECT);
    {}
    php > echo json_encode(['hello,world']);
    ["hello,world"]
    php > echo json_encode(['hello,world'], JSON_FORCE_OBJECT);
    {"0":"hello,world"}

    不过这个就变成所有的空数组都强制转换为对象了,也不见得就一定好用,怎么用就看题主自己取舍了(或者在js端多加一个额外的判断?)

    下面是原回答


    json_decode 第二个参数不带的话,返回的是一个对象,根本不是数组

    以下是php shell执行结果

    php > var_dump(json_decode("{\"0\":0}"));
    class stdClass#1 (1) {
      public $0 =>
      int(0)
    }
    php > var_dump(json_decode("{\"0\":0}", false));
    class stdClass#1 (1) {
      public $0 =>
      int(0)
    }
    php > var_dump(json_decode("{\"0\":0}", true));
    array(1) {
      [0] =>
      int(0)
    }
    php > var_dump(array_key_exists(0, json_decode("{\"0\":0}", true)));
    bool(true)
    php > var_dump(array_key_exists(0, json_decode("{\"0\":0}", false)));
    bool(false)
    php > var_dump(array_key_exists('0', json_decode("{\"0\":0}")));
    bool(false)
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:php php-坑 json
    上一篇:关于is_resource()方法的问题问题 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • 一文详解PHP实现职责链设计模式(附代码示例)• php实现通过JSON RPC与go通讯(附代码)• 浅析怎么使用PHP做异步爬取数据• PHP8.3要有新函数了!(json_validate函数说明)• 设计API接口时,要注意这些地方!
    1/1

    PHP中文网