PHP call_user_func vs. nur Funktion aufrufen


90

Ich bin sicher, dass es dafür eine sehr einfache Erklärung gibt. Was ist der Unterschied zwischen diesen:

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

... und das (und was sind die Vorteile?):

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

Antworten:


87

Verwenden Sie immer den tatsächlichen Funktionsnamen, wenn Sie ihn kennen.

call_user_func dient zum Aufrufen von Funktionen, deren Namen Sie nicht im Voraus kennen, die jedoch viel weniger effizient sind, da das Programm die Funktion zur Laufzeit nachschlagen muss.


Danke Kai. call_user_func erwies sich als genau das, was ich brauchte.
Jay

44
call_user_funcwird nicht unbedingt benötigt. Sie können eine Funktion jederzeit mit variablen Funktionen aufrufen : $some_func(). call_user_func_arrayist derjenige, der wirklich nützlich ist.
Ionuț G. Stan

22
PHP muss immer "die Funktion zur Laufzeit
nachschlagen

2
@ Pacerier Falsch. Anonyme Funktionen sind immer noch in Variablen, dh $func = function(){};. Jeder möglicher Parameter call_user_func hat aufrufbar zu sein, was bedeutet , dass es genügend Daten für den Zugriff enthält es direkt, ob das $func(), oder $obj->{$func}(), oder was auch immer.
Benubird

1
Die "weniger effiziente" ist eigentlich sehr wenig, besonders seit PHP7, es geht um wenige ms / Million Anrufe: github.com/fab2s/call_user_func
fab2s

32

Obwohl Sie variable Funktionsnamen folgendermaßen aufrufen können:

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

$funcname = 'printIt';
$funcname('Hello world!');

Es gibt Fälle, in denen Sie nicht wissen, wie viele Argumente Sie übergeben. Folgendes berücksichtigen:

function someFunc() {
  $args = func_get_args();
  // do something
}

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

Es ist auch praktisch, um statische bzw. Objektmethoden aufzurufen:

call_user_func(array('someClass','someFunc'),$arg);
call_user_func(array($myObj,'someFunc'),$arg);

8
Ich weiß, dass dies uralt ist, konnte aber anderswo keine Artikel finden. Ist es vorteilhafter, call_user_func ('customFunction') als $ variableFunction () zu verwenden? Was sind die Unterschiede? Vielen Dank!
David Hobs

15

Die call_user_funcOption ist da, damit Sie Dinge tun können wie:

$dynamicFunctionName = "barber";

call_user_func($dynamicFunctionName, 'mushroom');

wo die dynamicFunctionNameZeichenfolge aufregender sein und zur Laufzeit generiert werden könnte. Sie sollten call_user_func nicht verwenden, es sei denn, Sie müssen, weil es langsamer ist.


1
Es scheint, als könnten Sie in diesem Szenario eine variable Funktion verwenden.
Anthony Rutledge

6

Ich stelle mir vor, es ist nützlich, um eine Funktion aufzurufen, deren Namen Sie nicht im Voraus kennen ... So etwas wie:

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

call_user_func($func, 'stuff');

5
Nee. Wir können es immer noch tun$func('stuff');
ankush981

1
Ja, aber der Unterschied bei der Verwendung einer Variablen führt zu einem schwerwiegenden PHP-Fehler gegenüber einer PHP-Warnung, wenn call_user_func verwendet wird.
Robert Brisita

Dies hat den Wert variabler Funktionen call_user_func()in diesem Szenario nicht negiert .
Anthony Rutledge


3

Es gibt keine Vorteile, wenn man die Funktion so aufruft, weil ich denke, dass sie hauptsächlich zum Aufrufen der "Benutzer" -Funktion (wie das Plugin) verwendet wird, da das Bearbeiten der Kerndatei keine gute Option ist. Hier sind schmutzige Beispiele, die von Wordpress verwendet werden

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

Ausgabe

hello world my name is Tasikmalaya

0

In Ihrem ersten Beispiel verwenden Sie den Funktionsnamen, bei dem es sich um eine Zeichenfolge handelt. es kann von außen kommen oder im laufenden Betrieb bestimmt werden. Das heißt, Sie wissen nicht, welche Funktion zum Zeitpunkt der Codeerstellung ausgeführt werden muss.


-1

Wenn Sie Namespaces verwenden, ist call_user_func () die einzige Möglichkeit, eine Funktion auszuführen, deren Namen Sie vorher nicht kennen, zum Beispiel:

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

Wenn sich alle Ihre Funktionen im selben Namespace befinden würden, wäre dies kein Problem, da Sie Folgendes verwenden könnten:

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

Edit: Nachdem @Jannis gesagt hat, dass ich falsch liege, habe ich ein bisschen mehr getestet und hatte nicht viel Glück:

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

Sie können die Ausgabeergebnisse hier sehen: https://3v4l.org/iBERh Es scheint, dass die zweite Methode ab PHP 7 funktioniert, nicht jedoch PHP 5.6.


. für nicht wahr sein. $ fn = '\ Foo \ Bar \ getCurrency'; $ fn ();
Jan Sverre

Hallo @Jannis, ich finde das nicht wahr. Vielleicht kannst du sehen, wo ich falsch liege. Ich habe meiner Antwort ein detaillierteres Beispiel hinzugefügt.
Thomas Redstone

@ThomasRedstone haben Sie diese Funktionen vorher benötigt? PHP laden nicht automatisch Funktionen aus anderen Dateien. Auch was ist mit diesen kleinen gegen großen Buchstaben in Namespaces. Ist Bar eine Klasse? dann ist das ein weiterer Anwendungsfall.
przemo_li

hi @przemo_li, dies ist eine einzelne Datei (alle innerhalb des Namespace), nicht sicher, was mit dem Namespace-Namen passiert ist. Zu meiner Verteidigung habe ich die Antwort vor 4 Jahren geschrieben, den Namespace aktualisiert und einen Hinweis hinzugefügt PHP 7, mit einem Link, um die tatsächliche Ausgabe zu sehen. Ich weiß immer noch nicht, wie jansverre es funktioniert hat, PHP 7 hat Alpha erst am 11. Juni 2015
eingegeben
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.