PHP 闭包 - 获取闭包范围源的类名



Case

我正在玩一个 laravel 项目,看看我是否可以使用闭包来实现我的排序接口,我注意到当我dd()我的闭包时,它还显示了在其中创建闭包作为属性的类。

最小化代码

// in my Order model class, i have a function that will return a closure
public static function defaultSortFunction(){
$sortColumn = property_exists(self::class,'defaultSortingColumn') ? self::$defaultSortingColumn : 'created_at';
return function($p,$n)use($sortColumn){
return $p->$sortColumn <=> $n->$sortColumn;
};
}
// in one of my controller I use for testing, I added these 2 methods for testing
public function index(){
$sortFunction = Order::defaultSortFunction();
$this->someOtherFunction($sortFunction);
return 'done';
}
private function someOtherFunction($fn){
dd($fn);
// $scopeModel = get_class($fn); => Closure

// example of how I can use this value later
// $scopeModel::take(10)->get()->sort($fn);
}

someOtherFunction()内部dd()的结果:

^ Closure($p, $n) {#1308 ▼
class: "AppOrder"
use: {▼
$sortColumn: "created_at"
}
}

问题

dd()的结果来看,它表明闭包具有一个属性,该属性表明它是在类AppOrder中定义的。有没有办法访问此值

我已经尝试过get_class($fn)但正如预期的那样,它给出了"Closure",如果我这样做$fn->class它会给出一个错误,说Closure object cannot have properties

你可以在闭包上使用反射API,这是一种比debug_backtrace更干净的方法

// in one of my controller I use for testing, I added these 2 methods for testing
public function index(){
$sortFunction = Order::defaultSortFunction();
$this->someOtherFunction($sortFunction);
return 'done';
}
private function someOtherFunction($fn){
$reflectionClosure = new ReflectionFunction($fn);
dd($reflectionClosure->getClosureScopeClass()->getName());
}

getClosureScopeClass根据您需要查找的类返回一个ReflectionClass实例,getName完成作业。

当然,您可以通过 defaultSortFunction 中的参数将类名注入到闭包中,但这显然不是那么好。

您应该能够使用以下方法从调用堆栈中自行提取调用类: https://www.php.net/manual/en/function.debug-backtrace.php

如果使用 limit 参数,您应该能够将其限制为仅返回调用类,而不返回。

我不确定,但我怀疑它的性能不是特别好。

相关内容

  • 没有找到相关文章

最新更新