跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • PHP 里 empty((object)[])是 false 还是 true?
未分類
9 7 月 2020

PHP 里 empty((object)[])是 false 还是 true?

PHP 里 empty((object)[])是 false 还是 true?

資深大佬 : sagaxu 18

这么设计是否符合直觉?
大佬有話說 (32)

  • 資深大佬 : ksaa0096329

    false
    有时间来问,早就测试出来了.
    再说了 你这种写法有什么意义.

  • 資深大佬 : iamverylovely

    符合啊,不然又要 emptyObject();

  • 資深大佬 : zarte

    false 一定是用了那些查询回来是 obj 的 orm 了吧,哈哈。

  • 資深大佬 : lovecy

    empty,只针对
    0,空 string,空数组,false,’0’,null,未定义变量
    这几种返回 true,其他都是 false
    毕竟 object 判断是比较复杂的,除非新增一个__empty 魔术方法

  • 資深大佬 : jhdxr

    作为一个对象,判断 empty 非空,我觉得没啥不符合直觉的。大概想了想好像没啥语言会默认提供一个判断 object 为空的情况?

    JSON.parse(‘{}’)==null
    false

  • 資深大佬 : jhdxr

    『不区分 map 和 list,看似很灵活,但同时也有不少坑』这句话我不反对,在做 spread operator 相关的东西的时候的确就掉进去过。

    但是就你这个帖子,你混淆了 map 和 object

  • 主 資深大佬 : sagaxu

    @jhdxr 因为 PHP 中想要 json_encode 之后得到{}而不是[],最简便的方式就是用 object,不管是(object)[]还是 new stdClass 或 new class{},类型就变成了 array | object,埋下了一个坑。几层调用之后,后面的人容易忽视掉这个细节。

    某些 PHP 项目为了避免这个麻烦,干脆约定 JSON 中所有值为[]或{}的字段都传 null 或不包含这个字段。

  • 資深大佬 : jhdxr

    @sagaxu 在我的理解中,json_encode 某种意义上也已经是 view 层的东西,那么有诸如某些字段应该是 map 而非 array 这种限制也应该在这一层去做掉,而非直接通过修改原始的数据去实现。

    传 null 这个方案个人认为非常不妥,两者的语义不完全相同

  • 資深大佬 : DavidNineRoc

    主这种只传递一个 {} 我是没看懂,为什么你的这个语义就好了.
    个人认为正确的
    // 正常
    {
    “data”: {
    “id”: 1,
    “name: “foo”
    }
    }

    // 空对象
    {
    “data”: {
    // 同类型
    “id”: null or -1,
    “name”: “”,
    }
    }

    // 主的, 这个让前端怎么判断, getAttribute 之前先 if exists ?
    {
    “data”: {

    }
    }

    // 还不如直接给个 null, 前端知道不用解析了
    {
    “data”: null,
    }

    不过每种方法都可以,一切最重要的是约定.

  • 資深大佬 : JJstyle

    说白了 php 就是坑,{}在 json_decode 之后会变成[],没得洗,所以有时候我们对于动态结构的 json 都是直接返回字符串给前端,让他们解析

  • 主 資深大佬 : sagaxu

    @DavidNineRoc
    prop 可能是 0 个也可能是几十个
    {
    prop1: value1,
    prop2: value2,
    …
    },0 个属性,用{}是很符合预期的
    另一种方式打散成 list
    [
    {name:prop1, value:value1},
    {name:prop2, value:value2},
    ],然后由调用者自己组装成 map 或 object 使用,然后用[]表示 0 个
    @jhdxr 有时候只是转发和简单维护,比如某个中间件,对具体数据结构是不知情的,只知道一些 common 的字段,decode 后稍微改改再 encode 回来,碰到{}变[]的情况,就不能简单处理了。

  • 資深大佬 : NjcyNzMzNDQ3

    @sagaxu
    1 、解决主不想返回 NULL,不用你费力 empty,另外 json 里“[],{}”不影响前端做判断

    <?php

    $linksArray = [1, 4, “0”, “V”, null, false, true, ‘true’, “N”];
    var_dump(json_encode(array_map(‘strval’, $linksArray)));

    @JJstyle
    1 、{}在 json_decode 之后会变成 [],emm,php 默认解析 object 的
    2 、动态解析的 json 直接返回字符串,让前端判断是否是字符串或者是 JSON,这操作真是看不懂。我认为在制订 API 、数据结构时就能解决这些奇怪的问题。

    <?php

    // default object
    var_dump(json_decode(‘{}’)); // object(stdClass)#1 (0) { }

    // array
    var_dump(json_decode(‘{}’, true)); // array(0) { }

    最后说一点语言都有存在的道理,不要捧一个语言踩一个语言,我认为这个行为很 low

  • 資深大佬 : brader

    @JJstyle 你仔细了解过 php 的 json_encode 函数了吗?看手册了吗?这句话也送给上的一些人。
    麻烦去看看 json_encode 的 JSON_FORCE_OBJECT 参数好吗?

  • 主 資深大佬 : sagaxu

    @NjcyNzMzNDQ3 前端不仅仅是 js,还有客户端,类型不匹配解析会报错

  • 資深大佬 : pinews

    主,说清楚你到底想怎么样? php 是弱类语言,很多时候是优势,你非要反过来把优势当劣势用,要不用===,既然是不熟悉的地方,就别贸然用==

  • 主 資深大佬 : sagaxu

    @brader 两个空数组,一个要序列化成[],另一个要{},forceobject 一刀切显然是不行的

  • 資深大佬 : brader

    @sagaxu 完全没有问题好吗?你可以去测试

  • 資深大佬 : brader

    @sagaxu
    $b = ‘{“a”:1,”b”:{},”c”:[]}’;
    $b = json_decode($b);
    $b = json_encode($b);

    反序列化和序列化出来的字符串,一样的

  • 資深大佬 : Erroad

    @brader 你讲的道理都没错,但是人家问的是”两个空数组,一个要序列化成[],另一个要{}”

  • 資深大佬 : brader

    @Erroad 需要序列化成{}的,加 JSON_FORCE_OBJECT 参数不就好了吗?
    如果是在一个地方有[]和{}的,那在序列化前保持好数据类型不就对了?有什么问题呢

  • 主 資深大佬 : sagaxu

    @brader 把 map 都 decode 成 stdClass 也是一种办法,但跟用(object)[]表示{}没什么不同

  • 資深大佬 : brader

    @sagaxu 你说写法问题的话,我觉得(object)[]没啥不好的,这个语意非常明确,代码可读性也好,但简洁性有待加强,在官方还不支持{}的写法之前,我们只能这么写,你想改变他,可以提议。

    你要想想,以前数组,还要写 array()呢,现在变成[],不就是有些致力改变它的人的努力吗

  • 資深大佬 : JJstyle

    @brader 我需要的是一个对象数组,而加上参数后变成了一个对象:

    https://gist.github.com/Jaggle/9338af5321d3294d86d350fd2cad0fc9

  • 資深大佬 : JJstyle

    @NjcyNzMzNDQ3 我们有一个 json 的配置数据,存在数据库里,首先,解析后他是一个数组,这时进行 json_decode($json, true),没问题,但是他的元素是都是 object,而 object 就应该 decode 成 object

    u1s1,我踩 php 了?我又捧了哪个语言?

  • 資深大佬 : oooooooooooo

    map 和 list 不区分确实很 SB

  • 資深大佬 : NjcyNzMzNDQ3

    @JJstyle 忘记加断行了,只是句吐槽,没有特别针对某个人

  • 資深大佬 : brader

    @JJstyle 不理解你的对象数组是什么意思?你写出你所谓的对象数组的 json 串吗?

  • 資深大佬 : brader

    @JJstyle 还有你前面说的 {}在 json_decode 之后会变成[],
    我尝试了一下,并不是这样的

    $str = ‘[{},{}]’;
    $data = json_decode($str);
    var_dump($data);
    输出:
    array(2) {
    [0] =>
    class stdClass#153 (0) {
    }
    [1] =>
    class stdClass#154 (0) {
    }
    }

    php 版本 7.2.1

  • 資深大佬 : JJstyle

    @brader #23 中的第一个 ouput 就是一个对象数组(自身是一个数组,它的每个元素是一个对象)

  • 資深大佬 : lovecy

    @JJstyle 你的 json_decode,第二个参数是 true 才会把{}解析成 array(),官方文档是这么写的
    “`当该参数为 TRUE 时,将返回 array 而非 object “`
    说白了你自己用的方式不对,在这里抹黑

  • 資深大佬 : yc8332

    重来没这么写过。。要空对象就用 new stdClass

  • 資深大佬 : JJstyle

    @lovecy
    @brader
    @NjcyNzMzNDQ3

    我误怪 json_decode 这个函数了,本质上是因为 laravel 在接收参数时,默认用的 json_decode($request, true)解析参数,因此它会把{} decode 成 [],并非抹黑,只是被坑过有点恼火。

    解决办法是 1. 针对特定接口使用 json_decode($request, false)解析参数为 object,2. 动态 json 字段使用字符串传输,依然使用 json_decode($request, true)解析参数为 array 。我们选择了第二种方案。

    我的锅我的锅我的锅

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具