PHP-запрос пользователя Функ и просто вызов функции


Я уверен, что есть очень простое объяснение. В чем разница между этим:

function barber($type){
    echo "You wanted a $type haircut, no problemn";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");

... и это (а в чем польза?):

function barber($type){
    echo "You wanted a $type haircut, no problemn";
}
barber('mushroom');
barber('shave');
8 76

8 ответов:

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

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

the 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

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

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

$ret = $callable(...$params);

при использовании пространств имен 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.