Что такое Closure :: bind () в переполнении стека

Руководство по PHP предлагает мало объяснений о Закрытие :: Bind () и пример тоже сбивал с толку.

Вот пример кода на сайте:

class A {
private static $sfoo = 1;
private $ifoo = 2;
}
$cl1 = static function() {
return A::$sfoo;
};
$cl2 = function() {
return $this->ifoo;
};

$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo $bcl1(), "\n";
echo $bcl2(), "\n";

Каковы параметры для Closure :: bind ()?

Null был использован выше, и даже ключевое слово «new» также использовалось, что делает это еще более запутанным для меня.

3

Решение

Если вы поставите значение $cl2 как метод класса Aкласс выглядит так:

class A {
public $ifoo = 2;

function cl2()
{
return $this->ifoo;
}
}

и вы можете использовать это так:

$x = new A();
$x->cl2();
# it prints
2

Но потому что $cl2 является закрытием, а не членом класса Aкод использования выше не работает.

Метод Closure::bindTo() позволяет использовать замыкание как бы метод класса A:

$cl2 = function() {
return $this->ifoo;
};

$x = new A();
$cl3 = $cl2->bindTo($x);
echo $cl3();
# it prints 2

$x->ifoo = 4;
echo $cl3();
# it prints 4 now

Закрытие использует значение $this но $this не определен в $cl2,
когда $cl2() работает, $this является NULL и это вызывает ошибку («Неустранимая ошибка PHP: Использование $this когда не в контексте объекта «).

Closure::bindTo() создает новое замыкание, но оно «связывает» значение $this внутри этого нового замыкания к объекту, который он получает в качестве первого аргумента.

Внутри кода, хранящегося в $cl3, $this имеет то же значение, что и глобальная переменная $x, когда $cl3() работает, $this->ifoo это значение ifoo в объекте $x,

Closure::bind() это статическая версия Closure::bindTo(). Имеет такое же поведение, как Closure::bindTo() но требует дополнительного аргумента: первый аргумент должен быть замыканием для привязки.

4

Другие решения

Если вы предпочитаете использовать статическую версию, просто попробуйте

$cl4 = Closure::bind(function () { return $this->ifoo; }, new A(), 'A');
echo $cl4();
// it returns "2"

Это очень круто, если вы хотите обновить свойство объекта, но для него нет «установщика». Например:

class Product {
private $name;
private $local;
public function __construct(string $name) {
$this->name = $name;
$this->local = 'usa':
}
}
$product1 = new Product('nice product');
echo $product1->local;
// it returns 'usa'

$product2 = \Closure::bind(function () {
$this->local = 'germany';
return $this;
}, new Product('nice product'), 'Product');
echo $product2->local;
// it returns 'germany'
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector