Invalid argument supplied for foreach()

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:

  • Casting $nilai untuk array
  • Inisialisasi $nilai untuk array
  • Membungkus foreach dengan jika
  • Lain-lain (silakan menyarankan)
Mengomentari pertanyaan (1)
Larutan

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.

Komentar (8)

Bagaimana dengan yang satu ini? banyak debu dan semua dalam satu baris.

foreach ((array) $items as $item) {
 // ...
 }
Komentar (6)

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

Komentar (10)

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:

  1. Tipe cepat memeriksa: $array = is_array($var) atau is_object($var) ? $var : [] ;
  2. Type mengisyaratkan array dalam metode sebelum menggunakan foreach dan menetapkan kembali jenis
  3. Pembungkus foreach hanya jika
  4. Menggunakan try{}catch(){} blok
  5. Merancang kode yang tepat / pengujian sebelum rilis produksi
  6. Untuk menguji array terhadap bentuk yang tepat anda bisa menggunakan array_key_exists pada tombol tertentu, atau menguji kedalaman array (ketika itu adalah salah satu !)]6.
  7. Selalu ekstrak metode pembantu ke global namespace cara untuk mengurangi duplikasi kode
Komentar (0)

Coba ini:

//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
  echo $val;
}

;)

Komentar (1)
$values = get_values();

foreach ((array) $values as $value){
  ...
}

Masalahnya adalah selalu nol dan Casting ini sebenarnya larutan pembersih.

Komentar (0)

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; ?>
Komentar (1)

Pertama-tama, setiap variabel harus diinisialisasi. Selalu. Pengecoran adalah bukan pilihan. jika get_values(); dapat kembali berbagai jenis variabel, nilai ini harus diperiksa, tentu saja.

Komentar (2)

Jika anda're menggunakan php7 dan anda ingin menangani hanya terdefinisi kesalahan ini adalah yang terbersih IMHO

$array = [1,2,3,4];
foreach ( $array ?? [] as $item ) {
  echo $item;
}
Komentar (0)
foreach ($arr ? $arr : [] as $elem) {
    // Does something 
}

Ini doesen't memeriksa apakah itu adalah sebuah array, tapi melompat lingkaran jika variabel adalah null atau array kosong.

Komentar (0)

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.

Komentar (0)

Bagaimana solusi ini:

$type = gettype($your_iteratable);
$types = array(
    'array',
    'object'
);

if (in_array($type, $types)) {
    // foreach code comes here
}
Komentar (0)

Kasus yang luar biasa untuk pemberitahuan ini terjadi jika anda mengatur array null di dalam foreach loop

if (is_array($values))
{
    foreach ($values as $value)
    {
        $values = null;//WARNING!!!
    }
}
Komentar (0)

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) 
    {
        ...
    }
}
Komentar (1)

Bagaimana mendefinisikan array kosong sebagai cadangan jika get_value() kosong? Saya dapat't pikir dari yang terpendek.

$values = get_values() ?: [];

foreach ($values as $value){
  ...
}
Komentar (0)

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.

Komentar (0)

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; 
    }
}
Komentar (0)

Gunakan is_array fungsi, ketika anda akan melewati array dengan foreach loop.

if (is_array($your_variable)) {
  foreach ($your_variable as $item) {
   //your code
}
}
Komentar (0)

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
  } 
}
Komentar (2)