Closure::fromCallable

(PHP 7 >= 7.1.0)

Closure::fromCallablecallable をクロージャに変換する

説明

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

現在のスコープを用いて、指定された callback から新しい 無名関数 を作って返します。 このメソッドは、現在のスコープで callback が呼び出し可能かどうかをチェックし、可能でなければ TypeError をスローします。

注意:

PHP 8.1.0 以降では、このメソッドと同等の機能を実現するやり方として、第一級callableを生成する記法 があります。

パラメータ

callback

変換する callable。

戻り値

新しく作られた Closure を返します。 callback が現在のスコープで呼び出し可能でなければ、 TypeError をスローします。

add a note

User Contributed Notes 3 notes

up
13
igorchernin at yahoo dot com
8 years ago
It seems that the result of the "fromCallable" behaves a little bit different then an original Lambda function.class A {    private $name;    public function __construct($name)    {        $this->name = $name;    }}// test callablefunction getName(){      return $this->name;}$bob = new A("Bob");$cl1 = Closure::fromCallable("getName");$cl1 = $cl1->bindTo($bob, 'A');//This will retrieve: Uncaught Error: Cannot access private property A::$name $result = $cl1();echo $result;//But for a Lambda function$cl2 = function() {    return $this->name;};$cl2 = $cl2->bindTo($bob, 'A');$result = $cl2();// This will print Bobecho $result;
up
8
4-lom at live dot de
7 years ago
Sadly, your comparison is incorrect.// The equivalent to$cl1 = Closure::fromCallable("getName");$cl1 = $cl1->bindTo($bob, 'A');// is most likely this$cl2 = function() {    return call_user_func_array("getName", func_get_args());};$cl2 = $cl2->bindTo($bob, 'A');Executing one or the other Closure should result in the same access violation error you already postet.----A simple PHP 7.0 polyfill could look like this:----namespace YourPackage;/** * Class Closure * * @see \Closure */class Closure{    /**     * @see \Closure::fromCallable()     * @param callable $callable     * @return \Closure     */    public static function fromCallable(callable $callable)    {        // In case we've got it native, let's use that native one!        if(method_exists(\Closure::class, 'fromCallable')) {            return \Closure::fromCallable($callable);        }        return function () use ($callable) {            return call_user_func_array($callable, func_get_args());        };    }}
up
5
nakerlund at gmail dot com
7 years ago
I have two points:It is possible to use Closure::fromCallable to convert private/protected methods to closures and use them outside the class.Closure::fromCallable accepts late dynamic bindings using the keyword static if provided as a string. My code below demonstrate how a private static method can be used as a callback in a function outside the class.<?phpfunction 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