Laravel Collection的has方法未按预期工作,请求排查原因
Laravel Collection has()方法判断元素存在失效的原因及解决办法
问题场景
要判断某个值是否存在于数组中,尝试使用Laravel Collection的has()方法但未生效,改用PHP原生的in_array()方法则正常运行。相关代码如下:
查找目标
$value = "id";
待遍历数组
/** * Properties to be defined as private. * * @var array<string> */ protected array $privateData = [ "id" ];
未生效代码(使用has())
/** * Return array with public elements * @return array $data */ public function toArray():array { $data = []; foreach ($this->publicData as $value) { if(!$this->includePrivateProperties) { if(!collect($this->privateData)->has($value)){ $data[$value] = $this->get($value); } } } return $data; }
生效代码(使用in_array())
/** * Return array with public elements * @return array $data */ public function toArray():array { $data = []; foreach ($this->publicData as $value) { if(!$this->includePrivateProperties) { if(!in_array($value, $this->privateData)) { $data[$value] = $this->get($value); } } } return $data; }
原因分析
Laravel Collection的has()方法作用是检查集合中是否存在指定的键(key),而非检查值(value)是否存在。你的$privateData是索引数组,键为0,值为"id",所以collect($this->privateData)->has("id")实际是在判断集合中是否有键为"id"的元素,显然不存在,因此返回false,导致逻辑不符合预期。
而PHP原生的in_array()方法是直接检查值是否存在于数组中,所以能正确判断"id"是否在$privateData里。
解决办法
如果想继续使用Laravel Collection的方法,应该替换为contains()方法,该方法的作用就是检查集合中是否存在指定的值:
/** * Return array with public elements * @return array $data */ public function toArray():array { $data = []; foreach ($this->publicData as $value) { if(!$this->includePrivateProperties) { // 使用contains()替代has() if(!collect($this->privateData)->contains($value)){ $data[$value] = $this->get($value); } } } return $data; }
当然,保持使用in_array()的写法也是完全可行的,两种方式都能实现需求。
内容的提问来源于stack exchange,提问作者albertosetim
相关产品推荐
相关产品推荐

