Ошибка warning invalid argument supplied for foreach in wordpress

Разрабатывая свой код на PHP, программист может столкнуться с сообщением об ошибке «Invalid argument supplied for foreach in…». После данного сообщения обычно следует указание на её конкретику, к примеру, «/modules/tasks/todo_tasks_sub.php on line 121». Ошибка обычно обусловлена спецификой имеющегося отрезка кода, и требует проверки особенностей использования в нём переменных. Давайте разберём факторы появления ошибки, и как её можно исправить.

Ошибка Invalid argument

Содержание

  1. Причины появления Invalid argument supplied for foreach
  2. Как исправить ошибку «Invalid argument supplied for foreach in»
  3. Ошибка в WordPress
  4. Заключение

Причины появления Invalid argument supplied for foreach

Рассматриваемая ошибка обычно возникает в ситуации, когда переменная, которую foreach пытается выполнить (повторить) не является массивом. К примеру, вы передаёте в цикл не массив, а скаляр, или вы задействуйте двойной массив, и забыли определить, как выбирается индекс.

Давайте допустим, что мы имеем функцию с именем get_user_posts. Эта функция должна возвращать массив комментариев пользователя. Однако если комментариев нет, функция возвращает логическое значение FALSE.

Код PHP

В приведенном выше отрезке кода мы предположили, что переменная $ posts всегда будет массивом. Однако, если функция get_user_posts возвращает логическое значение FALSE, то цикл foreach не будет работать, и PHP выведет следующее сообщение об ошибке:

Warning: Invalid argument supplied for foreach() on line 7

Как же решить указанную проблему? Давайте разбираться.

Как исправить ошибку «Invalid argument supplied for foreach in»

Решение зависит от того, для чего предназначен ваш код. То есть, если функция get_user_posts всегда должна возвращать массив, то, очевидно, вам необходимо выяснить, почему она возвращает логическое значение FALSE или значение NULL. Причиной этому может быть несколько вещей:

  • Не удалось объявить пустой массив «по умолчанию» (default);
  • Сбой запроса к базе данных;
  • Массив перезаписывается или сбрасывается. Это часто происходит в скриптах с большим количеством массивов, когда имеются ограничения памяти, а разработчик вынужден сбрасывать массивы, с которыми он или она закончили работу.

Просматривая чей-либо код, мы можем столкнуться с API и функциями, которые возвращают значение FALSE, когда результаты отсутствуют. Если это так, то вы можете добавить следующую проверку в ваш код:

Пример кода PHP

Выше мы используем функцию is_array, чтобы проверить, является ли $posts массивом. И это мы делаем ДО того, как пытаемся зациклить его с помощью конструкции foreach. Как мы уже писали, все зависит от того, каково предназначение вашего скрипта. Добавление проверки is_array неразумно в ситуации, когда есть вопросы о том будет ли переменная массивом. Ведь вы будете скрывать ошибку, которой не должно существовать.

Ошибка в WordPress

Также рассматриваемая ошибка может появляться при работе сайтов на WordPress. Проблема вызвана тем, что WP_Block_Parser выполняет несколько строковых манипуляций с substr () и strlen (), предполагая, что они работают с одиночными байтами, а не с многобайтовыми последовательностями.

Решить ошибку Invalid argument supplied for foreach в WordPress помогает изменение значения настройки mbstring.func_overload на 0 (обычно стоит 2). Сохраните произведённые изменения, и попытайтесь перейти на проблемную ранее страницу.

Если это не помогло, попробуйте скачать Вордпресс 4.9.5, вытянуть из него папку wp-includes, и скопировать в аналогичную папку на вашем хостинге. После этого WordPress может предложить обновить ваши базы данных, соглашайтесь, и всё заработает после очистки кэша.

Заключение

Ошибка «Invalid argument supplied for foreach in…» в коде PHP обычно вызвана переменной, не являющейся массивом. Последнюю пытается выполнить foreach, но безуспешно. Для решения возникшей проблемы можно добавить функцию is_array (она проверит, является ли переменная массивом). Также может порекомендовать общий ознакомительный материал на сайте phpfaq.ru, где детально разобрано, как найти ошибку в созданном вами коде.

It often happens to me to handle data that can be either an array or a null variable and to feed some foreach with these data.

$values = get_values();

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

When you feed a foreach with data that are not an array, you get a warning:

Warning: Invalid argument supplied for foreach() in […]

Assuming it’s not possible to refactor the get_values() function to always return an array (backward compatibility, not available source code, whatever other reason), I’m wondering which is the cleanest and most efficient way to avoid these warnings:

  • Casting $values to array
  • Initializing $values to array
  • Wrapping the foreach with an if
  • Other (please suggest)

Geoffrey Hale's user avatar

asked Apr 13, 2010 at 13:48

Roberto Aloi's user avatar

Roberto AloiRoberto Aloi

30.5k21 gold badges74 silver badges112 bronze badges

1

Personally I find this to be the most clean — not sure if it’s the most efficient, mind!

if (is_array($values) || is_object($values))
{
    foreach ($values as $value)
    {
        ...
    }
}

The reason for my preference is it doesn’t allocate an empty array when you’ve got nothing to begin with anyway.

vlasits's user avatar

vlasits

2,2151 gold badge15 silver badges27 bronze badges

answered Apr 13, 2010 at 13:51

Andy Shellam's user avatar

Andy ShellamAndy Shellam

15.4k1 gold badge27 silver badges41 bronze badges

10

How about this one? lot cleaner and all in single line.

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

answered Apr 8, 2015 at 17:08

Ajith R Nair's user avatar

Ajith R NairAjith R Nair

2,1721 gold badge14 silver badges10 bronze badges

5

I usually use a construct similar to this:

/**
 * 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...
    }
}

Note that this particular version is not tested, its typed directly into SO from memory.

Edit: added Traversable check

answered Mar 27, 2013 at 9:30

Kris's user avatar

8

Please do not depend on casting as a solution,
even though others are suggesting this as a valid option to prevent an error, it might cause another one.

Be aware: If you expect a specific form of array to be returned, this might fail you. More checks are required for that.

E.g. casting a boolean to an array (array)bool, will NOT result in an empty array, but an array with one element containing the boolean value as an int: [0=>0] or [0=>1].

I wrote a quick test to present this problem.
(Here is a backup Test in case the first test url fails.)

Included are tests for: null, false, true, a class, an array and undefined.


Always test your input before using it in foreach. Suggestions:

  1. Quick type checking: $array = is_array($var) or is_object($var) ? $var : [] ;
  2. Type hinting arrays in methods before using a foreach and specifying return types
  3. Wrapping foreach within if
  4. Using try{}catch(){} blocks
  5. Designing proper code / testing before production releases
  6. To test an array against proper form you could use array_key_exists on a specific key, or test the depth of an array (when it is one !).
  7. Always extract your helper methods into the global namespace in a way to reduce duplicate code

Community's user avatar

answered Sep 26, 2015 at 17:54

AARTT's user avatar

AARTTAARTT

5035 silver badges8 bronze badges

Try this:

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

;)

answered Jun 12, 2014 at 23:06

Gigoland's user avatar

GigolandGigoland

1,22912 silver badges10 bronze badges

1

All answers provided above are essentially just error suppression.

Your PHP is telling you that you are trying to use a variable of incorrect type, and there is possibly an error. but all answers provided are just brushing this message off.

Your best bet is to initialize every variable before use. And to make return types strict and explicit. You must ask yourself, WHY get_values() is returning anything than array? Why it cannot be made to return just an empty array, if no data found? Surely it can be.

answered Apr 13, 2010 at 14:11

Your Common Sense's user avatar

Your Common SenseYour Common Sense

157k40 gold badges213 silver badges339 bronze badges

3

$values = get_values();

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

Problem is always null and Casting is in fact the cleaning solution.

answered Mar 2, 2016 at 14:25

boctulus's user avatar

boctulusboctulus

3958 silver badges15 bronze badges

0

foreach ($arr ?: [] as $elem) {
    // Do something
}

This doesen’t check if it is an array, but skips the loop if the variable is null or an empty array.

Update from PHP 7.0 you should use the null coalescing operator:

foreach ($arr ?? [] as $elem) {
    // Do something
}

This would solve the warning mentioned in the comment (here a handy table that compares ?: and ?? outputs).

answered Dec 18, 2015 at 9:31

T30's user avatar

T30T30

11.2k7 gold badges53 silver badges57 bronze badges

1

If you’re using php7 and you want to handle only undefined errors this is the cleanest IMHO

$array = [1,2,3,4];
foreach ( $array ?? [] as $item ) {
  echo $item;
}

answered Aug 9, 2016 at 15:27

Edwin Rodríguez's user avatar

0

More concise extension of @Kris’s code

function secure_iterable($var)
{
    return is_iterable($var) ? $var : array();
}

foreach (secure_iterable($values) as $value)
{
     //do stuff...
}

especially for using inside template code

<?php foreach (secure_iterable($values) as $value): ?>
    ...
<?php endforeach; ?>

Community's user avatar

answered Apr 23, 2015 at 12:38

HongKilDong's user avatar

HongKilDongHongKilDong

1,2763 gold badges16 silver badges23 bronze badges

1

Warning invalid argument supplied for foreach() display tweets.
go to /wp-content/plugins/display-tweets-php.
Then insert this code on line number 591, It will run perfectly.

if (is_array($tweets)) {
    foreach ($tweets as $tweet) 
    {
        ...
    }
}

Nik's user avatar

Nik

2,8552 gold badges25 silver badges25 bronze badges

answered Apr 10, 2015 at 7:59

Saad Khanani's user avatar

0

There seems also to be a relation to the environment:

I had that «invalid argument supplied foreach()» error only in the dev environment, but not in prod (I am working on the server, not localhost).

Despite the error a var_dump indicated that the array was well there (in both cases app and dev).

The if (is_array($array)) around the foreach ($array as $subarray) solved the problem.

Sorry, that I cannot explain the cause, but as it took me a while to figure a solution I thought of better sharing this as an observation.

answered Feb 22, 2015 at 11:36

araldh's user avatar

Exceptional case for this notice occurs if you set array to null inside foreach loop

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

answered Jan 18, 2016 at 9:24

Farid Movsumov's user avatar

Farid MovsumovFarid Movsumov

12.2k8 gold badges71 silver badges97 bronze badges

This warning is happening because the array that you want use is empty, you can use of below condition:

if ($your_array != false){
   foreach ($your_array as $value){
         echo $value['your_value_name'];
    }
}

answered May 12, 2022 at 6:24

Mohamad Shabihi's user avatar

Use is_array function, when you will pass array to foreach loop.

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

answered Oct 21, 2017 at 21:46

Billu's user avatar

BilluBillu

2,68326 silver badges47 bronze badges

How about this solution:

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

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

answered Nov 1, 2017 at 12:04

Julian's user avatar

JulianJulian

4,3365 gold badges38 silver badges51 bronze badges

What about defining an empty array as fallback if get_value() is empty?
I can’t think of a shortest way.

$values = get_values() ?: [];

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

answered Mar 18, 2019 at 22:27

Quentin Veron's user avatar

Quentin VeronQuentin Veron

3,0441 gold badge13 silver badges31 bronze badges

I’ll use a combination of empty, isset and is_array as

$array = ['dog', 'cat', 'lion'];

if (!empty($array) && isset($array) && is_array($array) {
    //loop
    foreach ($array as $values) {
        echo $values; 
    }
}

Nik's user avatar

Nik

2,8552 gold badges25 silver badges25 bronze badges

answered Oct 6, 2017 at 17:10

Rotimi's user avatar

RotimiRotimi

4,7734 gold badges18 silver badges27 bronze badges

<?php
 if (isset($_POST['checkbox'])) {
    $checkbox = $_POST['checkbox'];
    foreach ($checkbox as $key) {
       echo $key . '<br>';
    }
}

?>
    <input type="checkbox" name="checkbox[]" value="red">red <br>
    <input type="checkbox" name="checkbox[]" value="green">green <br>

sajadsalimian's user avatar

answered Sep 30, 2012 at 17:40

as_bold_as_love's user avatar

2

I recently moved a wordpress install from my local instance to a dev server. For the move, I installed a clean version of wordpress 3.4, moved exact duplicates of the file structre, and used the import / export feature to bring the posts in.

I then went in and set the necessary widgets, and settings. I’ve done this 100 times, and never had this problem. Here is the error:

Warning: Invalid argument supplied for foreach() in /home/content/46/9411746/html/dev/wp-admin/includes/plugin.php on line 1285

It only appears in the admin menu. I see it when I try to add a widget, change a setting, work with menus, or update meta data for a post. It pops up all over the admin menu.

Here is the function triggering the error in includes/plugin.php

function remove_menu_page( $menu_slug ) {
global $menu;

foreach ( $menu as $i => $item ) {
    if ( $menu_slug == $item[2] ) {
        unset( $menu[$i] );
        return $item;
    }
}

return false;
}

I’m using appearance > menus and have two registered here in functions.php here:

add_action( 'init', 'register_my_menus' );

function register_my_menus() {
register_nav_menus(
    array(
      'header-nav' => __( 'Main Header Navigation', 'kyosay' ),
      'footer-nav' => __( 'Footer Navigation', 'kyosay' )
    )
);
}

I am doing some other customization of the admin panel, reordering some menu items and eliminating others that my clients don’t need. I can include that code if you think it’s relevant.

Since this issue is triggered in core, I’m at a loss as to how to fix it. NOTE: The issue is not happening on my local build. Thoughts?

Edit: added remove_menu_items code from functions.php for reference

function remove_menu_items() {
remove_menu_page('link-manager.php'); // Links
remove_menu_page('edit-comments.php'); // Comments
}
add_action( 'admin_init', 'remove_menu_items' );

Update:
I have eliminated functions.php as the source of this issue. It seems to be triggered on Ajax events (dragging a new widget to a sidebar, updating a meta-box, etc. I’m going to uninstall and reinstall and see if it’s still happening. Could this have something to do with the web host (godaddy) ? It’s not showing up on my local build at all.

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Comments

@dimitrisindaryov

@ocean90
ocean90

changed the title
Warning: Invalid argument supplied for foreach() in /var/www/orthodox/data/www/orthodoxchurch.ru/wp-includes/blocks.php on line 183

Warning: Invalid argument supplied for foreach() in /wp-includes/blocks.php on line 183

Dec 7, 2018

@danielbachhuber

Hi @dimitrisindaryov,

Thanks for the report.

Based on the PHP error notice, it looks like WP_Block_Type_Registry::get_instance()->get_all_registered() may be failing to return an array.

https://github.com/WordPress/WordPress/blob/5.0-branch/wp-includes/blocks.php#L106-L107

I’m curious why this would be the case though, because WP_Block_Type_Registry‘s internal class variables can’t be modified by plugins.

Can you share which plugins you’re running? Also, have you tried deactivating each plugin one by one to see if the PHP error notice might be related to one of them?

@dimitrisindaryov

Accelerated Mobile Pages
Akismet Anti-Spam
All In One SEO Pack
All In One WP Security
AntiVirus
Bg Bible References
Classic Editor
Contact Form 7
Cyclone Slider
Easy WP Meta Description
Elementor
Google Analytics Dashboard for WP (GADWP)Автор: ExactMetrics | Детали
Google Analytics for WordPress by MonsterInsights
HayyaBuild
ImageRecycle pdf & image compression
iThemes Security
MailChimp для WordPress
Meta Description
Meta Tags Generator
Newsletter — Archive
Orbit Fox Companion
Pageviews
Popups, Lead Forms, Surveys, Live Chats WordPress Plugin — GetSiteControl
Post Views Counter
Redirection
Responsible
Security by CleanTalkGet
SEO Bulk Editor
Slide Anything — Responsive Content / HTML Slider and CarouselSimon Edge | Детали
Smart Slider 3
Subscribe2
Webcraftic Clearfy
Webcraftic Robin image optimizer
Webcraftic Скрыть страницу логина
WordPress Related Posts
WP Fastest Cache
WP Featherlight
WP Meta SEO
WP Speed of Light
WP Super Cache
WP Translitera
WP-PageNavi
WP-PostRatings
WP-PostViews
Yandex.Metrika
Yet Another Stars Rating
YouTube
YouTube Embed
Мобильное меню
Шорткоды
Яндекс.Дзен.
Яндекс.Поделиться
Яндекс.Турбо

@dimitrisindaryov

@dimitrisindaryov

This happened when your new editor turned on for the fifth version of WordPress.

@danielbachhuber

@dimitrisindaryov Have you tried deactivating each plugin one by one to see if the PHP error notice might be related to one of them?

@dimitrisindaryov

I turned off all the plugins. Nothing helps.

@x270488

Hellow!
I have same problem 2 web sites. (This happened when your new editor turned on for the fifth version of WordPress.)
I dont have plugins (on test site template is stock)
Please help!

@Gamulator

Hi.
I have just installed WP 5.0.3 to my local environment. It’s a clean setup with default settings (twentynineteen theme, no plugins working, no posts). And I have the same error.

@x270488

Hello )
in all posts in a classic editor switch to plain editor
and remove «<!-- wp:paragraph -->» and all tegs with <!-- /wp:tegs -->

RUS:
Всем привет!
Я удалил в ручном режиме во всех постах <!-- wp:тэг-->
В классическом редакторе переключив на текст.
Ошибка пропала.
Всем удачи!

@EldarAgalarov

I’m having the same issue. I found that it happens only on PHP 7.2. Do you using this version? Try to rollback to PHP 7.1 or older. and your problem will be gone.

@EldarAgalarov

@yurmar

Сделал проверку и ошибка ушла:

if ( is_array( $block['innerContent'] ) ) {
			foreach ( $block['innerContent'] as $chunk ) {
			$block_content .= is_string( $chunk ) ? $chunk : render_block( $block['innerBlocks'][ $index++ ] );
		}
	}

@youknowriad

This Code has moved to Core and is not maintained in the plugin anymore. Anyone willing to create a trac ticket instead?

@SergeyBiryukov

@youknowriad

I ran into a problem recently on a WordPress site that I manage where I was unable to disable and uninstall numerous plug-ins. After looking through the error logs on the web server, I found the following warning showing up repeatedly in the PHP error log:

PHP Warning: Invalid argument supplied for foreach() in /var/www/html/example.com/wp-cron.php on line 117

Here’s what I did to identify and fix the problem.


Before getting into details, this how-to will assume that you have basic knowledge working with Linux servers and MySQL databases, that you have access to and are familiar reviewing error logs on your server, that you have access to the database for your WordPress website through phpmyadmin or some other database tool, and that you have a backup of your WordPress site that you can restore in case things go sideways.


The problem I ran into was that I was unable to disable or uninstall some plug-ins on the WordPress website. Every time I tried, I encountered the white screen of death, aka WSOD.

Upon reviewing error logs on the server, I discovered the PHP Warning noted above. While it seems harmless (it is just a warning after all), it turns out that the cron job in the database for the WordPress website was corrupted. I confirmed it by logging into the database, opening the wp_options table, and looking at the value for the option name ‘cron’. If you’re not able to browse the table, you can run the following query to see the row value:

SELECT * FROM alb_options WHERE option_name = 'cron';

The quick fix is to reset the cron value, which can be done by clearing the value. The following query will do the trick:

UPDATE alb_options SET option_value = '' WHERE option_name = 'cron';

Once cleared, WordPress will recreate the cron value the next time the website is accessed. Once reset, you should no longer see the foreach() PHP Warning in your log files. Even better, you’ll be able to manage your plug-ins properly again, including the ability to uninstall.

In my case, the corruption was the result of a hack that added thousands of users to the WordPress install. Your case may not be the result of a hack but could be due to a poorly configured plug-in or other issue. In any case, you may want to check various areas of your WordPress website, starting with the User area, just to confirm that everything looks good.

  • Ошибка warning an error occurred while opening one or more files
  • Ошибка w12 на частотники данфосс
  • Ошибка warning 203 symbol is never used
  • Ошибка w12 на частотнике что это
  • Ошибка wargaming net error monitor