Bagaimana cara langsung menjalankan fungsi anonim di PHP?

96

Di JavaScript, Anda dapat menentukan fungsi anonim yang dijalankan segera:

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

Bisakah Anda melakukan hal seperti itu di PHP?

Emanuil Rusev
sumber
2
Saya tidak memiliki php 5.3 untuk dicoba, tapi bagaimana call_user_func(function(){/* stuff */})caranya?
Jasper

Jawaban:

121

Untuk PHP7: lihat jawaban Yasuo Ohgaki :(function() {echo 'Hi';})();

Untuk versi sebelumnya: satu-satunya cara untuk menjalankannya dengan segera yang dapat saya pikirkan adalah

call_user_func(function() { echo 'executed'; });
Gordon
sumber
12
Kecuali (atau, sampai) rangkaian pemanggilan fungsi diperkenalkan, ini akan menjadi saran saya juga.
salathe
2
@ Gordon: php 5.4 masih belum ada?
dinamis
@ yes123 tidak. masih harus menggunakancall_user_func
Gordon
2
@BennettMcElwee mari kita begini: meskipun ini bekerja agak lebih lambat daripada alternatif define-assign-call, kemungkinan hal ini menimbulkan hambatan yang signifikan dalam aplikasi Anda sangat rendah. jika ragu, buat profil aplikasi Anda dalam kondisi dunia nyata.
Gordon
Terima kasih @Gordon, itulah yang saya pikirkan. Saya mendapat kesan bahwa salathe dan yes123 tidak senang dengan metode ini, dan saya bertanya-tanya mengapa. Sepertinya baik-baik saja bagiku.
Bennett McElwee
28

In PHP 7adalah melakukan hal yang sama di javascript

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

    return 3;
})();

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

echo $gen->getReturn(), PHP_EOL;

Outputnya adalah:

1
2
3
Wallace Maxters
sumber
15

Tentu saja Anda dapat menggunakan call_user_func, tetapi masih ada alternatif lain yang cukup sederhana:

<?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
sumber
1
Saya ingin fungsi yang segera dijalankan, karena fungsi yang saya definisikan adalah fungsi yang TIDAK HARUS dipanggil lebih dari sekali dalam eksekusi normal. Masalah dengan mendefinisikan fungsi bernama, run (), seperti yang Anda miliki, adalah siapa pun yang melihat kode tersebut mungkin berpikir bahwa mereka juga dapat memanggil run () di beberapa bagian lain dari kode. Fungsi yang segera dijalankan memperjelas bahwa kode ini tidak boleh dijalankan dua kali.
Daniel Howard
3
Mereka tidak dapat memanggil runfungsi Anda di beberapa bagian lain dari kode karena tidak ada pegangan ke fungsi Anda yang ada setelah baris yang segera mengeksekusinya.
Pacerier
3
@DanielHoward Intinya run()adalah untuk segera menjalankan fungsi tanpa nama yang diteruskan ke sana. Sama seperti call_user_func(), hanya tidak ada parameter yang dilewatkan.
Cypher
1
@JordanLev, Ini memiliki implementasi yang lebih sederhana (hanya satu baris :) $f();dan mungkin lebih cepat jika mesin yang Anda gunakan tidak mengoptimalkan untuk kasus khusus di mana call_user_funchanya memiliki satu argumen fungsi. Ini karena call_user_funcmendukung penerusan beberapa parameter dan argumen pertamanya mendukung string sebagai argumen atau fungsi. Yang mengatakan, jika call_user_funclebih mudah dibaca, saya tidak akan menggunakan runkecuali kode tersebut terletak di suatu tempat di bagian bawah piramida .
Pacerier
1
@JordanLev, "implementasi yang lebih sederhana" mengacu pada perbandingan antara kode di dalam fungsi rundan call_user_func. call_user_funcmemiliki kelemahan inheren jika dibandingkan runkarena runhanya melakukan satu hal, sedangkan call_user_funcmendukung fitur tambahan selain melakukan apa yang rundilakukannya. Anda dapat mencoba tes putaran cepat ( mis. ) Untuk melihat mana yang lebih cepat pada mesin Anda.
Pacerier
11

Ini yang paling sederhana untuk PHP 7.0 atau yang lebih baru.

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

Artinya buat closure, lalu panggil fungsi dengan mengikuti "()". Bekerja seperti JS berkat urutan evaluasi variabel yang seragam.

https://3v4l.org/06EL3

Yasuo Ohgaki
sumber
2
Jawaban bagus, tetapi mengapa Anda memformatnya sebagai operasi baris perintah?
Kodos Johnson
6
(new ReflectionFunction(function() {
 // body function
}))->invoke();
dalam
sumber
6
dapatkah Anda memberikan lebih banyak detail? mungkin menambahkan penjelasan?
MoralCode
2

Catatan, jawaban diterima baik-baik saja tetapi dibutuhkan 1,41x lebih lama (41% lebih lambat) daripada mendeklarasikan fungsi dan memanggilnya dalam dua baris.

[Saya tahu ini bukanlah jawaban yang benar-benar baru, tetapi saya merasa sangat berharga menambahkan ini di suatu tempat untuk pengunjung.]

Rincian:

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

Hasil:

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

Saya mencobanya dengan cara ini, tetapi ini lebih bertele-tele daripada jawaban teratas dengan menggunakan operator (atau fungsi) apa pun yang memungkinkan Anda untuk menentukan fungsi terlebih dahulu:

    $value = $hack == ($hack = function(){
            // just a hack way of executing an anonymous function
            return array(0, 1, 2, 3);                
    }) ? $hack() : $hack();
Paul Jerome Bordallo
sumber
2
Lalu mengapa tidak begitu saja $hack = function(){...}; $hack()?
0

Ini bukan jawaban langsung, tapi solusi. Menggunakan PHP> = 7. Mendefinisikan kelas anonim dengan metode bernama dan membangun kelas dan memanggil metode itu segera.

$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.
nama keren36
sumber
-2

Tidak dieksekusi dengan segera, tetapi mendekati;)

<?php

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

?>
James
sumber