如何在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
临时解决方案
给闭包数组添加描述性键名,通过键名过滤:
$closures = [ 'filterThis' => test1(...), 'filterThat' => test2(...), 'filterMore' => test3(...) ];缺点:字面量易出错,用枚举改善会增加冗余代码,收益低。
使用序列化闭包库(如Laravel或Opis/closure)将序列化对象作为键:
$closures = [ new SerializableClosure(test1(...)) => test1(...), new SerializableClosure(test2(...)) => test2(...), new SerializableClosure(test3(...)) => test3(...) ];缺点:增加代码量,引入额外依赖,收益低。
提问
是否存在无需额外依赖或冗余代码的方法,来判断两个闭包引用是否指向同一闭包?
注:我了解类似问题,但那些问题关注的是函数或闭包引用的相等性,而非引用同一性。
内容的提问来源于stack exchange,提问作者lukas.j
相关产品推荐
相关产品推荐

