PHP'de anonim bir işlevi nasıl hemen çalıştırırım?


96

JavaScript'te, hemen çalıştırılan anonim işlevleri tanımlayabilirsiniz:

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

PHP'de böyle bir şey yapabilir misin?


2
Elimde denemek için php 5.3 yok, ama nasıl call_user_func(function(){/* stuff */})oluyor?
Jasper

Yanıtlar:


121

PHP7 için: Yasuo Ohgaki'nin cevabına bakın :(function() {echo 'Hi';})();

Önceki sürümler için: Aklıma gelen bunları hemen çalıştırmanın tek yolu

call_user_func(function() { echo 'executed'; });

12
İşlev çağrısı zincirleme tanıtılmadıkça (veya, kadar) , bu da benim önerim olacaktır.
salathe

2
@Gordon: php 5.4 hala bir şey yok mu?
dinamik

@ yes123 hayır. hala kullanmak zorundacall_user_func
Gordon

2
@BennettMcElwee bunu şu şekilde ifade edelim: Bu, tanımla-ata-çağrısı alternatifinden biraz daha yavaş çalışsa bile, bunun uygulamanızda önemli bir darboğaz oluşturma olasılığı çok düşüktür. şüpheye düştüğünüzde, uygulamanızın profilini gerçek dünya koşullarında uygulayın.
Gordon

Teşekkürler @Gordon, ben de öyle düşündüm. Salathe ve yes123'ün bu yöntemden memnun olmadığı izlenimini edindim ve nedenini merak ettim. Bana gayet iyi görünüyor.
Bennett McElwee

28

In PHP 7yapmak javascript aynıdır

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

    return 3;
})();

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

echo $gen->getReturn(), PHP_EOL;

Çıktı:

1
2
3

15

Tabii ki kullanabilirsiniz call_user_func, ancak yine de oldukça basit bir alternatif var:

<?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";
});

?>

1
Hemen çalışan bir işlev istiyorum, çünkü tanımladığım işlev, normal yürütmede birden fazla çağrılmaması GEREKEN bir işlevdir. Sizin gibi, run () adlı adlandırılmış bir işlevin tanımlanmasındaki sorun, kodu gören herhangi birinin kodun başka bir bölümünde de run () 'u çağırabileceğini düşünebilmesidir. Hemen çalıştırılan işlev, bu kodun iki kez çalıştırılmaması gerektiğini açıkça belirtir.
Daniel Howard

3
runİşlevinizi kodun başka bir bölümünde çağıramazlar çünkü işlevinizin hemen onu çalıştıran satırdan sonra var olan hiçbir tanıtıcısı yoktur.
Pacerier

3
@DanielHoward Buradaki amaç run(), kendisine aktarılan isimsiz işlevi hemen yürütmektir. Aynı şekilde call_user_func(), yalnızca hiçbir parametre aktarılmaz.
Cypher

1
@JordanLev, Daha basit bir uygulaması vardır (sadece bir satır :) $f();ve kullandığınız motor call_user_func, yalnızca bir fonksiyon argümanına sahip özel durum için optimize etmezse daha hızlı olabilir . Bunun nedeni call_user_func, birden çok parametrenin iletilmesini desteklemesidir ve ilk bağımsız değişkeni, bağımsız değişken olarak bir dizeyi veya bir işlevi desteklemektedir. Bununla birlikte call_user_func, çok okunaklıysa, runkod piramidin altında bir yerde bulunmadıkça kullanmam .
Pacerier

1
@JordanLev, "daha basit uygulama" , işlevler içindeki kodun runve call_user_func. call_user_funcile karşılaştırıldığında doğal bir dezavantajı vardır runçünkü runtek bir şey yapar, oysa call_user_funcne yaptığını yapmanın yanı sıra ek özellikleri destekler run. Motorunuzda hangisinin daha hızlı olduğunu görmek için hızlı bir döngü testi ( örneğin ) deneyebilirsiniz .
Pacerier

11

Bu, PHP 7.0 veya sonrası için en basit olanıdır.

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

Kapanış yaratmak anlamına gelir, ardından "()" izleyerek onu işlev olarak çağırır. Tek tip değişken değerlendirme sıralaması sayesinde JS gibi çalışır.

https://3v4l.org/06EL3


2
Güzel cevap, ama neden bunu bir komut satırı işlemi olarak biçimlendiriyorsunuz?
Kodos Johnson

6
(new ReflectionFunction(function() {
 // body function
}))->invoke();

6
daha fazla ayrıntı verebilir misin? belki bir açıklama ekler misiniz?
MoralCode

2

Unutmayın, kabul edilen cevap iyidir, ancak bir işlevi bildirip iki satırda çağırmaktan 1,41 kat daha uzun (% 41 daha yavaş) sürer.

[Bunun gerçekten yeni bir cevap olmadığını biliyorum, ancak bunu ziyaretçiler için bir yere eklemenin değerli olduğunu hissettim.]

Detaylar:

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

Sonuçlar:

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

0

Bunu bu şekilde denedim, ancak önce işlevi tanımlamanıza izin veren herhangi bir operatör (veya işlevi) kullanarak en üstteki cevaptan daha ayrıntılı:

    $value = $hack == ($hack = function(){
            // just a hack way of executing an anonymous function
            return array(0, 1, 2, 3);                
    }) ? $hack() : $hack();

2
Öyleyse neden basitçe değil $hack = function(){...}; $hack()?

0

Bu doğrudan bir cevap değil, geçici bir çözüm. PHP> = 7. Adsız bir sınıfın adlandırılmış bir yöntemle tanımlanması ve sınıfın oluşturulması ve yöntemi hemen çağırılması.

$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.

-2

Hemen idam edilmedi, ancak yakın;)

<?php

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

?>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.