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 callable
function 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 Bob
echo $result;
PHP.mk документација
Closure::fromCallable
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Патека
closure.fromcallable.php
Локална патека за оваа страница.
Извор
php.net/manual/en
Оригиналниот HTML се реупотребува и локално се стилизира.
Режим
Прокси + превод во позадина
Кодовите, табелите и белешките остануваат читливи во истиот тек.
Референца
closure.fromcallable.php
Closure::fromCallable
Референца за `closure.fromcallable.php` со подобрена типографија и навигација.
Closure::fromCallable
(PHP 7 >= 7.1.0)
Closure::fromCallable — (PHP 7 >= 7.1.0)
= NULL
Конвертира повикувач во затворање анонимна функција Креирај и врати ново callback од дадено callback користејќи го тековниот опсег. Овој метод проверува дали TypeError
е повикувач во тековниот опсег и фрла
Забелешка:
Од PHP 8.1.0, Синтакса за повикување од прва класа ако не е.
Параметри
callback-
има исто значење како овој метод.
Вратени вредности
Повикувачот за конвертирање. Затворање Враќа новосоздадено
TypeError ако callback или фрла
Види Исто така
Белешки од корисници 3 белешки
не е повикувач во тековниот опсег. ¶
пред 8 години
igorchernin at yahoo dot com ¶
пред 7 години
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.
<?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
?>
nakerlund at gmail dot com ¶
пред 7 години
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());
};
}
}