Поиск…


Вступление

Функциональное программирование 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;
});


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow