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'); 

Solutions Collecting From Web of "PHP call_user_func против просто вызывающей функции"

Всегда используйте имя фактической функции, когда вы это знаете.

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

Хотя вы можете вызвать имена переменных функций следующим образом:

 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); 

call_user_func опция call_user_func поэтому вы можете делать такие вещи, как:

 $dynamicFunctionName = "barber"; call_user_func($dynamicFunctionName, 'mushroom'); 

где строка dynamicFunctionName может быть более захватывающей и генерироваться во время выполнения. Вы не должны использовать call_user_func, если это необходимо, потому что оно медленнее.

Я предполагаю, что это полезно для вызова функции, которой вы не знаете имя заранее … Что-то вроде:

 switch($value): { case 7: $func = 'run'; break; default: $func = 'stop'; break; } call_user_func($func, 'stuff'); 

Нет никаких преимуществ, вызывающих такую ​​функцию, потому что я думаю, что в основном она используется для вызова функции «пользователь» (например, плагина), потому что редактирование файла ядра не является хорошим вариантом. вот грязный пример, используемый 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 

в первом примере вы используете имя функции, которое является строкой. это может происходить извне или определяться «на лету». то есть вы не знаете, какую функцию нужно будет запускать в момент создания кода.

При использовании пространств имен call_user_func () является единственным способом запуска функции, которую вы не знаете заранее, например:

 $function = '\Utilities\SearchTools::getCurrency'; call_user_func($function,'USA'); 

Если бы все ваши функции находились в одном и том же пространстве имен, то это не было бы такой проблемой, поскольку вы могли бы использовать что-то вроде этого:

 $function = 'getCurrency'; $function('USA'); 

Редактировать: После @ Джанниса, говорящего, что я ошибаюсь, я провел немного больше испытаний и не имел большой удачи:

 <?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.