call_user_func / call_user_func_array în PHP

Apelează o funcție dată printr-o variabilă (nume, closure sau metodă), cu argumentele primite.

Sintaxă
call_user_func(callable $callback, mixed ...$args): mixed

Ce face call_user_func / call_user_func_array

call_user_func rulează un callable: numele unei funcții ca text, o funcție anonimă, un tablou [$obiect, "metoda"] sau "Clasa::metoda". Argumentele se dau după el. call_user_func_array face același lucru, dar primește argumentele într-un tablou.

În PHP modern poți scrie de obicei mai simplu: $functie(...$argumente). Funcțiile rămân utile în codul care primește un callback de la altcineva, de exemplu sisteme de evenimente sau „hook”-urile din WordPress.

Parametri

Parametru Descriere
$callback Funcția de apelat.
$args Argumentele, unul după altul. La call_user_func_array, un tablou; cheile text devin argumente cu nume.

Ce returnează

Ce returnează funcția apelată.

Exemple

Exemplul 1: Tipuri de callable

<?php
class Text
{
    public static function majuscule(string $t): string { return strtoupper($t); }
    public function repeta(string $t, int $ori): string { return str_repeat($t, $ori); }
}

echo call_user_func("strrev", "dexblog") . "\n";
echo call_user_func(fn($n) => "Salut, $n!", "Ana") . "\n";
echo call_user_func("Text::majuscule", "php") . "\n";
echo call_user_func([new Text(), "repeta"], "ha", 3);

Rezultat

golbxed
Salut, Ana!
PHP
hahaha

Exemplul 2: Argumente dintr-un tablou

Cheile text din tablou sunt transmise ca argumente cu nume (PHP 8+).

<?php
function factura(string $client, float $total, string $moneda = "lei"): string
{
    return "$client: $total $moneda";
}

echo call_user_func_array("factura", ["Ana", 259.9]) . "\n";
echo call_user_func_array("factura", ["total" => 99, "client" => "Mihai", "moneda" => "EUR"]) . "\n";

$argumente = ["Ioana", 1299.5];
echo factura(...$argumente);

Rezultat

Ana: 259.9 lei
Mihai: 99 EUR
Ioana: 1299.5 lei

Exemplul 3: Un mic sistem de evenimente

<?php
$ascultatori = [];

function asculta(string $eveniment, callable $functie): void
{
    global $ascultatori;
    $ascultatori[$eveniment][] = $functie;
}

function declanseaza(string $eveniment, mixed ...$date): void
{
    global $ascultatori;
    foreach ($ascultatori[$eveniment] ?? [] as $functie) {
        call_user_func($functie, ...$date);
    }
}

asculta("comanda_noua", fn($id) => print("Trimit email pentru comanda $id\n"));
asculta("comanda_noua", fn($id) => print("Scad stocul pentru comanda $id\n"));

declanseaza("comanda_noua", 1024);

Rezultat

Trimit email pentru comanda 1024
Scad stocul pentru comanda 1024

Greșeli frecvente

  • Dai numele unei funcții care nu există. Primești TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback. Verifică înainte cu is_callable.
  • Apelezi funcții după un nume primit de la utilizator (call_user_func($_GET["f"])). Cineva poate rula orice funcție PHP. Folosește o listă de funcții permise.

Comenzi înrudite

  • function () use / fn: O funcție fără nume, salvată într-o variabilă sau dată direct altei funcții. Poate folosi variabile din exterior cu use.
  • function_exists: Verifică dacă o funcție există: una din PHP, dintr-o extensie sau definită de tine.
  • method_exists: Verifică dacă o clasă sau un obiect are o metodă cu un anumit nume.
  • func_get_args / func_num_args: Returnează, ca tablou, toate argumentele primite de funcția curentă (func_num_args dă numărul lor).