Funcții anonime
Funcțiile anonime permit transmiterea altor funcții ca parametri funcțiilor sau atribuirea acestora unor variabile.
O funcție anonimă este definită ca o funcție obișnuită, cu excepția faptului că nu are un nume. De exemplu:
$hello = function($name) {
echo "<h2>Hello $name</h2>";
};
Aici, variabilei $hello i se atribuie o funcție anonimă. Această funcție este definită cu ajutorul cuvântului cheie function. De asemenea, acceptă parametri - în acest caz, parametrul $name. Și conține un bloc de instrucțiuni.
Pentru a apela o astfel de funcție, se folosește numele variabilei care o reprezintă:
$hello("Tom");
Practic, o astfel de variabilă este folosită ca o funcție obișnuită.
Codul complet:
<?php
$hello = function($name) {
echo "<h2>Hello $name</h2>";
};
$hello("Tom");
$hello("Bob");
?>

Funcțiile anonime pot returna și valori:
<?php
$sum = function($a, $b) {
return $a + $b;
};
$number = $sum(5, 11); // 16
echo $number;
?>
Un caz comun de utilizare a funcțiilor anonime este transmiterea acestora ca parametri altor funcții. Astfel de funcții anonime sunt denumite funcții de callback. Să analizăm un exemplu simplu:
<?php
function welcome($message) {
$message();
}
welcome(function() {
echo "Hello!";
});
?>
În acest caz, funcția welcome() are un parametru $message, care este apelat ca o funcție în interiorul funcției $message().
La apelul funcției welcome(), parametrului $message i se transmite o funcție anonimă care afișează șirul "Hello!". În final, la apelul:
$message();
Se va executa funcția:
function() {
echo "Hello!";
}
Astfel, putem transmite funcții anonime diferite aceleiași funcții:
<?php
function welcome($message) {
$message();
}
$goodMorning = function() { echo "<h3>Good Morning</h3>"; };
$goodEvening = function() { echo "<h3>Good Evening</h3>"; };
welcome($goodMorning); // Good Morning
welcome($goodEvening); // Good Evening
welcome(function(){ echo "<h3>Hello</h3>"; }); // Hello
?>

Utilitatea transmiterii funcțiilor anonime ca parametri constă în faptul că putem defini o funcție, dar la momentul definirii nu știm exact ce acțiuni va executa la apelare sau putem face logica funcției mai flexibilă. De exemplu, să presupunem că trebuie să definim o funcție care afișează suma elementelor unui array:
function sum($numbers) {
$result = 0;
foreach($numbers as $number) {
$result += $number;
}
return $result;
}
$myNumbers = [-2, -1, 0, 1, 2, 3, 4, 5];
$numbersSum = sum($myNumbers);
echo $numbersSum; // 12
Dar să mergem mai departe: să presupunem că dorim ca funcția să calculeze suma doar a numerelor care îndeplinesc o anumită condiție, de exemplu, doar a numerelor pozitive sau doar a numerelor pare.
Dar la momentul definirii funcției, nu știm ce condiție vom dori să folosim în viitor. În acest caz, putem folosi funcții anonime:
<?php
function sum($numbers, $condition) {
$result = 0;
foreach($numbers as $number) {
if ($condition($number)) {
$result += $number;
}
}
return $result;
}
// pentru numere pare
$isEvenNumber = function($n) { return $n % 2 === 0; };
// pentru numere pozitive
$isPositiveNumber = function($n) { return $n > 0; };
$myNumbers = [-2, -1, 0, 1, 2, 3, 4, 5];
$positiveSum = sum($myNumbers, $isPositiveNumber);
$evenSum = sum($myNumbers, $isEvenNumber);
echo "Suma numerelor pozitive: $positiveSum <br /> Suma numerelor pare: $evenSum";
?>
Rezultatul scriptului:

Aici, funcția sum() acceptă ca al doilea parametru - $condition - o altă funcție. În buclă, la parcurgerea array-ului, verificăm cu ajutorul acestei funcții dacă un element al array-ului îndeplinește condiția:
if ($condition($number))
În acest moment, nu știm ce condiție va fi, cum va funcționa exact funcția $condition. Știm doar că primește un număr și returnează true dacă numărul îndeplinește condiția sau false dacă nu îndeplinește.
Dacă numărul îndeplinește condiția, îl adăugăm la rezultatul total:
$result += $number;
La apelul funcției sum(), se transmit funcții anonime specifice ca parametru $condition. De exemplu, funcția care determină dacă un număr este par:
$isEvenNumber = function($n) { return $n % 2 === 0; };
Logica funcției este simplă: dacă restul împărțirii numărului la 2 este 0, numărul este par și funcția returnează true.
Apoi, transmitem această funcție:
$evenSum = sum($myNumbers, $isEvenNumber);
În final, la apelul if ($condition($number)), se va executa efectiv funcția $isEvenNumber().