PHP
Programmazione funzionale
Ricerca…
introduzione
La programmazione funzionale di PHP si basa sulle funzioni. Le funzioni in PHP forniscono un codice organizzato e riutilizzabile per eseguire una serie di azioni. Le funzioni semplificano il processo di codifica, impediscono la logica ridondante e rendono il codice più facile da seguire. Questo argomento descrive la dichiarazione e l'utilizzo di funzioni, argomenti, parametri, dichiarazioni di ritorno e scope in PHP.
Assegnazione alle variabili
Le funzioni anonime possono essere assegnate a variabili da utilizzare come parametri in cui è previsto un callback:
$uppercase = function($data) {
return strtoupper($data);
};
$mixedCase = ["Hello", "World"];
$uppercased = array_map($uppercase, $mixedCase);
print_r($uppercased);
Queste variabili possono anche essere utilizzate come chiamate di funzione indipendenti:
echo $uppercase("Hello world!"); // HELLO WORLD!
Utilizzo di variabili esterne
Il costrutto use
viene utilizzato per importare le variabili nello scope della funzione anonima:
$divisor = 2332;
$myfunction = function($number) use ($divisor) {
return $number / $divisor;
};
echo $myfunction(81620); //Outputs 35
Le variabili possono anche essere importate per riferimento:
$collection = [];
$additem = function($item) use (&$collection) {
$collection[] = $item;
};
$additem(1);
$additem(2);
//$collection is now [1,2]
Passando una funzione di callback come parametro
Esistono diverse funzioni PHP che accettano funzioni di callback definite dall'utente come parametro, ad esempio call_user_func()
, usort()
e array_map()
.
A seconda di dove è stata definita la funzione di callback definita dall'utente, esistono diversi modi per passarli:
Stile procedurale:
function square($number)
{
return $number * $number;
}
$initial_array = [1, 2, 3, 4, 5];
$final_array = array_map('square', $initial_array);
var_dump($final_array); // prints the new array with 1, 4, 9, 16, 25
Stile orientato agli oggetti:
class SquareHolder
{
function square($number)
{
return $number * $number;
}
}
$squaredHolder = new SquareHolder();
$initial_array = [1, 2, 3, 4, 5];
$final_array = array_map([$squaredHolder, 'square'], $initial_array);
var_dump($final_array); // prints the new array with 1, 4, 9, 16, 25
Stile orientato agli oggetti utilizzando un metodo statico:
class StaticSquareHolder
{
public static function square($number)
{
return $number * $number;
}
}
$initial_array = [1, 2, 3, 4, 5];
$final_array = array_map(['StaticSquareHolder', 'square'], $initial_array);
// or:
$final_array = array_map('StaticSquareHolder::square', $initial_array); // for PHP >= 5.2.3
var_dump($final_array); // prints the new array with 1, 4, 9, 16, 25
Utilizzo di funzioni integrate come richiamate
Nelle funzioni che possono essere callable
come argomento, è anche possibile inserire una stringa con la funzione integrata PHP. È comune utilizzare il trim
come parametro array_map
per rimuovere gli spazi bianchi array_map
e finali da tutte le stringhe dell'array.
$arr = [' one ', 'two ', ' three'];
var_dump(array_map('trim', $arr));
// array(3) {
// [0] =>
// string(3) "one"
// [1] =>
// string(3) "two"
// [2] =>
// string(5) "three"
// }
Funzione anonima
Una funzione anonima è solo una funzione che non ha un nome.
// Anonymous function
function() {
return "Hello World!";
};
In PHP, una funzione anonima viene trattata come un'espressione e per questo motivo dovrebbe essere terminata con un punto e virgola ;
.
Una funzione anonima dovrebbe essere assegnata a una variabile.
// Anonymous function assigned to a variable
$sayHello = function($name) {
return "Hello $name!";
};
print $sayHello('John'); // Hello John
O dovrebbe essere passato come parametro di un'altra funzione.
$users = [
['name' => 'Alice', 'age' => 20],
['name' => 'Bobby', 'age' => 22],
['name' => 'Carol', 'age' => 17]
];
// Map function applying anonymous function
$userName = array_map(function($user) {
return $user['name'];
}, $users);
print_r($usersName); // ['Alice', 'Bobby', 'Carol']
O anche stato restituito da un'altra funzione.
Funzioni anonime autoeseguibili:
// For PHP 7.x
(function () {
echo "Hello world!";
})();
// For PHP 5.x
call_user_func(function () {
echo "Hello world!";
});
Passare un argomento in funzioni anonime autoeseguite:
// For PHP 7.x
(function ($name) {
echo "Hello $name!";
})('John');
// For PHP 5.x
call_user_func(function ($name) {
echo "Hello $name!";
}, 'John');
Scopo
In PHP, una funzione anonima ha il proprio scopo come qualsiasi altra funzione PHP.
In JavaScript, una funzione anonima può accedere a una variabile nell'ambito esterno. Ma in PHP, questo non è permesso.
$name = 'John';
// Anonymous function trying access outside scope
$sayHello = function() {
return "Hello $name!";
}
print $sayHello('John'); // Hello !
// With notices active, there is also an Undefined variable $name notice
chiusure
Una chiusura è una funzione anonima che non può accedere al di fuori dell'ambito.
Quando si definisce una funzione anonima come tale, si crea uno "spazio dei nomi" per quella funzione. Attualmente ha solo accesso a tale spazio dei nomi.
$externalVariable = "Hello";
$secondExternalVariable = "Foo";
$myFunction = function() {
var_dump($externalVariable, $secondExternalVariable); // returns two error notice, since the variables aren´t defined
}
Non ha accesso a nessuna variabile esterna. Per concedere questa autorizzazione per questo spazio dei nomi per accedere a variabili esterne, è necessario introdurlo tramite chiusure ( use()
).
$myFunction = function() use($externalVariable, $secondExternalVariable) {
var_dump($externalVariable, $secondExternalVariable); // Hello Foo
}
Questo è fortemente attribuito allo scope scope stretto di PHP - Se una variabile non è definita all'interno dell'ambito, o non è inclusa in global
allora non esiste.
Nota anche:
L'ereditarietà di variabili dall'ambito genitore non equivale all'utilizzo di variabili globali. Le variabili globali esistono nell'ambito globale, che è lo stesso indipendentemente dalla funzione in esecuzione.
L'ambito genitore di una chiusura è la funzione in cui è stata dichiarata la chiusura (non necessariamente la funzione da cui è stata chiamata).
Tratto dalla documentazione di PHP per le funzioni anonime
In PHP, le chiusure utilizzano un approccio precoce vincolante . Ciò significa che le variabili passate allo spazio dei nomi della chiusura use
parola chiave use
avranno gli stessi valori quando è stata definita la chiusura.
Per cambiare questo comportamento devi passare la variabile per riferimento .
$rate = .05;
// Exports variable to closure's scope
$calculateTax = function ($value) use ($rate) {
return $value * $rate;
};
$rate = .1;
print $calculateTax(100); // 5
$rate = .05;
// Exports variable to closure's scope
$calculateTax = function ($value) use (&$rate) { // notice the & before $rate
return $value * $rate;
};
$rate = .1;
print $calculateTax(100); // 10
Gli argomenti predefiniti non sono richiesti implicitamente quando si definiscono funzioni anonime con / senza chiusure.
$message = 'Im yelling at you';
$yell = function() use($message) {
echo strtoupper($message);
};
$yell(); // returns: IM YELLING AT YOU
Funzioni pure
Una funzione pura è una funzione che, dato lo stesso input, restituirà sempre lo stesso output e sarà priva di effetti collaterali .
// This is a pure function
function add($a, $b) {
return $a + $b;
}
Alcuni effetti collaterali stanno cambiando il filesystem , interagendo con i database , stampando sullo schermo .
// This is an impure function
function add($a, $b) {
echo "Adding...";
return $a + $b;
}
Gli oggetti come una funzione
class SomeClass {
public function __invoke($param1, $param2) {
// put your code here
}
}
$instance = new SomeClass();
$instance('First', 'Second'); // call the __invoke() method
Un oggetto con un metodo __invoke
può essere utilizzato esattamente come qualsiasi altra funzione.
Il metodo __invoke
avrà accesso a tutte le proprietà dell'oggetto e sarà in grado di chiamare qualsiasi metodo.
Metodi funzionali comuni in PHP
Mappatura
Applicazione di una funzione a tutti gli elementi di un array:
array_map('strtoupper', $array);
Essere consapevoli del fatto che questo è l'unico metodo della lista in cui la callback viene prima.
Ridurre (o piegare)
Ridurre una matrice a un singolo valore:
$sum = array_reduce($numbers, function ($carry, $number) {
return $carry + $number;
});
filtraggio
Restituisce solo gli elementi dell'array per cui il callback restituisce true
:
$onlyEven = array_filter($numbers, function ($number) {
return ($number % 2) === 0;
});