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.
<?php
function foo(callable $callback) {
$callback();
}
?>Einige Funktionen akzeptieren Callback-Funktionen als Parameter, zum Beispiel array_map(), usort() oder preg_replace_callback().
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:
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'durchparent::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.