PHP call user func vs. just calling Func

Jestem pewien, że jest na to bardzo łatwe wytłumaczenie. Jaka jest różnica między tym:

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

... i to (i jakie są korzyści?):

function barber($type){
    echo "You wanted a $type haircut, no problem\n";
}
barber('mushroom');
barber('shave');
Author: Donald Duck, 2009-10-20

8 answers

Zawsze używaj rzeczywistej nazwy funkcji, gdy ją znasz.

call_user_func służy do wywoływania funkcji, których nazwy nie znasz wcześniej, ale jest znacznie mniej wydajny, ponieważ program musi wyszukać funkcję w czasie wykonywania.

 74
Author: Kai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 17:49:43

Chociaż można wywołać nazwy funkcji zmiennych w ten sposób:

function printIt($str) { print($str); }

$funcname = 'printIt';
$funcname('Hello world!');
Są przypadki, w których nie wiesz, ile argumentów przekazujesz. Rozważmy następujące:
function someFunc() {
  $args = func_get_args();
  // do something
}

call_user_func_array('someFunc',array('one','two','three'));

Jest również przydatny do wywołania odpowiednio metod statycznych i obiektowych:

call_user_func(array('someClass','someFunc'),$arg);
call_user_func(array($myObj,'someFunc'),$arg);
 30
Author: Lucas Oman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 18:13:20

Opcja call_user_func jest dostępna, więc możesz robić takie rzeczy jak:

$dynamicFunctionName = "barber";

call_user_func($dynamicFunctionName, 'mushroom');

Gdzie dynamicFunctionName ciąg może być bardziej ekscytujący i generowany w czasie wykonywania. Nie powinieneś używać call_user_func, chyba że musisz, ponieważ jest to wolniejsze.

 14
Author: Brian Schroth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 20:21:15

Wyobrażam sobie, że jest to przydatne do wywołania funkcji, której nie znasz z góry nazwy... Coś w stylu:

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

call_user_func($func, 'stuff');
 6
Author: pivotal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 17:50:49

Nie ma żadnych korzyści wywołanie funkcji w ten sposób, ponieważ myślę, że głównie używane do wywołania funkcji "user" (jak plugin), ponieważ edycja pliku core nie jest dobrym rozwiązaniem. oto brudny przykład używany przez 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
?>

Wyjście

hello world my name is Tasikmalaya
 2
Author: uingtea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-27 10:42:48

W pierwszym przykładzie używasz nazwy funkcji, która jest ciągiem znaków. może pochodzić z zewnątrz lub być ustalana w locie. oznacza to, że nie wiesz, jaka funkcja będzie musiała zostać uruchomiona w momencie tworzenia kodu.

 0
Author: SilentGhost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 17:48:59

Z PHP 7 możesz używać ładniejszej składni zmiennej - funkcji wszędzie. Działa z funkcjami statycznymi/instancyjnymi i może przyjmować szereg parametrów. Więcej informacji na https://trowski.com/2015/06/20/php-callable-paradox

$ret = $callable(...$params);
 0
Author: mils,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-12 03:46:47

Podczas używania przestrzeni nazw, call_user_func () jest jedynym sposobem na uruchomienie funkcji, której wcześniej nie znasz, na przykład:

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

Gdyby wszystkie twoje funkcje były w tej samej przestrzeni nazw, to nie byłby to taki problem, ponieważ możesz użyć czegoś takiego:

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

Edytuj: Po tym jak @Jannis powiedział, że się mylę zrobiłem trochę więcej testów i nie miałem dużo szczęścia:

<?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()'
}

Możesz zobaczyć wyniki wyjściowe tutaj: https://3v4l.org/iBERh wydaje się, że druga metoda działa w PHP 7, ale nie w PHP 5.6.

 -1
Author: ThomasRedstone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 14:51:32