PHP null 对象 取一个索引 为什么没有报错,我们一个同事给我说写了好多年了,但是我本地缺跑不过,什么原理

下面这个代码我也不确定能不能这么用了,因为我本地跑不过,我同事却说他一直这么用,看大家的见解,有相关的说明,附上链接,我也学习一下新用法

$user = WechatUser::query()->first();
//  这个如果user 返回 null , 直接取 字段索引 不会报错吗?有数据这个写法没问题
return $user['nickname'];
每天一点小知识,到那都是大佬,哈哈
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 9
leo

7.3 及以前的版本确实可以用数组下标的方式访问一个值为 null 的变量(实际上可以是 null、bool、int、resource),无论用什么下标永远返回 null 而且不报错。

7.4 开始这么写会抛出 Notice,8.0 开始抛出 Warning。

各个版本的输出结果:3v4l.org/UIPDH

文档:www.php.net/manual/en/migration74....

2年前 评论
Tsukasa_Kanzaki 2年前
raybon (楼主) 2年前
raybon (楼主) 2年前
largezhou 2年前

php版本问题吧

2年前 评论
raybon (楼主) 2年前
2年前 评论
raybon (楼主) 2年前
raybon (楼主) 2年前
怕爱玩 2年前

首先要了解的是:

$user = WechatUser::query()->first();

这里返回的$user,实际上就是WechatUser模型的实例(或者是null,在没有查到数据时),然后这个实例实现了SPL的ArrayAccess接口,使得这个实例可以像PHP数组那样使用(即$user[foo_attribute]或者$user[0])。关于ArrayAccess的更多信息,热心的楼上已经提供了PHP文档链接,可以仔细阅读一下。

那么,回到你的问题,因为我没有用过早期版本的Laravel和PHP(Laravel < 5.8, PHP < 7.2),所以只是猜测:
在早期的Laravel中,如果查不到数据,返回的可能是一个空的WechatUser实例(等效于return new WechatUser;),或者是返回了空的Illuminate\Support\Collection实例(即Laravel文档->综合话题->集合,当然也可以确定是实现了ArrayAccess接口),无论是哪个,返回的都不是null,而且很可能在offsetGet() 方法中做了一定的安全处理,所以return $user['nickname']并不会抛出错误

但是,现在的Laravel,在使用诸如first()find()方法时,查不到数据会直接返回null,那么把null 当作数组使用当然出错(当然,你可以理解为:null并没有实现ArrayAccess接口),因此在你本机上,这个代码就可能抛出错误提示

2年前 评论
raybon (楼主) 2年前
raybon (楼主) 2年前
Tsukasa_Kanzaki (作者) 2年前
leo

7.3 及以前的版本确实可以用数组下标的方式访问一个值为 null 的变量(实际上可以是 null、bool、int、resource),无论用什么下标永远返回 null 而且不报错。

7.4 开始这么写会抛出 Notice,8.0 开始抛出 Warning。

各个版本的输出结果:3v4l.org/UIPDH

文档:www.php.net/manual/en/migration74....

2年前 评论
Tsukasa_Kanzaki 2年前
raybon (楼主) 2年前
raybon (楼主) 2年前
largezhou 2年前

接手了很多老代码,也是很多次从老代码那边看到了很多奇技淫巧

2年前 评论
raybon (楼主) 2年前

这样肯定是问题的,一般我都是这样:$user['nickname'] ??null

2年前 评论
raybon (楼主) 2年前

没有开启所有错误

2年前 评论
raybon (楼主) 2年前
        $user = WechatUser::query()->first();
        return sg($user['nickname']);

        function sg(&$val, $defVal = NULL) {
            return empty($val) ? $defVal : $val;
        }
2年前 评论

laravel中最优雅的写法是 file

2年前 评论
raybon (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!