Jestem pewien, że istnieje na to bardzo proste 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');
call_user_func
niekoniecznie jest potrzebne. Zawsze można wywołać funkcję za pomocą funkcji zmiennych:$some_func()
.call_user_func_array
jest tym, który jest naprawdę przydatny.$func = function(){};
. Ewentualne parametrem call_user_func musi być wymagalne, co oznacza, że zawiera wystarczającą ilość danych, aby uzyskać dostęp to bezpośrednio, czy to$func()
, czy$obj->{$func}()
, czy cokolwiek.Chociaż nazwy funkcji zmiennych można wywoływać 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ż 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ływania odpowiednio metod statycznych i obiektowych:
call_user_func(array('someClass','someFunc'),$arg); call_user_func(array($myObj,'someFunc'),$arg);
źródło
call_user_func
opcja jest tam tak można robić takie rzeczy jak:$dynamicFunctionName = "barber"; call_user_func($dynamicFunctionName, 'mushroom');
gdzie
dynamicFunctionName
ciąg mógłby być bardziej ekscytujący i generowany w czasie wykonywania. Nie powinieneś używać call_user_func, chyba że musisz, ponieważ jest wolniejszy.źródło
Wyobrażam sobie, że jest to przydatne do wywoływania funkcji, której nazwy z góry nie znasz ... Coś takiego:
switch($value): { case 7: $func = 'run'; break; default: $func = 'stop'; break; } call_user_func($func, 'stuff');
źródło
$func('stuff');
call_user_func()
w tym scenariuszu.W PHP 7 możesz wszędzie używać ładniejszej składni zmiennej i funkcji. Działa z funkcjami statycznymi / instancjami i może przyjmować tablicę parametrów. Więcej informacji na https://trowski.com/2015/06/20/php-callable-paradox
źródło
Nie ma żadnych korzyści z wywoływania tej funkcji w ten sposób, ponieważ myślę, że była używana głównie do wywoływania funkcji użytkownika (takiej jak wtyczka), ponieważ edycja pliku podstawowego nie jest dobrą opcją. 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 ?>
wynik
źródło
w pierwszym przykładzie używasz nazwy funkcji, która jest łańcuchem. może pochodzić z zewnątrz lub zostać ustalone w locie. to znaczy nie wiesz, jaka funkcja będzie musiała zostać uruchomiona w momencie tworzenia kodu.
źródło
Podczas korzystania z przestrzeni nazw call_user_func () jest jedynym sposobem na uruchomienie funkcji, której nazwy nie znasz, na przykład:
$function = '\Utilities\SearchTools::getCurrency'; call_user_func($function,'USA');
Gdyby wszystkie twoje funkcje znajdowały się w tej samej przestrzeni nazw, nie byłby to taki problem, ponieważ możesz użyć czegoś takiego:
$function = 'getCurrency'; $function('USA');
Edycja: Śledząc @Jannis mówiąc, że się mylę, przeprowadził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 od PHP 7, ale nie PHP 5.6.
źródło