Я нахожусь в процессе изучения PHP, и концепция функций обратного вызова меня немного запутала. Я понимаю, что существуют синхронные и асинхронные обратные вызовы и что общий обратный вызов в PHP является синхронным. Я прочитал много информации по этой теме, но я все же не мудрый.
Как это:
function string($string, $callback) {
$results = array(
'upper' => strtoupper($string),
'lower' => strtolower($string)
);
if(is_callable($callback)) {
call_user_func($callback, $results);
}
}
string('Danny', function($name) {
echo $name['upper'];
}
);
Отличается или лучше, чем это:
function string($string, $case) {
$options = [
'upper' => strtoupper($string),
'lower' => strtolower($string)
];
echo $options[$case];
}
string('Danny', 'upper');
Вот типичный пример, где обратный вызов лучше, чем прямое значение:
function intricateProcessToCalculateDefault() {
//Takes 3 seconds
}
function valueOrDefault($value, $default = null) {
if ($value === null) {
if (is_callable($default)) {
return $default();
}
return $default;
}
return $value;
}
Теперь рассмотрим эти два примера:
$valueToUse = valueOrDefault(
$_GET["parameterWithFallback"] ?? null,
intricateProcessToCalculateDefault()
);
// or
$valueToUse = valueOrDefault(
$_GET["parameterWithFallback"] ?? null,
function () { return intricateProcessToCalculateDefault(); }
);
Теперь вот в чем дело. Если вы не пройдете parameterWithCallback
это займет 3 секунды в любом случае. Однако, если вы делаете, то intricateProcessToCalculateDefault
никогда не будет вызван, если передан как обратный вызов и, следовательно, сэкономит ваше время.
В вашем случае, так как код функции запускается в любом случае, нет никакой выгоды.
PHP в основном синхронный, поэтому нет простого способа получить асинхронные функции. Некоторые библиотеки предлагают их, но обычно это связано с вызовом исполняемого файла оболочки или чего-то подобного.
Другой вариант использования для инверсия для контроля. Есть много общих алгоритмов, которые могут быть реализованы с помощью «заполнителя» для пользовательского кода для. array_map
такой пример.
$array = [ "string1", "sting2" ];
$action = "upper";
array_map(function ($value) use ($action) {
return ucfirst(strtolower($value));
}, $array);
В этом случае управление инвертировано. Функция PHP вызывает вашу функцию, а не наоборот.
В этом примере с обратным вызовом вы можете легко передать другую функцию без изменения исходного кода:
<?php
function string($string, $callback) {
$results = array(
'upper' => strtoupper($string),
'lower' => strtolower($string)
);
if(is_callable($callback)) {
call_user_func($callback, $results);
}
}
string('Danny', function($name) {
echo $name['upper'];
}
);
string('Danny', function($name) {
echo 'Mr.'.$name['upper'];
}
);
string('Danny', function($name) {
echo 'Mrs.'.$name['upper'];
}
);