PHP 8.1.0 itibariyle kullanılabilen birinci sınıf çağrılabilir sözdizimi çağrılabilir anonim işlevler oluşturmanın bir yoludur. Dizgeleri ve dizileri kullanan mevcut çağrılabilir sözdiziminin yerini alır. Bu sözdiziminin getirisi statik analiz için erişilebilir olması ve çağrılabilirin elde edildiği etki alanın kullanılabilmesidir.
Çağrılabilirden Closure nesne oluşturmakta
CallableExpr(...)
sözdizimi kullanılır.
CallableExpr
PHP dil yapısı içinde doğrudan çözümlenebilen
her ifadeyi kabul eder:
Örnek 1 - Basit birinci sınıf çağrılabilir sözdizimi
<?php
class Foo {
public function yöntem() {}
public static function statikyöntem() {}
public function __invoke() {}
}
$obj = new Foo();
$sınıfDizgesi = 'Foo';
$yöntemDizgesi = 'method';
$statikYöntemDizgesi = 'staticmethod';
$f1 = strlen(...);
$f2 = $obj(...); // çağrılabilir nesne
$f3 = $obj->yöntem(...);
$f4 = $obj->$yöntemDizgesi(...);
$f5 = Foo::statikyöntem(...);
$f6 = $sınıfDizgesi::$statikYöntemDizgesi(...);
// dizi, dizge kullanan geleneksel çağrılabilir
$f7 = 'strlen'(...);
$f8 = [$obj, 'method'](...);
$f9 = [Foo::class, 'staticmethod'](...);
?>
Bilginize:
...
sözdiziminin bir parçası olup ihmal edilmemelidir.
CallableExpr(...)
sözdizimi
Closure::fromCallable() ile aynı yapıdadır.
Yani, dizi ve dizge kullanan çağrılabilirlerin tersine
CallableExpr(...)
oluşturulduğu etki alanına bağlıdır:
Örnek 2 - Geleneksel çağrılabilir ile CallableExpr(...)
karşılaştırması
<?php
class Foo {
public function getPrivateMethod() {
return [$this, 'privateMethod'];
}
private function privateMethod() {
echo __METHOD__, "\n";
}
}
$foo = new Foo;
$privateMethod = $foo->getPrivateMethod();
$privateMethod();
// Ölümcül hata: private yöntem Foo::privateMethod() küresel etki alanında çağrılıyor.
// Bunun nedeni, çağrının Foo dışında yapılması ve
// görünürlüğün bu noktadan denetlenmesidir.
class Foo1 {
public function getPrivateMethod() {
// Çağrılabilirin oluşturulduğu etki alanı kullanılıyor.
return $this->privateMethod(...); // Closure::fromCallable([$this, 'privateMethod']); ile eşdeğer
}
private function privateMethod() {
echo __METHOD__, "\n";
}
}
$foo1 = new Foo1;
$privateMethod = $foo1->getPrivateMethod();
$privateMethod(); // Foo1::privateMethod
?>
Bilginize:
Bu sözdizimini kullanarak nesne oluşturmak (
new Foo(...)
gibi) desteklenmemektedir. Bunun sebebinew Foo()
sözdiziminin bir işlev/yöntem çağrısı olarak ele alınmamasıdır.
Bilginize:
Basit birinci sınıf çağrılabilir sözdizimi ile güvenli null işleci ?-> birlikte kullanılmamalıdır. Aşağıdakilerin her biri bir derleme hatasıyla sonuçlanır:
<?php
$obj?->method(...);
$obj?->prop->method(...);
?>