PHP
Programowanie funkcjonalne
Szukaj…
Wprowadzenie
Programowanie funkcjonalne PHP opiera się na funkcjach. Funkcje w PHP zapewniają zorganizowany kod wielokrotnego użytku do wykonywania zestawu działań. Funkcje upraszczają proces kodowania, zapobiegają nadmiarowej logice i ułatwiają śledzenie kodu. W tym temacie opisano deklarację i wykorzystanie funkcji, argumentów, parametrów, instrukcji return i zakresu w PHP.
Przypisanie do zmiennych
Funkcje anonimowe można przypisać do zmiennych w celu użycia ich jako parametrów, w których oczekuje się wywołania zwrotnego:
$uppercase = function($data) {
return strtoupper($data);
};
$mixedCase = ["Hello", "World"];
$uppercased = array_map($uppercase, $mixedCase);
print_r($uppercased);
Zmiennych tych można również używać jako samodzielnych wywołań funkcji:
echo $uppercase("Hello world!"); // HELLO WORLD!
Korzystanie ze zmiennych zewnętrznych
Konstrukcja use
służy do importowania zmiennych do zakresu funkcji anonimowej:
$divisor = 2332;
$myfunction = function($number) use ($divisor) {
return $number / $divisor;
};
echo $myfunction(81620); //Outputs 35
Zmienne można również importować przez odniesienie:
$collection = [];
$additem = function($item) use (&$collection) {
$collection[] = $item;
};
$additem(1);
$additem(2);
//$collection is now [1,2]
Przekazywanie funkcji zwrotnej jako parametru
Istnieje kilka funkcji PHP, które akceptują zdefiniowane przez użytkownika funkcje zwrotne jako parametr, takie jak: call_user_func()
, usort()
i array_map()
.
W zależności od tego, gdzie zdefiniowano funkcję wywołania zwrotnego zdefiniowaną przez użytkownika, istnieją różne sposoby jej przekazania:
Styl proceduralny:
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
Styl obiektowy:
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
Styl obiektowy przy użyciu metody statycznej:
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
Korzystanie z wbudowanych funkcji jako wywołań zwrotnych
W funkcjach, w których można callable
argument jako argument, można również wstawić ciąg znaków za pomocą wbudowanej funkcji PHP. Powszechnie używa się parametru trim
jako parametru array_map
do usuwania array_map
i końcowych białych znaków ze wszystkich ciągów w tablicy.
$arr = [' one ', 'two ', ' three'];
var_dump(array_map('trim', $arr));
// array(3) {
// [0] =>
// string(3) "one"
// [1] =>
// string(3) "two"
// [2] =>
// string(5) "three"
// }
Funkcja anonimowa
Funkcja anonimowa to po prostu funkcja , która nie ma nazwy.
// Anonymous function
function() {
return "Hello World!";
};
W PHP anonimowa funkcja jest traktowana jak wyrażenie i z tego powodu powinna być zakończona średnikiem ;
.
Do zmiennej należy przypisać funkcję anonimową.
// Anonymous function assigned to a variable
$sayHello = function($name) {
return "Hello $name!";
};
print $sayHello('John'); // Hello John
Lub powinien zostać przekazany jako parametr innej funkcji.
$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']
Lub nawet zostały zwrócone z innej funkcji.
Samoczynne anonimowe funkcje:
// For PHP 7.x
(function () {
echo "Hello world!";
})();
// For PHP 5.x
call_user_func(function () {
echo "Hello world!";
});
Przekazywanie argumentu do samodzielnie wykonujących się funkcji anonimowych:
// For PHP 7.x
(function ($name) {
echo "Hello $name!";
})('John');
// For PHP 5.x
call_user_func(function ($name) {
echo "Hello $name!";
}, 'John');
Zakres
W PHP anonimowa funkcja ma swój własny zakres, jak każda inna funkcja PHP.
W JavaScript anonimowa funkcja może uzyskać dostęp do zmiennej spoza zakresu. Ale w PHP jest to niedozwolone.
$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
Domknięcia
Zamknięcie jest anonimową funkcją, która nie może uzyskać dostępu poza zakresem.
Definiując anonimową funkcję jako taką, tworzysz „przestrzeń nazw” dla tej funkcji. Obecnie ma dostęp tylko do tej przestrzeni nazw.
$externalVariable = "Hello";
$secondExternalVariable = "Foo";
$myFunction = function() {
var_dump($externalVariable, $secondExternalVariable); // returns two error notice, since the variables aren´t defined
}
Nie ma dostępu do żadnych zmiennych zewnętrznych. Aby przyznać to uprawnienie dla tego obszaru nazw w celu uzyskania dostępu do zmiennych zewnętrznych, należy wprowadzić je za pomocą zamknięć ( use()
).
$myFunction = function() use($externalVariable, $secondExternalVariable) {
var_dump($externalVariable, $secondExternalVariable); // Hello Foo
}
Jest to w dużej mierze przypisywane ścisłemu określaniu zakresu zmiennych PHP - jeśli zmienna nie jest zdefiniowana w zakresie lub nie jest wprowadzana z global
wówczas nie istnieje.
Uwaga:
Dziedziczenie zmiennych z zakresu nadrzędnego to nie to samo, co używanie zmiennych globalnych. Zmienne globalne istnieją w zasięgu globalnym, który jest taki sam bez względu na wykonywaną funkcję.
Zakres nadrzędny zamknięcia jest funkcją, w której zostało zadeklarowane zamknięcie (niekoniecznie funkcja, z której został wywołany).
Na podstawie dokumentacji PHP dla funkcji anonimowych
W PHP zamknięcia używają wczesnego wiązania . Oznacza to, że zmienne przekazywane do przestrzeni nazw zamknięcia za use
słowa kluczowego use
będą miały takie same wartości, gdy zdefiniowane zostanie zamknięcie.
Aby zmienić to zachowanie, należy przekazać zmienną przez odniesienie .
$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
Domyślne argumenty nie są domyślnie wymagane przy definiowaniu anonimowych funkcji z / bez zamknięć.
$message = 'Im yelling at you';
$yell = function() use($message) {
echo strtoupper($message);
};
$yell(); // returns: IM YELLING AT YOU
Czyste funkcje
Funkcja czysta to funkcja, która przy takim samym wejściu zawsze zwraca tę samą moc wyjściową i nie powoduje skutków ubocznych .
// This is a pure function
function add($a, $b) {
return $a + $b;
}
Niektóre skutki uboczne to zmiana systemu plików , interakcja z bazami danych , drukowanie na ekranie .
// This is an impure function
function add($a, $b) {
echo "Adding...";
return $a + $b;
}
Obiekty jako funkcja
class SomeClass {
public function __invoke($param1, $param2) {
// put your code here
}
}
$instance = new SomeClass();
$instance('First', 'Second'); // call the __invoke() method
Obiekt z metodą __invoke
może być używany dokładnie tak samo, jak każda inna funkcja.
Metoda __invoke
będzie miała dostęp do wszystkich właściwości obiektu i będzie mogła wywoływać dowolne metody.
Typowe metody funkcjonalne w PHP
Mapowanie
Zastosowanie funkcji do wszystkich elementów tablicy:
array_map('strtoupper', $array);
Należy pamiętać, że jest to jedyna metoda listy, w której oddzwanianie jest pierwsze.
Zmniejszenie (lub złożenie)
Zmniejszenie tablicy do jednej wartości:
$sum = array_reduce($numbers, function ($carry, $number) {
return $carry + $number;
});
Filtracja
Zwraca tylko elementy tablicy, dla których callback zwraca true
:
$onlyEven = array_filter($numbers, function ($number) {
return ($number % 2) === 0;
});