如何更好地检查变量是否为null或空字符串?

214
由于PHP是一种动态语言,那么检查提供的字段是否为空的最佳方法是什么?
我想确保:
1. null被视为空字符串 2. 只包含空格的字符串被视为空 3. "0"不被视为空
这是我目前的进展:
$question = trim($_POST['question']);

if ("" === "$question") {
    // Handle error here
}

一定有更简单的方法做这个吧?

2
我建议使用empty($question),但这也会将0视为空。 - Powerlord
5
Yoda条件很糟糕。 - user3791372
我希望我知道一个比基本条件更简单的代码。 - Your Common Sense
12个回答

350
对于帖子标题中的问题,一个直接的回答是非常明显和直截了当的:
function IsNullOrEmptyString($str){
    return ($str === null || trim($str) === '');
}

但对于您实际询问的“输入变量”,这将是多余且不足够的。
一个`$_POST`数组元素不能为null,因此检查null将是多余的。同时,任何外部变量都可能不存在,这将引发错误,您可能希望避免这种情况。因此,假设您需要一个`$question`变量,代码应该是这样的:
$question = trim($_POST['question'] ?? '');
if ("" === $question) {
    // Handle error here
}

5
既然OP要求一个非常简单的操作的“更简单”版本,我认为实际上需要的是“更好”。 - chaos
2
我把它转换成了一个函数。这应该能让您的验证代码更简单。 - Michael Haren
8
在这里,!isset() 的目的是什么?它与 is_null() 有什么不同? - nickf
2
也返回(!empty($question) || trim($question)===''); - SpYk3HH
2
更正我之前的评论(右括号放错位置了):可以简单地使用 return trim($question)===''; - ToolmakerSteve
显示剩余8条评论

126

虽然这是一篇旧帖,但可能有人像我一样需要它 ;)

if (strlen($str) == 0){
do what ever
}

用你的变量替换$strNULL""在使用strlen时都返回0。


4
常见的写法是:if(strcmp($var, '') == 0)...,意思是如果变量 $var 的值与空字符串相等则执行某些操作。strcmp() 函数用于比较两个字符串是否相等,它返回一个整数值,如果两个字符串相等则返回 0。 - peter
13
为什么要使用“==0”而不是只是使用“if (strlen($str))”? - Noumenon
20
因为那样会影响可读性,而且不解决任何问题。很容易将您的建议理解为“如果有长度”,但实际上正好相反。 - Mattias Åslund
11
仅有空格的字符串不会被处理,如果有人在意。 - airboss
5
如果该变量未设置,这将生成警告。 - Konstantin Pereiaslov
显示剩余3条评论

32
使用PHP的empty()函数。以下情况被认为是空的:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)

更多详细信息,请查看空函数


15
海报上说他们不想把“0”视为空。 - dougd_in_nc
@dougd_in_nc SO的目的是让问题尽可能通用,以建立一个知识库,并且还有更多像我这样从谷歌进入这个问题的人,他们并不了解原帖作者的所有要求。对于这些人来说,这个回答是正确的,不应该受到负评。 - Hashim Aziz

23

如果我错了,我会谦虚地接受,但是我在自己的测试中发现以下内容适用于测试字符串(0) ""和空值变量:

if ( $question ) {
  // Handle success here
}

也可以反过来测试成功的情况,例如:

if ( !$question ) {
  // Handle error here
}

1
我可以建议使用 "if (trim($n))..",否则如果一个 $_POST 变量(例如)只是 " ",它将被视为有效,而在大多数情况下,这几乎等同于一个空字符串。 - Michael M
如果“”不是特定函数的可接受值,那么使用trim将是一个好主意。 - Adal
8
对于“0”,数值0或0.0和FALSE,这将返回false。 - Vedmant

7

注意trim()函数可能会出现假负值——它在修剪之前执行了一个字符串转换,因此如果你传递一个空数组,它将返回例如"Array"。这可能不是一个问题,取决于你如何处理数据,但是根据你提供的代码,如果POST数据中提供了一个名为question[]的字段,它可能会被认为是非空字符串。相反,我建议使用:

$question = $_POST['question'];

if (!is_string || ($question = trim($question))) {
    // Handle error here
}

// If $question was a string, it will have been trimmed by this point

我认为,如果你得到了一个数组,而你期望的是一个字符串,那么这应该是一个错误。如果你期望得到一个数组,那么你应该有一个单独的过滤函数来处理它。 - OIS
这段代码是不是将其视为错误?如果过滤操作在其他地方完成,就要小心确保不会将参数验证规则的知识重复到不同的位置。 - grantwparks

4
在2023年,我建议使用空值合并运算符。这也将在数组键不存在的情况下抑制错误。
if (trim($_POST['question'] ?? '') === '') {
    // Handle error here
}

2

这个函数检查数组和字符串:

function is_set($val) {
  if(is_array($val)) return !empty($val);

  return strlen(trim($val)) ? true : false;
}

还不错。PHPst的答案虽然更简洁,但是实现了同样的功能。 - Allain Lalonde

2
为了使程序更加健壮(包括制表符、回车等),我定义如下内容:

最初的回答:

function is_not_empty_string($str) {
    if (is_string($str) && trim($str, " \t\n\r\0") !== '')
        return true;
    else
        return false;
}

// code to test
$values = array(false, true, null, 'abc', '23', 23, '23.5', 23.5, '', ' ', '0', 0);
foreach ($values as $value) {
    var_export($value);
    if (is_not_empty_string($value)) 
        print(" is a none empty string!\n");
    else
        print(" is not a string or is an empty string\n");
}

来源:


2

没有比自动化这个过程更好的方法了,因为这是您通常经常执行的操作。

大多数框架都提供了一种简化参数解析的方法。您可以构建自己的对象来完成此任务。以下是一个快速而简单的示例:

class Request
{

    // This is the spirit but you may want to make that cleaner :-)
    function get($key, $default=null, $from=null)
    {
         if ($from) :
             if (isset(${'_'.$from}[$key]));
                return sanitize(${'_'.strtoupper($from)}[$key]); // didn't test that but it should work
         else
             if isset($_REQUEST[$key])
                return sanitize($_REQUEST[$key]);

         return $default;
    }

    // basics. Enforce it with filters according to your needs
    function sanitize($data)
    {
          return addslashes(trim($data));
    }

    // your rules here
    function isEmptyString($data)
    {
        return (trim($data) === "" or $data === null);
    }


    function exists($key) {}

    function setFlash($name, $value) {}

    [...]

}

$request = new Request();
$question= $request->get('question', '', 'post');
print $request->isEmptyString($question);

Symfony广泛使用这种语法糖。

但是,你提到的"// Handle error here"不仅仅如此。你正在混合两个任务:获取数据和处理数据。这完全不同。

您可以使用其他机制来验证数据。同样,框架可以向您展示最佳实践。

创建代表表单数据的对象,然后附加进程并回退。它听起来比快速编写PHP脚本要多得多(第一次),但它是可重用的、灵活的,并且由于使用常规PHP进行表单验证很容易变成意大利面条代码,因此出错的可能性要小得多。


26
你做的完全是他不想要的相反的事情...把事情变得简单。 - TravisO

1
当您想检查字段是否提供了值时,该字段可能是一个 stringarray 或未定义的。因此,以下内容已足够。
function isSet($param)
{
    return (is_array($param) && count($param)) || trim($param) !== '';
}

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