PHP实现可返回引用且支持空值的find函数的问题求助
实现PHP版安全支持引用的Array.find()替代函数
你想在PHP里做一个和JS Array.prototype.find() 功能一样的助手函数,但踩了两个坑:
- 最初写的函数返回的是值拷贝,改找到的嵌套子数组时,原数组根本没变化;
- 改成返回引用后,找不到元素时返回
null会触发E_NOTICE,又不想用临时变量或者屏蔽通知这种凑活的办法。
最优实现方案
用静态变量存一个唯一的空对象当"未找到"标记,既保证找到元素时返回引用(修改同步原数组),又不会因为返回null报错:
function &find(array &$arr, callable $callable) { // 用唯一空对象当标记,避免和用户的数据冲突 static $notFound; if ($notFound === null) { $notFound = new stdClass(); } foreach ($arr as &$element) { if ($callable($element)) { return $element; } } return $notFound; }
使用示例
$main_array = [ ['key' => 10], ['key' => 20], // ... ]; // 赋值给引用变量,不会触发E_NOTICE $sub_array =& find($main_array, fn($x) => $x['key'] === 10); // 判断是否找到:检查返回值是不是标记对象 if ($sub_array instanceof stdClass) { echo "没找到匹配的元素"; } else { // 修改返回的子数组,原数组会同步更新 $sub_array['key'] = 200; echo $main_array[0]['key'] === 200 ? 'True' : 'False'; // 输出True }
为什么这么做?
- 引用同步:函数声明带
&,遍历数组时也用&$element,返回的是原数组元素的直接引用,修改返回值会同步到原数组; - 避免通知:用空对象代替
null当未找到标记,赋值给引用变量时不会触发E_NOTICE; - 无歧义判断:用
instanceof stdClass判断是否找到,不会和用户数组里的空数组、null元素混淆。
如果担心stdClass和自己的业务对象冲突,还可以专门建个标记类:
class NotFoundMarker {} function &find(array &$arr, callable $callable) { static $notFound = new NotFoundMarker(); foreach ($arr as &$element) { if ($callable($element)) { return $element; } } return $notFound; } // 判断时改成: if ($sub_array instanceof NotFoundMarker) { // 未找到处理逻辑 }
内容的提问来源于stack exchange,提问作者Fawfulcopter
相关产品推荐
相关产品推荐

