为foreach()提供的参数无效

它经常发生在我处理数据,可以是一个数组或一个空变量,并提供一些foreach与这些数据。

$values = get_values();


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

当你给foreach提供不是数组的数据时,你会得到一个警告:

警告:在[…]中为foreach()提供的参数无效

假设不可能重构get_values()函数以始终返回一个数组(向后兼容,没有可用的源代码,无论其他原因),我想知道哪一种方法是避免这些警告的最干净和最有效的方法:

  • $values转换为数组
  • 初始化$values到array
  • if包装foreach
  • 其他(请建议)
1127882 次浏览

就我个人而言,我认为这是最干净的-不确定它是否是最有效的,注意!

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

我偏爱的原因是,当你没有任何开始时,它不会分配一个空数组。

首先,每个变量都必须初始化。总是这样。< br > 强制转换不是一个选项 如果get_values ();可以返回不同类型的变量,当然这个值必须检查。

<?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>

我通常使用类似这样的结构:

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

请注意,这个特定的版本没有经过测试,它直接从内存输入到SO中。

编辑:添加了可否认的检查

试试这个:

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

;)

这似乎也与环境有关:

我有“无效参数提供foreach()”错误仅在开发环境中,但不在prod(我在服务器上工作,而不是localhost)。

尽管有错误,但var_dump指示数组在那里(在app和dev两种情况下)。

if (is_array($array))围绕foreach ($array as $subarray)解决了这个问题。

对不起,我不能解释原因,但我花了一段时间来找出解决方案,我想更好地分享这作为一个观察。

这个怎么样?干净多了,都是单线的。

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

foreach()显示tweets提供的警告无效参数。 去/wp-content/plugins/display-tweets-php。 然后在第591行插入这段代码,它将完美地运行

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

@Kris的代码的更简洁的扩展

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


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

特别是使用内部模板代码

<?php foreach (secure_iterable($values) as $value): ?>
...
<?php endforeach; ?>
< p > 请不要依赖铸造作为解决方案, 尽管其他人认为这是防止错误的有效选项,但它可能会导致另一个错误

请注意:如果你期望返回一个特定形式的数组,这可能会让你失败。为此需要进行更多的检查。

例如,将布尔值强制转换为数组(array)bool,将结果为空数组,但数组中有一个元素包含布尔值作为int: [0=>0][0=>1]

< p > 我编写了一个快速测试来呈现这个问题。 (这里是一个备份测试以防第一个测试url失败。

包括测试:nullfalsetrueclassarrayundefined


在foreach中使用输入之前一定要测试它。建议:

  1. 快速类型检查: $array = is_array($var) or is_object($var) ? $var : [] ;
  2. 在使用foreach和指定返回类型 . 类型提示数组方法之前
  3. 将foreach包裹在if内
  4. 使用try{}catch(){}
  5. 在产品发布之前设计适当的代码/测试
  6. 要根据合适的形式测试数组,可以在特定的键或者测试数组的深度(当数组为1时!)上使用array_key_exists
  7. 始终将帮助方法提取到全局名称空间中,以减少重复代码
foreach ($arr ?: [] as $elem) {
// Do something
}

这并不检查它是否是一个数组,但如果变量为null或空数组则跳过循环。

从PHP 7.0更新,你应该使用空合并运算符:

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

这将解决注释中提到的警告(在这里是一个比较?:??输出的方便表格)。

如果在每个循环中设置数组为空,则会出现此通知的例外情况

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


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

问题总是空的,铸造实际上是解决方案。

如果你正在使用php7,你只想处理未定义的错误,这是最干净的IMHO

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

我将使用emptyissetis_array的组合作为

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


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

当你将数组传递给foreach循环时,使用is_array函数。

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

这个解决方案怎么样:

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


if (in_array($type, $types)) {
// foreach code comes here
}
如果get_value()为空,那么定义一个空数组作为回退呢?< br >

.我想不出一条最短的路
$values = get_values() ?: [];


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

从PHP >= 7.1.0开始使用is_iterable

https://www.php.net/manual/en/function.is-iterable.php

if (is_iterable($value)) {
foreach ($value as $v) {
...
}
}

这个警告发生是因为你想要使用的数组是空的,你可以使用下面的条件:

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