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

2020-07-08 15:39:57 +08:00
 sagaxu
这么设计是否符合直觉?
4191 次点击
所在节点    PHP
32 条回复
ksaa0096329
2020-07-08 15:44:04 +08:00
false
有时间来问,早就测试出来了.
再说了 你这种写法有什么意义.
iamverylovely
2020-07-08 16:10:47 +08:00
符合啊,不然又要 emptyObject();
zarte
2020-07-08 18:29:08 +08:00
false 一定是用了那些查询回来是 obj 的 orm 了吧,哈哈。
lovecy
2020-07-08 20:22:06 +08:00
empty,只针对
0,空 string,空数组,false,'0',null,未定义变量
这几种返回 true,其他都是 false
毕竟 object 判断是比较复杂的,除非新增一个__empty 魔术方法
jhdxr
2020-07-08 23:08:04 +08:00
作为一个对象,判断 empty 非空,我觉得没啥不符合直觉的。大概想了想好像没啥语言会默认提供一个判断 object 为空的情况?

JSON.parse('{}')==null
false
jhdxr
2020-07-08 23:10:02 +08:00
『不区分 map 和 list,看似很灵活,但同时也有不少坑』这句话我不反对,在做 spread operator 相关的东西的时候的确就掉进去过。

但是就你这个帖子,你混淆了 map 和 object
sagaxu
2020-07-08 23:54:24 +08:00
@jhdxr 因为 PHP 中想要 json_encode 之后得到{}而不是[],最简便的方式就是用 object,不管是(object)[]还是 new \stdClass 或 new class{},类型就变成了 array | object,埋下了一个坑。几层调用之后,后面的人容易忽视掉这个细节。

某些 PHP 项目为了避免这个麻烦,干脆约定 JSON 中所有值为[]或{}的字段都传 null 或不包含这个字段。
jhdxr
2020-07-09 03:27:16 +08:00
@sagaxu 在我的理解中,json_encode 某种意义上也已经是 view 层的东西,那么有诸如某些字段应该是 map 而非 array 这种限制也应该在这一层去做掉,而非直接通过修改原始的数据去实现。

传 null 这个方案个人认为非常不妥,两者的语义不完全相同
DavidNineRoc
2020-07-09 08:54:56 +08:00
楼主这种只传递一个 {} 我是没看懂,为什么你的这个语义就好了.
个人认为正确的
// 正常
{
"data": {
"id": 1,
"name: "foo"
}
}

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

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

}
}

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

不过每种方法都可以,一切最重要的是约定.
JJstyle
2020-07-09 09:11:35 +08:00
说白了 php 就是坑,{}在 json_decode 之后会变成[],没得洗,所以有时候我们对于动态结构的 json 都是直接返回字符串给前端,让他们解析
sagaxu
2020-07-09 09:56:24 +08:00
@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
2020-07-09 10:18:42 +08:00
@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
2020-07-09 10:24:17 +08:00
@JJstyle 你仔细了解过 php 的 json_encode 函数了吗?看手册了吗?这句话也送给楼上的一些人。
麻烦去看看 json_encode 的 JSON_FORCE_OBJECT 参数好吗?
sagaxu
2020-07-09 10:26:49 +08:00
@NjcyNzMzNDQ3 前端不仅仅是 js,还有客户端,类型不匹配解析会报错
pinews
2020-07-09 10:28:48 +08:00
楼主,说清楚你到底想怎么样? php 是弱类语言,很多时候是优势,你非要反过来把优势当劣势用,要不用===,既然是不熟悉的地方,就别贸然用==
sagaxu
2020-07-09 10:29:01 +08:00
@brader 两个空数组,一个要序列化成[],另一个要{},forceobject 一刀切显然是不行的
brader
2020-07-09 10:35:16 +08:00
@sagaxu 完全没有问题好吗?你可以去测试
brader
2020-07-09 10:36:21 +08:00
@sagaxu
$b = '{"a":1,"b":{},"c":[]}';
$b = json_decode($b);
$b = json_encode($b);

反序列化和序列化出来的字符串,一样的
Erroad
2020-07-09 10:48:33 +08:00
@brader 你讲的道理都没错,但是人家问的是"两个空数组,一个要序列化成[],另一个要{}"
brader
2020-07-09 10:53:38 +08:00
@Erroad 需要序列化成{}的,加 JSON_FORCE_OBJECT 参数不就好了吗?
如果是在一个地方有[]和{}的,那在序列化前保持好数据类型不就对了?有什么问题呢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/688251

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX