PHP 闭包 - 获取 class 闭包作用域名称
PHP Closures - Getting class name of closure scope origin
案例
我正在玩一个 laravel 项目,看看我是否可以使用闭包来实现排序接口,我注意到当我 dd()
我的闭包时,它还显示了class 其中闭包创建为 属性.
最小化代码
// 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);
}
dd()
里面someOtherFunction()
的结果:
^ Closure($p, $n) {#1308 ▼
class: "App\Order"
use: {▼
$sortColumn: "created_at"
}
}
问题
从 dd()
的结果可以看出,闭包有一个 属性,表明它是在 class App\Order
中定义的。 有什么方法可以访问这个值?
我已经尝试了 get_class($fn)
,但正如预期的那样,它给出了 "Closure"
,如果我尝试了 $fn->class
,它给出了一个错误提示 Closure object cannot have properties
。
您当然可以通过 defaultSortFunction 中的参数将 class 名称注入到闭包中,但这显然不太好。
您应该能够使用以下方法自行从调用堆栈中提取调用 class:
https://www.php.net/manual/en/function.debug-backtrace.php
如果您使用 limit 参数,您应该能够将其限制为仅返回调用 class 而不再返回。
我不确定,但我怀疑它的性能不是特别好。
您可以在闭包中使用反射 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
returns 一个 ReflectionClass
实例基于 class 你需要找到并且 getName
完成工作。
案例
我正在玩一个 laravel 项目,看看我是否可以使用闭包来实现排序接口,我注意到当我 dd()
我的闭包时,它还显示了class 其中闭包创建为 属性.
最小化代码
// 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);
}
dd()
里面someOtherFunction()
的结果:
^ Closure($p, $n) {#1308 ▼
class: "App\Order"
use: {▼
$sortColumn: "created_at"
}
}
问题
从 dd()
的结果可以看出,闭包有一个 属性,表明它是在 class App\Order
中定义的。 有什么方法可以访问这个值?
我已经尝试了 get_class($fn)
,但正如预期的那样,它给出了 "Closure"
,如果我尝试了 $fn->class
,它给出了一个错误提示 Closure object cannot have properties
。
您当然可以通过 defaultSortFunction 中的参数将 class 名称注入到闭包中,但这显然不太好。
您应该能够使用以下方法自行从调用堆栈中提取调用 class: https://www.php.net/manual/en/function.debug-backtrace.php
如果您使用 limit 参数,您应该能够将其限制为仅返回调用 class 而不再返回。
我不确定,但我怀疑它的性能不是特别好。
您可以在闭包中使用反射 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
returns 一个 ReflectionClass
实例基于 class 你需要找到并且 getName
完成工作。