检查 $_POST-value 是否为空

34
if(isset($_POST['submit'])) {
    if(!isset($_POST['userName'])) {
        $username = 'Anonymous';
    }      
    else $username = $_POST['userName'];
}

我无法将$username设为"Anonymous"。它要么是空的,要么是$_POST['userName']的值。


2
isset值检查变量是否已经设置。然而,当您提交表单时,变量将是一个空字符串。 - miki725
8个回答

51

isset()函数将在变量已初始化的情况下返回true。如果您有一个表单字段,其name值设置为userName,当该表单被提交时,该值将始终是"set",尽管可能没有任何数据。

相反,trim()字符串并测试其长度。

if("" == trim($_POST['userName'])){
    $username = 'Anonymous';
}      

直接使用全局变量而不进行净化或转义是否安全? - Alex Jones
5
在上面的例子中,变量只用于比较,没有被进一步使用。如果它正在改变上下文(如输出到HTML / JSON,用于数据存储查询等),则应将其视为不受信任的,并根据上下文进行处理。 - Andy
@Andy 只有在控件成功时才有效。在 PHP 中,不适用于未选中的复选框。trim() 仅从两端删除不良内容。不是通用解决方案。对输入进行了假设。如果 $_POST 中不存在 userName 键,则会失败。 - Anthony Rutledge

49
如果表单提交成功,$_POST['userName'] 应该总是被设置的,尽管它可能包含一个空字符串,这与根本没有设置是不同的。而应该检查是否为空,可以使用empty()函数。
if (isset($_POST['submit'])) {
    if (empty($_POST['userName'])) {
        $username = 'Anonymous';
    } else { 
        $username = $_POST['userName'];
    }
}

设置一个先例,即“应忽略含糊不清的空值”。这可能是特定于问题的完整解决方案,但并非普适的解决方案。不要将此解决方案用作所有文本框的通用解决方案,否则您将遇到逻辑错误。 - Anthony Rutledge

14

要检查属性是否存在,而不考虑值,请使用:

if (array_key_exists('userName', $_POST)) {}

要检查属性是否已设置(即属性存在且值不为nullfalse),请使用:

if (isset($_POST['userName'])) {}

要检查属性是否已设置且不为空(即不是空字符串,0(整数),0.0(浮点数),'0'(字符串),nullfalse[](空数组)),请使用:

if (!empty($_POST['userName'])) {}

第一个用例是最技术上准确的解决方案,但它无法击败第二个用例的速度。第三个用例是一种应该避免使用的代码,因为它存在歧义性,特别是对于标量值。当然,我所说的是 application/x-www-form-urlencoded 数据,而不是 JSON。 - Anthony Rutledge

8

问题:检查$_POST值是否为空。

翻译:检查数组键/索引是否有与之关联的值。

回答:取决于您对安全性的重视程度。取决于哪些输入被允许作为有效输入。

1. Some people say use empty().

来自PHP手册:

"[Empty] 确定变量是否被视为空。如果变量不存在或其值等于FALSE,则变量被视为空。"

因此,以下内容被视为空。

"" (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)

如果您的输入控件没有任何有效值,则可以使用empty()。问题在于empty()可能太宽泛,无法一致地使用(在不同的输入控件提交到$_POST$_GET时,以相同的方式、出于相同的原因)。empty()的一个好用途是检查整个数组是否为空(没有元素)。
2. Some people say use isset().

isset()(一种语言结构)无法像isset($myArray)那样操作整个数组。它只能操作变量数组元素(通过索引/键):isset($var)isset($_POST['username'])isset()语言结构有两个作用。首先,它检查变量或数组索引/键是否与值相关联。其次,它检查该值是否不等于PHP NULL值。

简而言之,最准确的检查可以通过isset()实现,因为某些输入控件在未选中或未选中时甚至不会向$_POST注册。我从未见过提交PHP NULL值的表单。我的表单都没有,所以我使用isset()来检查$_POST键是否没有与其关联的值(并且不为NULL)。isset()是比empty()更严格的空值测试(在您问题的意义上)。

3. Some people say just do if($var), if($myArray), or if($myArray['userName']) to determine emptiness.

在if语句中,您可以测试任何计算为true或false的内容。空数组计算为false,未设置的变量也是如此。包含PHP NULL值的变量也计算为false。不幸的是,在这种情况下,与empty()一样,许多其他东西也会计算为false:1.空字符串'',零(0),零点零(0.0),字符串零'0',布尔值false和某些空XML对象。使用isset()并考虑将其与其他测试组合使用。例如:可能由于超级全局变量的混乱而无法工作,但对于其他数组而言则没有问题。
if (is_array($_POST) && !empty($_POST)) {
    // Now test for your successful controls in $_POST with isset()
} 

因此,在你确定$_POST是否表示一个数组并且是否存储了任何值之前,为什么要寻找与键相关联的值(这是许多人未考虑的)?请记住,人们可以在不使用网络浏览器的情况下向您的表单发送数据。也许有一天您会测试$_POST只有允许的键,但那是另一天的谈话。
有用的参考资料: PHP手册:类型测试比较表

is_array($_POST) && !empty($_POST) 是对 empty() 函数的不合理/不适当使用。首先,像 $_POST 这样的超全局变量总是被声明的,因此检查它是否被声明没有任何意义。其次,如果它是一个可能未被声明的变量,则应在调用 is_array() 之前检查 !empty()。应在调用其他函数之前调用 empty()isset() 来确保变量已声明。在我看来,太多的开发人员不知道如何/何时使用 isset()empty(),也不知道它们实际上是做什么的。 - mickmackusa
is_array的严格测试并不是不合逻辑的,但你对它的推理却是如此。我所知道的是,没有什么能防止一个不幸的超全局变量被重新定义。无论如何,如果你在2022年仍在使用$_POST,那么你需要升级你的代码。 - Anthony Rutledge
@AnthonyRutledge $_POST 在大部分静态网站中仍然适用于添加一些表单,或者当你自己编写框架时...即便如此,最好还是使用 $_POST = filter_input_array(INPUT_POST, FILTER_UNSAFE_RAW); 来自行设置以确保安全性。 - Fravadona

3

将其更改为:

if(isset($_POST['submit'])){

    if(!(isset($_POST['userName']))){
    $username = 'Anonymous';
    }      
    else $username = $_POST['userName'];
}

转换为这样:

if(!empty($_POST['userName'])){
     $username = $_POST['userName'];
}

if(empty($_POST['userName'])){
     $username = 'Anonymous';
}

1
你可能想亲自尝试一下这个。 - jprofitt
从高层来看,我希望人们能够理解,在$_POST中检查值的表单特定解决方案并不是通用或普遍的方法。检查是否为空永远不应该是对表单输入进行测试的第一步。绝不。 - Anthony Rutledge

3
$username = filter_input(INPUT_POST, 'userName', FILTER_SANITIZE_STRING);
if ($username == '') {$username = 'Anonymous';}

最佳实践-始终过滤输入,清理字符串可以,但最好使用自定义回调函数来真正过滤掉不可接受的内容。 然后检查现在安全的变量是否为空/空白,如果是,则设置为匿名。不需要“else”语句,因为它已经在第一行设置了。


2

针对这些用例,我建议使用简单的一行比较。

$username = trim($_POST['userName'])?:'Anonymous';

以下是针对某种情况的使用方法,即您确定错误日志记录已关闭,以便不会收到未初始化变量的警告。

以下是谨慎版本:

$username = !empty(trim(isset($_POST['userName'])?$_POST['userName']:''))?$_POST['userName']:'Anonymous';

这里实现了一个检查,确保在访问 $_POST 变量之前已经设置好了。


1
如果值为“0”,那么变量将为NULL。不要使用它。 - Erikas
1
@Erikas,我修改了它,这样它就不会在0上失败了。 - Tschallacka
@Tschallacka 没有理解检查HTTP POST请求中是否存在必要的键/值对的重点。如果缺少强制性键,则应尽快拒绝HTTP POST输入。虽然你的意图是好的,但你的解决方案过于庞大且缺乏灵活性。如果一个键/值对不是强制性的(例如带有复选框的表单),那么你将为一个本不应该存在的变量提供一个值。 - Anthony Rutledge
@AnthonyRutledge 是的,但在这种情况下,它是一个用户名,而不是复选框。请查看问题:我无法将 $username 设置为 "Anonymous"? - Tschallacka
@Tschallacka 我正在看这个问题。它并不是在问如果 userName 的值为空字符串该怎么办。代码是检查 $_POST 中是否存在键 userName。因此,代码的结论是错误的。如果键不存在,则提交是异常的,可能是黑客攻击,并应尽快终止。在这种情况下将字符串“Anonymous”分配给 userName 是错误的。对于错误解决方案的好答案仍然是错误的。 - Anthony Rutledge

1

isset 是用来测试哈希表(或关联数组)中所检查的键是否“已设置”。在这个上下文中,“已设置”只是指它是否知道该值。没有值就是一个空字符串。

因此,只要您有一个名为 userName 的输入字段,无论他们是否填写它,这将是真的。您真正想做的是检查 userName 是否等于一个空字符串''。


测试之间不能互相排斥。即使是文本框,您也必须首先检查userName键是否存在。仅仅因为您创建了一个表单,并不意味着世界上的人都要使用它来发送应用程序数据。不要假设您的表单将被用于发送应用程序数据。如果关键字在$_POST中是必要的、强制性的,但却缺失了,则是时候终止表单处理了。 - Anthony Rutledge

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