我经常遇到处理数据的问题,foreach这些数据既可以是数组也可以是null变量,并且可以为这些数据提供一些数据.
$values = get_values();
foreach ($values as $value){
...
}
Run Code Online (Sandbox Code Playgroud)
当您使用非数组的数据提供foreach时,您会收到警告:
警告:为[...]中的foreach()提供的参数无效
假设无法重构get_values()函数以始终返回数组(向后兼容性,不可用的源代码,无论其他原因),我想知道哪种方法是最简洁,最有效的方法来避免这些警告:
$values到阵列$values为数组foreach用一个包裹着ifAnd*_*lam 481
我个人认为这是最干净的 - 不确定它是否是最有效的,介意!
if (is_array($values) || is_object($values))
{
foreach ($values as $value)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我偏好的原因是,当你无论如何都没有任何东西时,它不会分配一个空数组.
小智 102
这个怎么样?更清洁,所有在一条线.
foreach ((array) $items as $item) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
Kri*_*ris 41
我通常使用类似于这样的结构:
/**
* 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...
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,此特定版本未经过测试,直接从内存中输入SO.
编辑:添加了Traversable检查
AAR*_*RTT 14
请不要依赖于转换作为解决方案,即使其他人建议将其作为防止错误的有效选项,也可能会导致另一个错误.
请注意:如果您希望返回特定形式的数组,则可能会失败.需要更多检查.
例如
(array)bool,将一个布尔值转换为数组,不会产生空数组,而是一个数组,其中一个元素包含布尔值作为int:[0=>0]或[0=>1].
我写了一个快速测试来介绍这个问题.(如果第一个测试网址失败,这是备份测试.)
包括用于测试:null,false,true,一class,一array和undefined.
在foreach中使用之前,请务必测试您的输入.建议:
$array = is_array($var) or is_object($var) ? $var : [] ;try{}catch(){}块array_key_exists特定的键,或测试数组的深度(当它是一个!).上面提供的所有答案本质上只是错误抑制。
您的 PHP 告诉您正在尝试使用类型不正确的变量,并且可能存在错误。但提供的所有答案都只是忽略了此消息。
最好的办法是在使用之前初始化每个变量。并使返回类型严格且明确。您必须问自己,为什么get_values()返回数组以外的任何内容?如果没有找到数据,为什么不能只返回一个空数组?当然可以。
试试这个:
//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
echo $val;
}
Run Code Online (Sandbox Code Playgroud)
;)
foreach ($arr ?: [] as $elem) {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
这不会检查它是否是数组,但如果变量为 null 或空数组,则跳过循环。
从 PHP 7.0 更新,您应该使用null 合并运算符:
foreach ($arr ?? [] as $elem) {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
这将解决评论中提到的警告(这里?:有一个方便的比较和输出表??)。
$values = get_values();
foreach ((array) $values as $value){
...
}
Run Code Online (Sandbox Code Playgroud)
问题总是无效的,而 Casting 实际上是清洁解决方案。
如果您使用的是 php7 并且只想处理未定义的错误,这是最干净的恕我直言
$array = [1,2,3,4];
foreach ( $array ?? [] as $item ) {
echo $item;
}
Run Code Online (Sandbox Code Playgroud)
自 PHP >= 7.1.0 使用is_iterable
https://www.php.net/manual/en/function.is-iterable.php
if (is_iterable($value)) {
foreach ($value as $v) {
...
}
}
Run Code Online (Sandbox Code Playgroud)