PHP
Функциональное программирование
Поиск…
Вступление
Функциональное программирование PHP зависит от функций. Функции в PHP предоставляют организованный, многоразовый код для выполнения набора действий. Функции упрощают процесс кодирования, предотвращают избыточную логику и упрощают выполнение кода. В этом разделе описывается декларация и использование функций, аргументов, параметров, операторов возврата и области видимости в PHP.
Присвоение переменных
Анонимные функции могут быть назначены переменным для использования в качестве параметров, в которых ожидается обратный вызов:
$uppercase = function($data) {
return strtoupper($data);
};
$mixedCase = ["Hello", "World"];
$uppercased = array_map($uppercase, $mixedCase);
print_r($uppercased);
Эти переменные также могут использоваться как автономные вызовы функций:
echo $uppercase("Hello world!"); // HELLO WORLD!
Использование внешних переменных
Конструкция use
используется для импорта переменных в область анонимной функции:
$divisor = 2332;
$myfunction = function($number) use ($divisor) {
return $number / $divisor;
};
echo $myfunction(81620); //Outputs 35
Переменные также можно импортировать по ссылке:
$collection = [];
$additem = function($item) use (&$collection) {
$collection[] = $item;
};
$additem(1);
$additem(2);
//$collection is now [1,2]
Передача функции обратного вызова в качестве параметра
Существует несколько функций PHP, которые принимают пользовательские функции обратного вызова в качестве параметра, такие как: call_user_func()
, usort()
и array_map()
.
В зависимости от того, где определена определяемая пользователем функция обратного вызова, существуют разные способы их передачи:
Процедурный стиль:
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
Объектно-ориентированный стиль:
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
Объектно-ориентированный стиль с использованием статического метода:
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
Использование встроенных функций в качестве обратных вызовов
В функциях, callable
в качестве аргумента, вы также можете поместить строку с встроенной функцией PHP. Обычно используется trim
как параметр array_map
для удаления ведущего и array_map
пробела из всех строк в массиве.
$arr = [' one ', 'two ', ' three'];
var_dump(array_map('trim', $arr));
// array(3) {
// [0] =>
// string(3) "one"
// [1] =>
// string(3) "two"
// [2] =>
// string(5) "three"
// }
Анонимная функция
Анонимная функция - это просто функция , которая не имеет имени.
// Anonymous function
function() {
return "Hello World!";
};
В PHP анонимная функция рассматривается как выражение, и по этой причине она должна заканчиваться точкой с запятой ;
,
Для переменной должна быть назначена анонимная функция.
// Anonymous function assigned to a variable
$sayHello = function($name) {
return "Hello $name!";
};
print $sayHello('John'); // Hello John
Или он должен быть передан как параметр другой функции.
$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']
Или даже был возвращен из другой функции.
Самостоятельные анонимные функции:
// For PHP 7.x
(function () {
echo "Hello world!";
})();
// For PHP 5.x
call_user_func(function () {
echo "Hello world!";
});
Передача аргумента в самостоятельные исполняемые анонимные функции:
// For PHP 7.x
(function ($name) {
echo "Hello $name!";
})('John');
// For PHP 5.x
call_user_func(function ($name) {
echo "Hello $name!";
}, 'John');
Объем
В PHP анонимная функция имеет свою область видимости, как и любую другую функцию PHP.
В JavaScript анонимная функция может получить доступ к переменной во внешней области. Но в PHP это недопустимо.
$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
Затворы
Закрытие - анонимная функция, которая не может получить доступ к внешней области.
При определении анонимной функции как таковой вы создаете «пространство имен» для этой функции. В настоящее время он имеет доступ только к этому пространству имен.
$externalVariable = "Hello";
$secondExternalVariable = "Foo";
$myFunction = function() {
var_dump($externalVariable, $secondExternalVariable); // returns two error notice, since the variables aren´t defined
}
Он не имеет доступа к каким-либо внешним переменным. Чтобы предоставить это разрешение для этого пространства имен для доступа к внешним переменным, вам необходимо ввести его через закрытие ( use()
).
$myFunction = function() use($externalVariable, $secondExternalVariable) {
var_dump($externalVariable, $secondExternalVariable); // Hello Foo
}
Это в значительной степени связано с ограниченным охватом переменных PHP. Если переменная не определена в пределах области действия или не включена в global
то она не существует.
Также обратите внимание:
Наследование переменных из родительской области не совпадает с использованием глобальных переменных. Глобальные переменные существуют в глобальной области, что то же самое независимо от того, какая функция выполняется.
Родительская область замыкания - это функция, в которой было объявлено закрытие (не обязательно функция, из которой она была вызвана).
Взято из документации PHP для анонимных функций
В PHP закрытие использует ранний подход. Это означает, что переменные, переданные в пространство имен замыкания с use
ключевого слова use
будут иметь одинаковые значения, когда было определено закрытие.
Чтобы изменить это поведение, вы должны передать переменную по ссылке .
$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
Аргументы по умолчанию не обязательно требуются при определении анонимных функций с / без закрытия.
$message = 'Im yelling at you';
$yell = function() use($message) {
echo strtoupper($message);
};
$yell(); // returns: IM YELLING AT YOU
Чистые функции
Чистая функция - это функция, которая, учитывая тот же ввод, всегда будет возвращать тот же результат и свободна от побочных эффектов .
// This is a pure function
function add($a, $b) {
return $a + $b;
}
Некоторые побочные эффекты меняют файловую систему , взаимодействуют с базами данных , печатают на экране .
// This is an impure function
function add($a, $b) {
echo "Adding...";
return $a + $b;
}
Объекты как функция
class SomeClass {
public function __invoke($param1, $param2) {
// put your code here
}
}
$instance = new SomeClass();
$instance('First', 'Second'); // call the __invoke() method
Объект с методом __invoke
может использоваться точно так же, как любая другая функция.
Метод __invoke
будет иметь доступ ко всем свойствам объекта и сможет вызывать любые методы.
Общие функциональные методы в PHP
картографирование
Применение функции ко всем элементам массива:
array_map('strtoupper', $array);
Имейте в виду, что это единственный метод списка, где обратный вызов приходит первым.
Уменьшение (или складывание)
Уменьшение массива до одного значения:
$sum = array_reduce($numbers, function ($carry, $number) {
return $carry + $number;
});
фильтрация
Возвращает только элементы массива, для которых обратный вызов возвращает true
:
$onlyEven = array_filter($numbers, function ($number) {
return ($number % 2) === 0;
});