Ein Callable ist eine Referenz auf eine Funktion oder Methode, die einer
anderen Funktion als Argument übergeben wird.
Sie werden durch die Typdeklaration callable repräsentiert.
Erstellung von Callables
Ein Callable ist ein Typ, der etwas repräsentiert, das aufgerufen werden
kann. Callables können als Argumente an Funktionen oder Methoden übergeben
werden, die einen Callback-Parameter erwarten, oder sie können direkt
aufgerufen werden. Der Typ callable kann nicht als
Typdeklaration für Klasseneigenschaften verwendet werden. Verwenden Sie
stattdessen eine Closure-Typdeklaration.
Callables können auf verschiedene Arten erstellt werden:
-
Closure-Objekt
-
Ein String, der den Namen einer Funktion oder Methode enthält
-
Ein Array, das einen Klassennamen oder ein Object an
Index 0 und den Methodennamen an Index 1 enthält
-
Ein Objekt, das die magische Methode
__invoke() implementiert
Ein Closure-Objekt kann mit der Syntax für
anonyme Funktionen, der Syntax
für Pfeilfunktionen, der
Syntax für
Callbacks als Objekte erster Klasse oder mit der Methode
Closure::fromCallable() erstellt werden.
Hinweis:
Die Syntax für
Callbacks als Objekte erster Klasse ist erst ab PHP 8.1.0
verfügbar.
Beispiel #1
Callback-Beispiel mit einem Closure
<?php
// Verwendung der Syntax für anonyme Funktionen
$double1 = function ($a) {
return $a * 2;
};
// Verwendung der Syntax für Callbacks als Objekte erster Klasse
function double_function($a) {
return $a * 2;
}
$double2 = double_function(...);
// Verwendung der Syntax für Pfeilfunktionen
$double3 = fn($a) => $a * 2;
// Verwendung von Closure::fromCallable
$double4 = Closure::fromCallable('double_function');
// Hier wird das Closure als Callback verwendet, um
// die Größe jedes Elements unseres Bereichs zu verdoppeln
$new_numbers = array_map($double1, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;
$new_numbers = array_map($double2, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;
$new_numbers = array_map($double3, range(1, 5));
print implode(' ', $new_numbers) . PHP_EOL;
$new_numbers = array_map($double4, range(1, 5));
print implode(' ', $new_numbers);
?>
Das oben gezeigte Beispiel erzeugt mit PHP 8.1 folgende Ausgabe:
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
2 4 6 8 10
Ein Callable kann auch ein String sein, der den Namen einer Funktion oder
einer statischen Methode enthält. Jede eingebaute oder benutzerdefinierte
Funktion kann verwendet werden, außer Sprachkonstrukten wie:
array(), echo,
empty(), eval(),
isset(),
list(), print oder
unset().
Statische Klassenmethoden können verwendet werden, ohne dass ein
Object dieser Klasse instantiiert werden muss, indem entweder
ein Array mit dem Klassennamen an Index 0 und dem Methodennamen an Index 1
erstellt wird, oder indem die spezielle Syntax mit dem
Bereichsauflösungsoperator :: wie in
'ClassName::methodName' verwendet wird.
Eine Methode eines instantiierten Objects kann ein Callable
sein, wenn sie als Array mit dem Object an Index 0 und dem
Methodennamen an Index 1 angegeben wird.
Der Hauptunterschied zwischen einem Closure-Objekt
und dem Typ callable besteht darin, dass ein
Closure-Objekt unabhängig vom Geltungsbereich ist
und immer aufgerufen werden kann, während ein Callable-Typ vom
Geltungsbereich abhängig sein kann und möglicherweise nicht direkt aufgerufen
werden kann. Closure ist die bevorzugte Art,
Callables zu erstellen.
Hinweis:
Während Closure-Objekte an den Geltungsbereich
gebunden sind, in dem sie erstellt werden, werden Callables, die
Klassenmethoden als Strings oder Arrays referenzieren, in dem
Geltungsbereich aufgelöst, in dem sie aufgerufen werden. Um aus einer
privaten oder geschützten Methode ein Callable zu erstellen, das dann
von außerhalb des Geltungsbereichs der Klasse aufgerufen werden kann,
verwenden Sie Closure::fromCallable() oder die
Syntax für
Callbacks als Objekte erster Klasse.
PHP erlaubt die Erstellung von Callables, die als Callback-Argument
verwendet, aber nicht direkt aufgerufen werden können. Dabei handelt es
sich um kontextabhängige Callables, die eine Klassenmethode in der
Vererbungshierarchie einer Klasse referenzieren, zum Beispiel
'parent::method' oder
["static", "method"].
Hinweis:
Seit PHP 8.2.0 sind kontextabhängige Callables veraltet. Entfernen Sie
die Kontextabhängigkeit, indem Sie
'parent::method' durch
parent::class . '::method' ersetzen, oder verwenden
Sie die Syntax für
Callbacks als Objekte erster Klasse.
Beispiel #2
Verschiedene Arten von Callables mit
call_user_function() aufrufen
<?php
// Eine Beispiel-Callback-Funktion
function my_callback_function() {
echo 'hello world!', PHP_EOL;
}
// Eine Beispiel-Callback-Methode
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!', PHP_EOL;
}
}
// Typ 1: Einfaches Callback
call_user_func('my_callback_function');
// Typ 2: Statischer Methodenaufruf
call_user_func(['MyClass', 'myCallbackMethod']);
// Typ 3: Aufruf einer Objektmethode
$obj = new MyClass();
call_user_func([$obj, 'myCallbackMethod']);
// Typ 4: Statischer Methodenaufruf
call_user_func('MyClass::myCallbackMethod');
// Typ 5: Statischer Methodenaufruf mit dem Schlüsselwort ::class
call_user_func([MyClass::class, 'myCallbackMethod']);
// Typ 6: Relativer statischer Methodenaufruf
class A {
public static function who() {
echo 'A', PHP_EOL;
}
}
class B extends A {
public static function who() {
echo 'B', PHP_EOL;
}
}
call_user_func(['B', 'parent::who']); // seit PHP 8.2.0 veraltet
// Typ 7: Objekte die __invoke implementieren können als Callable verwendet werden
class C {
public function __invoke($name) {
echo 'Hello ', $name;
}
}
$c = new C();
call_user_func($c, 'PHP!');
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
hello world!
Hello World!
Hello World!
Hello World!
Hello World!
Deprecated: Callables of the form ["B", "parent::who"] are deprecated in script on line 41
A
Hello PHP!
Hinweis:
Callbacks, die für
Funktionen wie call_user_func() und call_user_func_array() registriert
sind, werden nicht mehr ausgeführt, wenn in einem vorherigen Callback eine Exception geworfen und nicht gefangen
wurde.