Hal ini sering terjadi kepada saya untuk menangani data-data yang dapat berupa sebuah array atau null variabel dan untuk memberi makan beberapa foreach
dengan data ini.
$values = get_values();
foreach ($values as $value){
...
}
Ketika anda makan foreach dengan data yang tidak array, anda mendapatkan peringatan:
Warning: Invalid argument supplied for foreach() in [...]
Asumsi itu's tidak mungkin untuk refactor get_values()
fungsi untuk selalu mengembalikan array (backward compatibility, tidak tersedia source code, apapun alasan lain), saya'm bertanya-tanya mana yang paling bersih dan paling efisien cara untuk menghindari peringatan ini:
$nilai
untuk array$nilai
untuk arrayforeach
dengan jika
Secara pribadi saya menemukan ini untuk menjadi yang paling bersih - tidak yakin apakah itu's paling efisien, pikiran!
if (is_array($values) || is_object($values))
{
foreach ($values as $value)
{
...
}
}
Alasan untuk preferensi saya adalah itu doesn't mengalokasikan array kosong ketika anda've punya apa-apa untuk mulai dengan pula.
Saya biasanya menggunakan construct yang mirip dengan ini:
/**
* Determine if a variable is iterable. i.e. can be used to loop over.
*
* @return bool
*/
function is_iterable($var)
{
return $var !== null
&& (is_array($var)
|| $var instanceof Traversable
|| $var instanceof Iterator
|| $var instanceof IteratorAggregate
);
}
$values = get_values();
if (is_iterable($values))
{
foreach ($values as $value)
{
// do stuff...
}
}
Perhatikan bahwa versi ini adalah tidak diuji, yang diketik langsung ke JADI dari memori.
Edit: ditambahkan Traversable periksa
Mohon tidak tergantung pada casting sebagai solusi, meskipun orang lain yang menyarankan ini sebagai pilihan yang valid untuk mencegah kesalahan, itu mungkin penyebab yang lain.
Perlu diketahui: Jika anda mengharapkan sebuah bentuk khusus dari array yang akan dikembalikan, ini mungkin gagal anda. Lebih lanjut pemeriksaan yang diperlukan untuk itu.
E. g. casting boolean ke sebuah array
(array)bool
, akan TIDAK hasilnya dalam array kosong, tetapi sebuah array dengan salah satu unsur yang mengandung nilai boolean sebagai int:[0=>0]
atau[0=>1]
.
Saya tulis tes cepat untuk menyajikan masalah ini. (Di sini adalah backup Tes dalam kasus pertama tes url gagal.)
Termasuk tes untuk: null
, false
, true
, kelas
, sebuah array
dan undefined
.
Selalu menguji masukan anda sebelum menggunakannya dalam foreach. Saran:
$array = is_array($var) atau is_object($var) ? $var : [] ;
try{}catch(){}
blokarray_key_exists
pada tombol tertentu, atau menguji kedalaman array (ketika itu adalah salah satu !)]6.Coba ini:
//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
echo $val;
}
;)
Lebih ringkas perpanjangan @Kris's kode
function secure_iterable($var)
{
return is_iterable($var) ? $var : array();
}
foreach (secure_iterable($values) as $value)
{
//do stuff...
}
terutama untuk penggunaan di dalam kode template
<?php foreach (secure_iterable($values) as $value): ?>
...
<?php endforeach; ?>
Saya tidak yakin jika ini adalah kasus, tetapi masalah ini tampaknya terjadi beberapa kali ketika melakukan migrasi situs wordpress atau migrasi situs dinamis pada umumnya. Jika hal ini terjadi, pastikan hosting anda bermigrasi untuk menggunakan PHP versi lama anda menggunakan situs.
Jika anda tidak melakukan migrasi situs anda dan ini hanya masalah yang telah datang mencoba update ke PHP 5. Ini mengurus beberapa masalah ini. Mungkin tampak konyol solusi tapi melakukan trik untuk saya.
Warning invalid argument supplied for foreach()
menampilkan tweet.
pergi ke /wp-content/plugins/tampilan-tweet-php
.
Kemudian masukkan kode ini di baris nomor 591, Itu akan berjalan dengan sempurna.
if (is_array($tweets)) {
foreach ($tweets as $tweet)
{
...
}
}
Ada tampaknya juga menjadi kaitannya dengan lingkungan:
Saya punya "invalid argument supplied foreach()" kesalahan hanya di dev lingkungan, tetapi tidak prod (saya bekerja di server, bukan localhost).
Meskipun kesalahan yang var_dump menunjukkan bahwa array juga ada (dalam kedua kasus aplikasi dan dev).
The if (is_array($array))
sekitar foreach ($array as $subarray)
memecahkan masalah.
Maaf, yang saya tidak bisa menjelaskan penyebabnya, tapi karena butuh waktu untuk mencari solusi, saya pikir lebih baik berbagi ini sebagai pengamatan.
I'll menggunakan kombinasi kosong
, isset
dan is_array
sebagai
$array = ['dog', 'cat', 'lion'];
if (!empty($array) && isset($array) && is_array($array) {
//loop
foreach ($array as $values) {
echo $values;
}
}
saya akan melakukan hal yang sama seperti Andy tapi aku'ld gunakan 'kosong' fungsi.
seperti:
if(empty($yourArray))
{echo"<p>There's nothing in the array.....</p>";}
else
{
foreach ($yourArray as $current_array_item)
{
//do something with the current array item here
}
}