检查PHP中所有数组项是否为空

96

我正在从表单中添加一个项目数组,如果它们全部为空,我想执行一些验证并将其添加到错误字符串中。

$array = array(
    'RequestID'       => $_POST["RequestID"],
    'ClientName'      => $_POST["ClientName"],
    'Username'        => $_POST["Username"],
    'RequestAssignee' => $_POST["RequestAssignee"],
    'Status'          => $_POST["Status"],
    'Priority'        => $_POST["Priority"]
);

如果数组中所有元素都为空,则执行以下操作:

$error_str .= '<li>Please enter a value into at least one of the fields regarding the request you are searching for.</li>';
7个回答

210
你可以直接使用内置的array_filter函数。
如果没有提供回调函数,所有等于FALSE的输入条目(参见转换为布尔值)将被删除。
所以可以用一行简单的代码实现。
if(!array_filter($array)) {
    echo '<li>Please enter a value into at least one of the fields regarding the request you are searching for.</li>';
}

1
我很好奇这个方法是否比我建议的implode方法更快。有任何基准测试吗? - Capsule
array_filter()已经被@dogmatic69提到过了。关于性能 - 我相信简单的foreach应该比array_filter()implode()都要快。 - binaryLV
1
@xzyfer,if(implode($array)) echo '..'即使数组元素之一为(string)"0",也会打印出'..'。关于foreacharray_filter()慢的说法 - 你确定吗?逐个删除数组元素怎么会比仅仅读取数组元素更快呢? - binaryLV
3
@xzyfer,我进行了一些测试-使用array_filter()仅检查是否填充任何值至少比基本的foreach循环慢几倍,而使用布尔变量存储结果并在第一个无效值上使用break的基本foreach循环要更快一些。即使array_filter()是一个“本地PHP函数”,它也不能真正比foreach更快,因为它必须创建新的数组变量。 - binaryLV
2
我点了赞,但我还是有点惊讶这个被接受了,因为它并没有满足要求,对吧?如果你输入 requestID=0status=0,当明显有值时会出现“请输入一个值”的结果。 - Toskan
显示剩余9条评论

26

使用空粘合剂将数组组合起来,并检查结果字符串的大小:

Implode函数是PHP中用于将数组元素组合成一个字符串的函数。该函数接受两个参数:glue和array。在这里,我们将glue设置为空字符串,因此implode函数将在数组元素之间没有添加任何分隔符的情况下将它们组合在一起。接着,我们使用strlen函数检查结果字符串的大小。

<?php if (strlen(implode($array)) == 0) echo 'all values of $array are empty'; ?>
请注意,这是一种安全的方式来将像0"0"这样的值视为非空。使用空的array_filter回调的接受答案将认为这些值为空,因为它使用empty()函数。许多表单用途必须将0视为有效答案,因此在选择最佳方法时要小心。

1
你可以移除 strlen 调用以提高效率。if(implode($array)) echo '..' - xzyfer
3
如果$str(string)'0',那么strlen($str) == 0的结果为false,而!$str的结果为true,因此strlen($str) == 0不能被替换为!$str - binaryLV
2
@kasimir,array_filter 的回调函数是可选的,手册明确说明:“如果没有提供回调函数,则会删除所有等于 FALSE(参见转换为布尔值)的输入条目。”因此,使用 array_filter 并不比这种方法更不正确,它只是一种不同的方法;-) - Capsule
1
由于原帖没有提供样本数据和对“空”含义的具体描述,并且因为此页面被用作规范,回答者应非常小心地提供强大的解释,并在其答案可能产生意外结果的情况下包括警告。array_filter()empty()经常被PHP开发人员误用/误解。 - mickmackusa
1
@mickmackusa,感谢您的评论,我已经在我的答案中添加了一条注释。 - Capsule
显示剩余12条评论

9

虽然这是一个老问题,但我想分享我的解决方案,因为它还没有在上面列出。

function isArrayEmpty(array $array): bool {
    foreach($array as $key => $val) {
        if ($val !== '' && $val !== null) // remove null check if you only want to check for empty strings
            return false;
    }
    return true;
}

1
empty() 可能会提供错误的结果。请参阅手册了解该函数如何处理 falsey 值。我建议使用调用 strlen() - mickmackusa
谢谢@mickmackusa提醒我关于falseyness的问题,我已经更新了代码以显式检查空字符串。 - Jacob Mulquin

3
简化使用方式如下:
$array = []; //target array
$is_empty = true; //flag

foreach ($array as $key => $value) {
    if ($value != '')
        $is_empty = false;
}
if ($is_empty)
    echo 'array is empty!';
else
    echo 'array is not empty!';

我们应该在这个脚本中看到一个break。你的答案缺少了教育性的解释。这实际上是与https://dev59.com/U2445IYBdhLWcg3wGWd7#38447764相同的答案,但是更糟糕的版本。 - mickmackusa

3

你其实不需要它。
你将单独验证这些字段,通过完成此过程,您可以确定数组是否为空(或包含无效值,这是一样的)。


有趣!我想知道这是否比将数组implode更快。 - Capsule
2
对于数组大小为6的情况,即使您花费一生时间检查数组,也永远不会看到任何微小的差异。对于大于1000的大小,我建议根本不要使用数组。 - Your Common Sense
既然我们正在谈论网站,您必须根据访问者数量进行乘法运算。1000个或100个访问者计算10个数组在CPU成本方面是相同的。您不能因为您的网站变得受欢迎而决定停止使用数组;-) - Capsule

-1

我有同样的问题,但想要单独检查数组中的每个元素以查看哪个为空。这比预期的要困难,因为您需要创建键值和实际值分别在不同的数组中进行检查并响应空数组元素。

print_r($requestDecoded);
$arrayValues = array_values($requestDecoded);  //Create array of values
$arrayKeys = array_keys($requestDecoded);      //Create array of keys to count
$count = count($arrayKeys);
for($i = 0; $i < $count; $i++){  
    if ( empty ($arrayValues[$i] ) ) {         //Check which value is empty
        echo $arrayKeys[$i]. " can't be empty.\r\n";
    } 
}

结果:

Array
(
    [PONumber] => F12345
    [CompanyName] => Test
    [CompanyNum] => 222222
    [ProductName] => Test
    [Quantity] =>
    [Manufacturer] => Test
)

数量不能为空。


1
什么?只需使用foreach($array as $key => $value)并测试$value是否为空即可。 - Capsule

-4

这很简单:

foreach($array as $k => $v)
{
    if(empty($v))
    {
        unset($array[$k]);
    }
}
$show_error = count($array) == 0;

你还需要将数组值的封装改为双引号。


他不需要一个数字,只要1就足够了。 - Your Common Sense
什么?他想知道是否所有元素都为空,没有数字只有一个布尔值。 - RobertPitt
我认为Col.粗略地表达的意思是在PHP中,count($array) == 0count($array)都会被计算为true,因此额外比较和赋值步骤是不必要的开销。虽然在php中,赋值的成本很小。 - xzyfer
啊,是的,这并没有太大的区别,但我宁愿大部分时间使用布尔值,我不明白为什么会有负评,这是一种有效的方法,并且可以得到所需的结果。 - RobertPitt
抱歉晚来一步,但我也支持 @xzyfer 的观点。在“foreach”循环中使用unset()应该被避免,而且通常不建议使用empty(),因为empty(0)empty('0')都是true。在这个问题中,$_POST["Priority"]可能被设置为0(它是一个优先级,0可能是有效的),并会触发错误。 - Capsule
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接