Wie führe ich sofort eine anonyme Funktion in PHP aus?

96

In JavaScript können Sie anonyme Funktionen definieren, die sofort ausgeführt werden:

(function () { /* do something */ })()

Können Sie so etwas in PHP machen?

Emanuil Rusev
quelle
2
Ich habe kein PHP 5.3 zum Ausprobieren, aber wie geht call_user_func(function(){/* stuff */})das?
Jasper

Antworten:

120

Für PHP7: siehe Yasuo Ohgakis Antwort :(function() {echo 'Hi';})();

Für frühere Versionen: Die einzige Möglichkeit, sie sofort auszuführen, ist die, an die ich denken kann

call_user_func(function() { echo 'executed'; });
Gordon
quelle
12
Dies wäre auch mein Vorschlag, es sei denn, die Verkettung von Funktionsaufrufen wird eingeführt (oder bis) .
Salathe
2
@ Gordon: PHP 5.4 noch nichts?
dynamische
@ yes123 nein. müssen noch verwendencall_user_func
Gordon
2
@BennettMcElwee sagen wir es so: Selbst wenn dies etwas langsamer als die Alternative zum Definieren, Zuweisen und Aufrufen ist, ist die Wahrscheinlichkeit, dass dies einen erheblichen Engpass in Ihrer Anwendung darstellt, sehr gering. Im Zweifelsfall profilieren Sie Ihre App unter realen Bedingungen.
Gordon
Danke @Gordon, das habe ich mir gedacht. Ich hatte den Eindruck, dass salathe und yes123 mit dieser Methode nicht zufrieden waren, und ich fragte mich, warum. Scheint mir vollkommen in Ordnung zu sein.
Bennett McElwee
28

In PHP 7ist das gleiche in Javascript zu tun

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

Die Ausgabe ist:

1
2
3
Wallace Maxters
quelle
15

Natürlich können Sie verwenden call_user_func, aber es gibt noch eine andere ziemlich einfache Alternative:

<?php
// we simply need to write a simple function called run:
function run($f){
    $f();
}

// and then we can use it like this:
run(function(){
    echo "do something";
});

?>
Pacerier
quelle
1
Ich möchte eine sofort ausgeführte Funktion, da die von mir definierte Funktion eine Funktion ist, die bei normaler Ausführung NICHT mehr als einmal aufgerufen werden sollte. Das Problem beim Definieren einer benannten Funktion, run (), wie Sie es getan haben, besteht darin, dass jeder andere, der den Code sieht, denkt, dass er run () auch in einem anderen Teil des Codes aufrufen kann. Die sofort ausführbare Funktion macht deutlich, dass dieser Code nicht zweimal ausgeführt werden sollte.
Daniel Howard
3
Sie können runIhre Funktion in einem anderen Teil des Codes nicht aufrufen, da nach der Zeile, die sie sofort ausführt, kein Handle für Ihre Funktion vorhanden ist.
Pacerier
3
@DanielHoward Der Zweck von run()besteht darin, die an ihn übergebene unbenannte Funktion sofort auszuführen. Es call_user_func()werden nur keine Parameter übergeben.
Cypher
1
@JordanLev, Es hat eine einfachere Implementierung (nur eine Zeile :) $f();und ist möglicherweise schneller, wenn die von Ihnen verwendete Engine nicht für den Sonderfall optimiert wird, in dem call_user_funcnur ein Funktionsargument vorhanden ist. Dies liegt daran, dass call_user_funcdie Übergabe mehrerer Parameter unterstützt wird und das erste Argument entweder eine Zeichenfolge als Argument oder eine Funktion unterstützt. Das heißt, wenn call_user_funces gut lesbar ist, würde ich es nur verwenden, runwenn sich der Code irgendwo unten in der Pyramide befindet .
Pacerier
1
@JordanLev, "einfachere Implementierung" bezieht sich auf den Vergleich zwischen dem Code innerhalb der Funktionen runund call_user_func. call_user_funchat einen inhärenten Nachteil im Vergleich zu runweil runnur eine Sache tut, während call_user_funczusätzliche Funktionen zusätzlich zu dem, was runtut, unterstützt. Sie können einen schnellen Schleifentest ( z. B. ) durchführen, um festzustellen, welcher Motor schneller ist.
Pacerier
11

Dies ist die einfachste Version für PHP 7.0 oder höher.

php -r '(function() {echo 'Hi';})();'

Es bedeutet, einen Abschluss zu erstellen und ihn dann als Funktion aufzurufen, indem Sie "()" folgen. Funktioniert genau wie JS dank einheitlicher variabler Auswertungsreihenfolge.

https://3v4l.org/06EL3

Yasuo Ohgaki
quelle
2
Gute Antwort, aber warum formatieren Sie es als Befehlszeilenoperation?
Kodos Johnson
6
(new ReflectionFunction(function() {
 // body function
}))->invoke();
Innermond
quelle
6
Können Sie mehr Details liefern? vielleicht eine Erklärung hinzufügen?
MoralCode
2

Hinweis, akzeptierte Antwort in Ordnung ist, aber 1,41x so lange dauert (41% langsamer) als das Deklarieren einer Funktion und das Aufrufen in zwei Zeilen.

[Ich weiß, dass es keine wirklich neue Antwort ist, aber ich fand es wertvoll, diese irgendwo für Besucher hinzuzufügen.]

Einzelheiten:

<?php
# Tags: benchmark, call_user_func, anonymous function 
require_once("Benchmark.php");
bench(array(
        'test1_anonfunc_call' => function(){
                $f = function(){
                        $x = 123;
                };
                $f();
        },
        'test2_anonfunc_call_user_func' => function(){
                call_user_func(
                        function(){
                                $x = 123;
                        }
                );
        }
), 10000);
?>

Ergebnisse:

$ php test8.php
test1_anonfunc_call took 0.0081379413604736s (1228812.0001172/s)
test2_anonfunc_call_user_func took 0.011472940444946s (871616.13432805/s)
Shovas
quelle
0

Ich habe es auf diese Weise ausprobiert, aber es ist ausführlicher als die oberste Antwort, wenn Sie einen Operator (oder eine Funktion) verwenden, mit dem Sie die Funktion zuerst definieren können:

    $value = $hack == ($hack = function(){
            // just a hack way of executing an anonymous function
            return array(0, 1, 2, 3);                
    }) ? $hack() : $hack();
Paul Jerome Bordallo
quelle
2
Warum dann nicht einfach $hack = function(){...}; $hack()?
0

Dies ist keine direkte Antwort, sondern eine Problemumgehung. Verwenden von PHP> = 7. Definieren einer anonymen Klasse mit einer benannten Methode, Erstellen der Klasse und sofortiges Aufrufen der Methode.

$var = (new class() { // Anonymous class
    function cool() { // Named method
        return 'neato';
    }
})->cool(); // Instantiate the anonymous class and call the named method
echo $var; // Echos neato to console.
thecoolestname36
quelle
-2

Nicht sofort ausgeführt, aber in der Nähe von;)

<?php

$var = (function(){ echo 'do something'; });
$var();

?>
James
quelle