2009-10-20 2 views
70

Я уверен, что для этого очень простое объяснение. В чем разница между этим: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'); 

ответ

65

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

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

+0

Спасибо, Кай. call_user_func оказался именно тем, что мне нужно. – jay

+38

'call_user_func' необязательно необходимо. Вы всегда можете вызывать функцию с помощью переменных функций: '$ some_func()'. 'call_user_func_array' - тот, который действительно полезен. –

+18

php всегда нуждается в «поиске функции во время выполнения» – VolkerK

0

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

12

опция call_user_func есть, так что вы можете сделать что-то вроде:

$dynamicFunctionName = "barber"; 

call_user_func($dynamicFunctionName, 'mushroom'); 

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

+0

Похоже, что вы можете использовать переменную функцию в этом сценарии. –

5

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

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

call_user_func($func, 'stuff'); 
+3

Нет. Мы все еще можем использовать '$ func ('stuff');' – dotslash

+0

Да, но разница в использовании переменной приведет к ошибке PHP Fatal по сравнению с предупреждением PHP, если используется call_user_func. –

+0

Это не отрицает значение переменных функций над 'call_user_func()' в этом сценарии. –

28

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

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

Я знаю, что это возраст, но не нашел статей в другом месте. Полезно ли использовать call_user_func ('customFunction'), как и $ variableFunction()? Каковы различия? Благодаря! –

-1

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

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

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

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

Edit: После @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.

+0

. потому что это не так. $ fn = '\ Foo \ Bar \ getCurrency'; $ П(); –

+0

Привет @Jannis, я не считаю, что это правда, может быть, вы можете увидеть, где я ошибаюсь, я добавил более подробный пример моего ответа. – ThomasRedstone

+0

@ThomasRedstone, вам были нужны эти функции заранее? php не выполняет функции автозагрузки из других файлов. Также, что с этим маленьким против больших букв в пространствах имен. Является ли Bar классом? то это еще одна утилита. –

1

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

С PHP 7 вы можете использовать более хороший синтаксис переменной функции везде. Он работает со статическими/экземплярами функций, и он может принимать множество параметров. Больше информации на https://trowski.com/2015/06/20/php-callable-paradox

$ret = $callable(...$params); 
Смежные вопросы