Closure::fromCallable

(PHP 7 >= 7.1.0)

Closure::fromCallable将可调用对象转换为闭包

描述

public static Closure::fromCallable(callable $callback): Closure

使用当前作用域从给定的 callback 创建并返回一个新的 匿名函数。此方法检查 callback 在当前作用域中是否可调用,如果不可调用,则抛出 TypeError

注意:

从 PHP 8.1.0 开始,一等函数语法 与此方法具有相同的语义。

参数

callback

要转换的可调用对象。

返回值

返回新创建的 Closure,或者如果 callback 在当前作用域中不可调用,则抛出 TypeError

添加注释

用户贡献的注释 3 个注释

igorchernin at yahoo dot com
7 年前
看起来“fromCallable”的结果与原始 Lambda 函数的行为略有不同。

class A {
private $name;
public function __construct($name)
{
$this->name = $name;
}
}

// 测试可调用对象
function getName()
{
return $this->name;
}
$bob = new A("Bob");

$cl1 = Closure::fromCallable("getName");
$cl1 = $cl1->bindTo($bob, 'A');

// 这将检索:未捕获的错误:无法访问私有属性 A::$name
$result = $cl1();
echo $result;

// 但是对于 Lambda 函数
$cl2 = function() {
return $this->name;
};
$cl2 = $cl2->bindTo($bob, 'A');
$result = $cl2();

// 这将打印 Bob
echo $result;
4-lom at live dot de
6 年前
遗憾的是,您的比较不正确。

// 等效于
$cl1 = Closure::fromCallable("getName");
$cl1 = $cl1->bindTo($bob, 'A');

// 很可能就是这样
$cl2 = function() {
return call_user_func_array("getName", func_get_args());
};
$cl2 = $cl2->bindTo($bob, 'A');

执行任一闭包都应该导致与您已发布相同的访问冲突错误。

----
一个简单的 PHP 7.0 填充程序可能看起来像这样
----

namespace YourPackage;

/**
* Class Closure
*
* @see \Closure
*/
class Closure
{
/**
* @see \Closure::fromCallable()
* @param callable $callable
* @return \Closure
*/
public static function fromCallable(callable $callable)
{
// 如果我们有 native 版本,就使用 native 版本!
if(method_exists(\Closure::class, 'fromCallable')) {
return \Closure::fromCallable($callable);
}

return function () use ($callable) {
return call_user_func_array($callable, func_get_args());
};
}
}
nakerlund at gmail dot com
6 年前
我有两点

可以使用 Closure::fromCallable 将私有/受保护的方法转换为闭包并在类外部使用它们。

如果作为字符串提供,Closure::fromCallable 接受使用关键字 static 的延迟动态绑定。

下面的代码演示了如何在类外部的函数中将私有静态方法用作回调。

<?php
function myCustomMapper ( Callable $callable, string $str ): string {
return
join(' ', array_map( $callable, explode(' ', $str) ) );
}

class
MyClass {

public static function
mapUCFirst ( string $str ): string {
$privateMethod = 'static::mapper';
$mapper = Closure::fromCallable( $privateMethod );
return
myCustomMapper( $mapper, $str );
}
private static function
mapper ( string $str ): string {
return
ucfirst( $str );
}

}

echo
MyClass::mapUCFirst('four little uncapitalized words');
// Prints: Four Little Uncapitalized Words
?>
To Top