You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
}

为什么这么做?

  1. 引用同步:函数声明带&,遍历数组时也用&$element,返回的是原数组元素的直接引用,修改返回值会同步到原数组;
  2. 避免通知:用空对象代替null当未找到标记,赋值给引用变量时不会触发E_NOTICE;
  3. 无歧义判断:用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 01:46:11