Saya ingin menggunakan foreach
loop dengan variabel, tetapi variabel ini dapat memiliki banyak jenis, NULL
misalnya.
Jadi sebelum foreach
saya mengujinya:
if(is_array($var)){
foreach($var as ...
Tetapi saya menyadari bahwa itu juga bisa menjadi kelas yang mengimplementasikan Iterator
antarmuka. Mungkin saya buta tapi bagaimana cara memeriksa apakah kelas mengimplementasikan antarmuka? Apakah ada sesuatu seperti is_a
fungsi atau inherits
operator? Saya menemukan class_implements
, saya dapat menggunakannya, tetapi mungkin ada sesuatu yang lebih sederhana?
Dan kedua, yang lebih penting, saya kira fungsi ini ada, akan cukup untuk memeriksa apakah variabel is_array
atau "mengimplementasikan Iterator
antarmuka" atau haruskah saya menguji sesuatu yang lebih?
Jawaban:
Jika Anda menggunakan
foreach
inside sebuah fungsi dan Anda mengharapkan sebuah array atau objek Traversable, Anda dapat mengetik petunjuk yang berfungsi dengan:function myFunction(array $a) function myFunction(Traversable)
Jika Anda tidak menggunakan
foreach
inside sebuah fungsi atau mengharapkan keduanya, Anda dapat menggunakan konstruksi ini untuk memeriksa apakah Anda dapat melakukan iterasi pada variabel:if (is_array($a) or ($a instanceof Traversable))
sumber
is_array
mahal. Biaya komputasi sepertinya meningkat dengan ukuran array (yang tidak masuk akal karena hanya memeriksa apakah itu array). Tapi itu terjadi pada saya secara mengejutkan di perpustakaan. Lihat komentar saya di pertanyaan terkait. Akaninstanceof Traversable
bekerja dengan array? Saya tidak sempat menguji performanya.Traversable
jadi ya.$var = array(1,2,3);
hasil sebagai berikut:is_array($var) = true
dan$var instanceof Traversable = false
.Iterator
dan karenanya tidak berfungsiTraversable
.foreach
dapat menangani array dan objek. Anda dapat memeriksanya dengan:$can_foreach = is_array($var) || is_object($var); if ($can_foreach) { foreach ($var as ... }
Anda tidak perlu memeriksanya secara khusus karena
Traversable
orang lain telah mengisyaratkan dalam jawaban mereka, karena semua objek - seperti semua array - dapat dilintasi dalam PHP.Lebih teknis:
( sumber )
Secara sederhana dikatakan dalam pemrograman PHP umum, setiap kali ada variabel
dan tidak
Anda dapat menggunakannya
foreach
.sumber
Anda dapat memeriksa instance
Traversable
dengan fungsi sederhana. Ini akan berhasil untuk semua iniIterator
karenaIterator extends Traversable
function canLoop($mixed) { return is_array($mixed) || $mixed instanceof Traversable ? true : false; }
sumber
<?php $var = new ArrayIterator(); var_dump(is_array($var), ($var instanceof ArrayIterator));
kembali
bool(false)
ataubool(true)
sumber
Fungsi
<?php /** * Is Array? * @param mixed $x * @return bool */ function isArray($x) : bool { return !isAssociative($x); } /** * Is Associative Array? * @param mixed $x * @return bool */ function isAssociative($x) : bool { if (!is_array($array)) { return false; } $i = count($array); while ($i > 0) { if (!isset($array[--$i])) { return true; } } return false; }
Contoh
<?php $arr = [ 'foo', 'bar' ]; $obj = [ 'foo' => 'bar' ]; var_dump(isAssociative($arr)); # bool(false) var_dump(isAssociative($obj)); # bool(true) var_dump(isArray($obj)); # bool(false) var_dump(isArray($arr)); # bool(true)
sumber
Sejak PHP 7.1 ada tipe pseudo
iterable
untuk tujuan ini. Mengisyaratkan tipeiterable
menerima larik apa pun serta implementasiTraversable
antarmuka apa pun. PHP 7.1 juga memperkenalkan fungsi tersebutis_iterable()
. Untuk versi yang lebih lama, lihat jawaban lain di sini untuk menyelesaikan penerapan jenis yang setara tanpa fitur bawaan yang lebih baru.Permainan yang adil: Seperti yang ditunjukkan BlackHole, pertanyaan ini tampaknya merupakan duplikat dari objek Iterable dan petunjuk tipe array? dan jawabannya lebih detail dari saya.
sumber