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

如何在PHP中判断两个闭包是否为同一引用?

问题:PHP中判断闭包引用同一性并过滤闭包数组

我有一个闭包数组,用于通过array_reduce过滤对象,代码运行正常:

function test1(/* params */): bool { /* code returns true or false */ }
function test2(/* params */): bool { /* code returns true or false */ }
function test3(/* params */): bool { /* code returns true or false */ }
// ... many more

$closures = [ test1(...), test2(...), test3(...) ];

function filterObject(object $object): bool {
  return array_reduce(
    $closures(),
    fn(bool $carry, Closure $filter): bool => $carry && $filter($object),
    true
  );
}

function filterObjectArray(array $objects): array {
  return array_filter(
    $objects,
    fn(object $object): bool => filterObject($object)
  );
}

$result = filterObjectArray($contacts);

现在需要过滤相同数据,但要排除其中一个闭包,期望得到:

$closuresFiltered = [ test1(...), test3(...) ];   // test2(...) omitted

我尝试过滤闭包数组,但发现无法通过比较闭包判断引用同一性:

$closuresFiltered = array_filter(
  $closures,
  fn(Closure $closure): bool => $closure !== test2(...)   // always false
);

直接比较闭包会始终返回false:

echo test1(...) === test1(...) ? 'true' : 'false';   // Will always return false

已尝试的方法

  • 使用Reflection,但不可行
  • 使用spl_object_hash,但所有闭包返回相同哈希值:
    $hash1 = spl_object_hash(test1(...));
    $hash2 = spl_object_hash(test2(...));
    echo $hash1 === $hash2 ? 'true' : 'false';   // always true
    

临时解决方案

  1. 给闭包数组添加描述性键名,通过键名过滤:

    $closures = [
      'filterThis' => test1(...),
      'filterThat' => test2(...),
      'filterMore' => test3(...)
    ];
    

    缺点:字面量易出错,用枚举改善会增加冗余代码,收益低。

  2. 使用序列化闭包库(如Laravel或Opis/closure)将序列化对象作为键:

    $closures = [
      new SerializableClosure(test1(...)) => test1(...),
      new SerializableClosure(test2(...)) => test2(...),
      new SerializableClosure(test3(...)) => test3(...)
    ];
    

    缺点:增加代码量,引入额外依赖,收益低。

提问

是否存在无需额外依赖或冗余代码的方法,来判断两个闭包引用是否指向同一闭包?

注:我了解类似问题,但那些问题关注的是函数或闭包引用的相等性,而非引用同一性。


内容的提问来源于stack exchange,提问作者lukas.j

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:27:02