我应该声明并检查PHP中是否存在变量?

时间:2011-12-07 01:16:24

标签: php structure undefined isset

我在XAMPP上注意到严格的错误报告已经开启,现在我得到了未定义的索引错误。我只有两个小问题(我还在这里学习):

我知道你没有在PHP中声明变量但是否有任何优势来声明它们?如果没有,当我没有定义严格错误报告时,为什么会出现错误?

例如,当我使用get变量时,我会在运行像

这样的函数之前检查它们的值
if($_GET['todo'] == 'adduser')
    runFunctionAddUser();

这会产生错误,因为我从不检查get变量是否首先存在。我应该

if(isset($_GET['todo']))
    if($_GET['todo'] == 'adduser')
        runFunctionAddUser();

代替?这会有优势还是不必要又慢?

4 个答案:

答案 0 :(得分:7)

这个帖子很老了,但我做了一些与问题相关的测试,所以我不妨发布它:

测试代码(PHP 5.3.3 - CentOS 6.5版(最终版)):

class NonExistant
{
    protected $associativeArray = array(
        'one' => 'one',
        'two' => 'two',
        'three' => 'three',
        'four' => 'four',
        'five' => 'five',
        'six' => 'six',
    );

    protected $numIterations = 10000;

    public function noCheckingTest()
    {
        for ($i = 0; $i < $this->numIterations; $i++) {
            $this->associativeArray['none'];
        }
    }

    public function emptyTest()
    {
        for ($i = 0; $i < $this->numIterations; $i++) {
            empty($this->associativeArray['none']);
        }
    }

    public function isnullTest()
    {
        for ($i = 0; $i < $this->numIterations; $i++) {
            is_null($this->associativeArray['none']);
        }
    }


    public function issetTest()
    {
        for ($i = 0; $i < $this->numIterations; $i++) {
            isset($this->associativeArray['none']);
        }
    }

    public function arrayKeyExistsTest()
    {
        for ($i = 0; $i < $this->numIterations; $i++) {
            array_key_exists($this->associativeArray['none']);
        }
    }
}

结果是:

| Method Name                              | Run time             | Difference
=========================================================================================
| NonExistant::noCheckingTest()            | 0.86004090309143     | +18491.315775911%
| NonExistant::emptyTest()                 | 0.0046701431274414   | +0.95346080503016%
| NonExistant::isnullTest()                | 0.88424181938171     | +19014.461681183%
| NonExistant::issetTest()                 | 0.0046260356903076   | Fastest
| NonExistant::arrayKeyExistsTest()        | 1.9001779556274      | +209.73055713%

所有功能的调用方式与通过call_user_func()相同,并以microtime(true)

计时

<强>观察

empty()isset()是其他2种方法的明显赢家,这两种方法几乎与性能挂钩。

is_null()表现不好,因为它需要首先查找值,几乎与访问不存在的值$this->associativeArray['none']相同,这涉及到数组的完整查找。

然而,我对array_key_exists()的表现感到惊讶。它比empty()isset()慢2倍。

注意:

我测试的所有功能都有不同的用途,此基准仅适用于您希望快速检查数组中值的最通用用例。我们可以讨论null是否应被视为&#34;值&#34;或者只是一个不存在的指标,但这是另一个话题。 o.o

更新2017-01-20

使用PHP 7.1

修正了@bstoney

提到的错误
$ php -v
PHP 7.1.0 (cli) (built: Dec  2 2016 03:30:24) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
$ php -a
php > $a = ['one' => 1, 'two' => 2, 'three' => 3];
php > $numIterations = 1000000;
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { $a['none']; }; echo microtime(true) - $start;
0.43768811225891
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { empty($a['none']); }; echo microtime(true) - $start;
0.033049821853638
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { is_null($a['none']); }; echo microtime(true) - $start;
0.43995404243469
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { isset($a['none']); }; echo microtime(true) - $start;
0.027907848358154
php > $start = microtime(true); for ($i = 0; $i < $numIterations; $i++) { array_key_exists('none', $a); }; echo microtime(true) - $start;
0.049405097961426

答案 1 :(得分:1)

我建议if(!empty($_GET['todo']) && $_GET['todo'] == 'adduser')。这是因为PHP短路逻辑表达式。

最好使用E_ALL(包括E_NOTICE)的错误报告级别进行开发,因为它可以快速帮助识别错误输入的变量/密钥名称。

如果你问的是否测试变量的存在是否缓慢,你就会问错误的问题(答案是它的速度很快。你的工作进展缓慢与文件系统/数据库/等)。

答案 2 :(得分:0)

这不是关于你得到的缺失变量的错误,这是一个关于尝试将变量与不存在的变量进行比较的错误。

如果您尝试将nothingness与'adduser'进行比较,则会引发错误,因为您无法比较nothingness

这就是#1的答案。

对于#2,你应该几乎总是(如果不是总是)检查你的变量是否存在,尤其是你的GET变量,因为它们很不稳定。

答案 3 :(得分:0)

这不是一个直接的答案,因为你已经知道了,但有关如何存档的信息:

我总是在所有程序中使用this之类的函数来初始化传入变量(如果需要,使用默认值)。

所以你可以像这样进行初始化:

$todo = initGet('todo');

然后正常检查:

if($todo=='adduser') {

功能:

function initGet($var, $default=''){
    if(!isset($_GET[$var])) return $default;
    return $_GET[$var];
}