PHP 7 — использование PHP анонимных функций

Так что я действительно озадачен анонимными функциями в PHP, я хочу знать, используются ли анонимные функции в основном по вкусу или стилю кодирования.

Я спрашиваю об этом, потому что вы можете достичь того же результата без функции обратного вызова и меньшего количества кода.

Итак, вот некоторый тестовый код:

$output = 10;
$people = (new People(new John));

//VERSION 1 ANONYMOUS FUNCTION
$people->run(function ($value) use(&$output){
$output = $output + $value;
});

var_dump($output); //RESULT => 20

//VERSION 2 WITHOUT ANONYMOUS FUNCTION
var_dump($people->run() + $output); //RESULT => 30

Вы можете запустить и увидеть полный код здесь:
https://www.tehplayground.com/IhWJJU0jbNnzuird

<?php

interface HumanInterface
{
public function hello();
}

class People
{
protected $person;
protected $value;

public function __construct(HumanInterface $person)
{
$this->person = $person;
return $this;
}

public function run(callable $callback = null, $name = null)
{
$this->value = 10;
if(is_callable($callback)) {
return call_user_func($callback, $this->value);
}

return $this->value;
}
}

class John implements HumanInterface
{
public function hello()
{
return 'hi i am john';
}
}
$output = 10;
$people = (new People(new John));
$people->run(function ($value) use(&$output){
$output = $output + $value;
});

var_dump($output);
var_dump($people->run() + $output);

Поэтому мой вопрос: зачем использовать анонимную функцию? Это вопрос
личный выбор?

1

Решение

Анонимные функции или «замыкания» очень полезны, если они используются в качестве одноразового обратного вызова. Если вы используете PHP usortметод например. Вторым параметром может быть Закрытие. Поэтому вместо написания именованной функции, которая используется один раз, а затем никогда больше, вы используете Closure.
ИМХО, это единственный способ использовать замыкания: как обратный вызов.

1

Другие решения

Анонимные функции полезны для последующего выполнения или для других функций, принимающих код. Их использование может значительно сократить код, необходимый для выполнения каких-либо задач.

Представь, что у тебя есть UserCollection объект, который использует общую коллекцию внизу. Вы хотите уменьшить UserCollection только пользователям из определенной страны. Чтобы вы могли добавить метод findByCountry() на UserCollection:

public function findByCountry($country) : UserCollection {
$subset = new UserCollection;
foreach ($this->users as $user) {
if ($user->country === $country) {
$subset->add($user);
}
}
return $subset;
}

Это все хорошо, но дополнительные методы поиска будут делать то же самое: выполнять итерации и собирать в подмножество только с разными критериями. Так много шаблонного кода.

Вы можете легко отделить шаблон от критериев, добавив метод find(callable $callback) в основной коллекции, вот так:

public function find(callable $criteria) : Collection {
$subset = new Collection;
foreach ($this->users as $user) {
if ($criteria($user)) {
$subset->add($user);
}
}
return $subset;
}

Это общий поиск. Теперь ваш код в UserCollection будет содержать только фактические критерии:

public function findByCountry($country): UserCollection {
return $this->subset(function(User $user) {
return $user->country === $country;
});
}

private function subset($criteria): UserCollection {
return new UserCollection($this->allUsers->find($criteria));
}

Отделяя критерии от стандартного, гораздо проще понять, что вы пытаетесь найти пользователей по стране. Там нет итерационного кода, отвлекающего от фактических критериев. Так становится легче понять и меньше усилий писать. Кроме того, вы не можете случайно испортить итерацию, потому что она определена в другом месте.

При использовании анонимных функций, подобных этой, они очень похожи на использование шаблона стратегии или FilterIterator, Заметная разница в том, что вы создаете их на лету.

Обратите внимание, что вы должны различать лямбды и затворы. Я сознательно проигнорировал разницу для этого ответа.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector