无法检测空变量?

时间:2013-10-30 11:21:47

标签: php string

我有一个PHP脚本,通过查询字符串接收变量。

一开始我使用explode将某些字符串放在数组中,因为它们包含我需要使用的几个值。举个例子:

index.php?a=2,2&b=foo&i=&s=bar

$d['i'] = explode(',',$_GET['i']); 
$d['s'] = $_GET['s'];       
$d['a'] = explode(',',$_GET['a']);
$d['b'] = explode(',',$_GET['b']);

我需要检查是否设置了某些变量,因为它们是必需的,即必须设置“i”和“s”并包含一些数据。

如果没有设置或为空,我想重定向到错误页面。但是,它并不总是有效,我无法弄清楚原因。 当我说“不总是”时,这就是我的意思。它似乎随机接受并拒绝空变量,我不知道为什么。

这是我现在拥有的PHP代码:

    if(!$d['i'] || !$d['s']) {
        header('Location: error.php?e=2');
    }

首先我只有上面的内容,但是当变量设置但是空的时候,它仍然存在。

我尝试的是使用:

    if(strlen($d['i']) < 1 || strlen($d['s']) < 1) {
        header('Location: error.php?e=2');
    }

但是出于一些奇怪的原因,它仍然接受空字符串。 我也试过这个,没有成功:

    if(empty($d['i']) < 1 || empty($d['s']) < 1) {
        header('Location: error.php?e=2');
    }

我在这里做错了什么线索?

3 个答案:

答案 0 :(得分:0)

爆炸后,变量将是一个数组而不是一个字符串,因此您需要使用计数进行检查。

if(!isset($d['i'][0]) || !isset($d['s'])) {
    header('Location: error.php?e=2');
}

OR

if(count($d['i']) < 1 || strlen($d['s']) < 1) {
    header('Location: error.php?e=2');
}

答案 1 :(得分:0)

直接回答:

使用trimarray_filter确保数组具有值。

/* get the string value of i */
$i = $_GET['i'];

/* explode it into an array of values */
$i = explode(',', $i);

/* use array_map to apply trim to each value contained by i */
$i = array_map('trim', $i);

/* OR */

/* use array_map to apply intval / floatval to each value contained by i */
$i = array_map('intval', $i);

/* use array_filter to remove all empty entries */
/* this includes integer 0 (zero) values, empty strings, nulls etc. */
$i = array_filter($i);

/* OR */

/* use array_filter to remove all empty entries */
/* specify a function which validates if a value */
/* should be considered empty, perhaps you don't */
/* want integer 0 (zero) values to be filtered */
function my_filter($value) {
    return($value === '');
}

$i = array_filter($i, 'my_filter');

/* after trimming and filtering the array */
/* you can use PHP's `empty($i)` or `count($i) < 1` */
if(empty($i)) {
    /* do redirect */
}

背景信息:

当您尝试检查某些内容是true还是falsesetnot setempty还是not empty时,很多隐含的转换和假设。

在您的特定情况下:

if($d['i'] || $d['s']) {}

做出以下假设:

由于$d['i']是一个数组,因此根据天气true进行false!empty($d['i'])评估,这意味着它必须包含至少一个值。

例如,如果来自$_GET['i']的原始字符串值为',',则爆炸将生成包含两个空字符串的数组。因为$d['i']包含两个空字符串,所以它被认为不是空的 - 即使它包含的值本身也被认为是空的。

如果来自$_GET['i']的原始字符串值类似'0',则爆炸将生成包含一个字符串的数组。因为$d['i']包含一个字符串,所以它被认为不是空的 - 即使它包含的值本身也被认为是空的。

例如,如果来自$_GET['i']的原始字符串值为' '(注意空格),则爆炸将生成包含包含一个空格的字符串的数组。因为$d['i']包含字符串,所以它被认为不是空的。

答案 2 :(得分:0)

感谢您提供良好的提示和技巧! 以下是我现在解决的问题:

index.php?a=2,2&b=foo&i=&s=bar

if(empty(trim($_GET['i'])) || empty(trim($_GET['s'])) {
    header('Location: error.php?e=2');
}

$d['i'] = explode(',',trim($_GET['i'])); 
$d['s'] = trim($_GET['s']);       
$d['a'] = explode(',',trim($_GET['a']));
$d['b'] = explode(',',trim($_GET['b']));

也许不是最好的解决方案,但它确实有效!