PHP call_user_func против просто вызывающей функции
Я уверен, что для этого очень простое объяснение. В чем разница между ними:
function barber($type){
echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
... и это (и каковы преимущества?):
function barber($type){
echo "You wanted a $type haircut, no problem\n";
}
barber('mushroom');
barber('shave');
Ответы
Ответ 1
Всегда используйте имя фактической функции, когда вы ее знаете.
call_user_func
предназначен для вызовов функций, имя которых вы не знаете заранее, но оно намного менее эффективно, так как программа должна искать функцию во время выполнения.
Ответ 2
Хотя вы можете вызвать имена переменных функций следующим образом:
function printIt($str) { print($str); }
$funcname = 'printIt';
$funcname('Hello world!');
Есть случаи, когда вы не знаете, сколько аргументов вы передаете. Рассмотрим следующее:
function someFunc() {
$args = func_get_args();
// do something
}
call_user_func_array('someFunc',array('one','two','three'));
Это также удобно для вызова статических и объектных методов, соответственно:
call_user_func(array('someClass','someFunc'),$arg);
call_user_func(array($myObj,'someFunc'),$arg);
Ответ 3
существует опция call_user_func
, поэтому вы можете делать такие вещи, как:
$dynamicFunctionName = "barber";
call_user_func($dynamicFunctionName, 'mushroom');
где строка dynamicFunctionName
может быть более захватывающей и сгенерирована во время выполнения. Вы не должны использовать call_user_func, если это необходимо, потому что оно медленнее.
Ответ 4
Я предполагаю, что это полезно для вызова функции, которой вы не знаете имя заранее...
Что-то вроде:
switch($value):
{
case 7:
$func = 'run';
break;
default:
$func = 'stop';
break;
}
call_user_func($func, 'stuff');
Ответ 5
Нет никаких преимуществ, вызывающих такую функцию, потому что я думаю, что в основном она используется для вызова функции "пользователь" (например, плагина), потому что редактирование файла ядра не является хорошим вариантом. вот грязный пример, используемый Wordpress
<?php
/*
* my_plugin.php
*/
function myLocation($content){
return str_replace('@', 'world', $content);
}
function myName($content){
return $content."Tasikmalaya";
}
add_filter('the_content', 'myLocation');
add_filter('the_content', 'myName');
?>
...
<?php
/*
* core.php
* read only
*/
$content = "hello @ my name is ";
$listFunc = array();
// store user function to array (in my_plugin.php)
function add_filter($fName, $funct)
{
$listFunc[$fName]= $funct;
}
// execute list user defined function
function apply_filter($funct, $content)
{
global $listFunc;
if(isset($listFunc))
{
foreach($listFunc as $key => $value)
{
if($key == $funct)
{
$content = call_user_func($listFunc[$key], $content);
}
}
}
return $content;
}
function the_content()
{
$content = apply_filter('the_content', $content);
echo $content;
}
?>
....
<?php
require_once("core.php");
require_once("my_plugin.php");
the_content(); // hello world my name is Tasikmalaya
?>
Выход
hello world my name is Tasikmalaya
Ответ 6
в первом примере вы используете имя функции, которое является строкой. это может происходить извне или определяться "на лету". то есть вы не знаете, какую функцию нужно будет запускать в момент создания кода.
Ответ 7
При использовании пространств имен call_user_func() является единственным способом запуска функции, которую вы не знаете заранее, например:
$function = '\Utilities\SearchTools::getCurrency';
call_user_func($function,'USA');
Если все ваши функции находились в одном и том же пространстве имен, это не было бы такой проблемой, поскольку вы могли бы использовать что-то вроде этого:
$function = 'getCurrency';
$function('USA');
Изменить:
Следуя @Jannis, заявив, что я ошибаюсь, я сделал немного больше тестов и не имел большой удачи:
<?php
namespace Foo {
class Bar {
public static function getBar() {
return 'Bar';
}
}
echo "<h1>Bar: ".\Foo\Bar::getBar()."</h1>";
// outputs 'Bar: Bar'
$function = '\Foo\Bar::getBar';
echo "<h1>Bar: ".$function()."</h1>";
// outputs 'Fatal error: Call to undefined function \Foo\Bar::getBar()'
$function = '\Foo\Bar\getBar';
echo "<h1>Bar: ".$function()."</h1>";
// outputs 'Fatal error: Call to undefined function \foo\Bar\getBar()'
}
Вы можете увидеть результаты вывода здесь: https://3v4l.org/iBERh кажется, что второй метод работает для PHP 7, но не PHP 5.6.