php is_function () untuk menentukan apakah suatu variabel adalah fungsi

89

Saya sangat senang membaca tentang fungsi anonim di php, yang memungkinkan Anda mendeklarasikan variabel yang berfungsi lebih mudah daripada yang dapat Anda lakukan dengan create_function . Sekarang saya bertanya-tanya apakah saya memiliki fungsi yang dilewatkan variabel, bagaimana cara memeriksanya untuk menentukan apakah itu sebuah fungsi? Belum ada fungsi is_function (), dan ketika saya melakukan var_dump dari variabel yang merupakan fungsi ::

$func = function(){
    echo 'asdf';
};
var_dump($func);

Saya mengerti ini:

object(Closure)#8 (0) { } 

Ada pemikiran tentang cara memeriksa apakah ini suatu fungsi?

Jage
sumber

Jawaban:

142

Gunakan is_callableuntuk menentukan apakah variabel yang diberikan adalah fungsi. Sebagai contoh:

$func = function()
{  
    echo 'asdf';  
};

if( is_callable( $func ) )
{
    // Will be true.
}
Jon Benedicto
sumber
10
is_callable () akan bekerja dengan baik baik Anda meneruskan fungsi anonim, nama fungsi sebagai string, atau array callback PHP yang valid. Jika Anda secara khusus ingin memeriksa fungsi anonim saja, Anda pasti menginginkan sesuatu seperti yang dikatakan Gumbo: pastikan parameternya adalah objek, dan pastikan itu adalah turunan dari Closure.
Jalur
2
Bagaimana jika saya ingin memeriksa apakah itu callack atau string dan melakukan hal yang berbeda untuk mereka. Saya tidak ingin nilai string diambil secara tidak sengaja sebagai callback.
Gherman
3
@ Jerman Cukup periksa dulu jika is_string ($ func) lalu sebagai periksa kedua dengan is_callable ($ func)
Heroselohim
4
Potongan kode di atas membuat saya kesulitan. Saya bermaksud string berlabel "Tanggal" dan kemudian ditangani sebagai penutupan dan dieksekusi. Cara yang benar adalah if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Basil Musa
1
Mengapa contoh penutupan AND dapat dipanggil. Kapan closure tidak bisa dipanggil? Tidak heran jika ada waktu, tapi saya penasaran kenapa kita perlu cek keduanya.
Joel M
34

Anda dapat menggunakan function_existsuntuk memeriksa apakah ada fungsi dengan nama yang diberikan. Dan untuk menggabungkannya dengan fungsi anonim, coba ini:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}
Gumbo
sumber
Terima kasih untuk ini! Aplikasi saya memungkinkan pengguna untuk menentukan fungsi hashing mereka sendiri, atau sebagai gantinya memberikan argumen untuk hash (). Tetapi beberapa algoritma hashing yang valid juga merupakan bawaan PHP, dan oleh karena itu dapat dipanggil ('md5', 'sha1' misalnya). is_object()dan instanceof Closuremerupakan cara yang jauh lebih kuat untuk memeriksa hal ini!
njbair
Hapus panggilan is_string dan function_exists dan ini adalah fungsi yang ingin Anda gunakan untuk mendeteksi fungsi lambda. Terima kasih!
jack
30

Jika Anda hanya ingin memeriksa apakah variabel adalah fungsi anonim, dan bukan string atau larik yang dapat dipanggil, gunakan instanceof.

$func = function()
{  
    echo 'asdf';  
};

if($func instanceof Closure)
{
    // Will be true.
}

Fungsi anonim (dari jenis yang ditambahkan di PHP 5.3) selalu merupakan instance Closurekelas, dan setiap instance Closurekelas adalah fungsi anonim.

Ada jenis hal lain di PHP yang bisa dianggap sebagai fungsi, dan itu adalah objek yang menerapkan __invokemetode ajaib. Jika Anda ingin memasukkannya (sambil tetap mengecualikan string dan array), gunakan method_exists($func, '__invoke'). Ini masih akan mencakup closure, karena closure diimplementasikan __invokeuntuk konsistensi.

Brilliand
sumber
8
Ini sangat membantu, karena is_callable()akan mencoba menemukan metode untuk memanggil berdasarkan string atau larik yang diteruskan, yang mungkin memuat kelas secara otomatis dan mungkin bukan perilaku yang Anda harapkan / butuhkan.
spikyjt
2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}
Artemiy StagnantIce Alexeew
sumber
Di masa depan, PHP mungkin mengubah gettype () dari Object menjadi Callable, seperti yang sudah dilakukan bahasa lain. Jadi, jawaban ini mungkin cara terbaik untuk pergi. Tetapi ini dapat dioptimalkan sebagai: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Alexandre T.
0

Dalam php callable yang valid dapat berupa fungsi, nama fungsi (string) dan array bentuk ['className', 'staticMethod']atau [$object, 'method'], jadi untuk mendeteksi hanya fungsi yang perlu mengecualikan string dan array:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}
Andrey Izman
sumber