PHP允许在switch语句中使用无效代码

时间:2011-07-08 20:57:48

标签: php switch-statement

我无法理解为什么以下不会导致5.3.3中的编译器错误(在我的同事5.2.5上正确出错):

<?php
    echo "starting\n";

    switch(1) {
        case 2:
            echo "two\n";
            break;
        defalut:        // note the misspelling
            echo "deflaut\n";
    }

    echo "ending\n";

而不是给我一个编译器错误(甚至是警告),它只是给出了这个:

starting
ending

但是,如果我在if语句中使用它,它会给我我期望的内容:

<?php
    if (1 == deflaut)
        echo "deflaut2\n";

给出:

PHP Notice:  Use of undefined constant deflaut - assumed 'deflaut' in ...

这是为什么?我可以禁用某个设置,告诉它对这类事情要严格吗?

3 个答案:

答案 0 :(得分:8)

它可能只是将其解释为另一个标签(这是有道理的,因为技术上default 是一个标签,case可以解释为一种特殊的标签也可以与goto一起使用。试试goto然后找出答案。我愿意,但我没有PHP 5.3.3,对不起。

答案 1 :(得分:4)

问题是您的代码没有按照您的想法进行。 case阻止仅在下一个case阻止发生,或找到default:时,或达到结束}时结束。这意味着defalutcase 2:块的一部分。所以它甚至从未被解释过。

但是,它甚至不会触发语法错误(即使你执行switch (2)也不会。这是因为{5.3}中引入了goto运算符。语法word: at PHP语句的开头现在是可通过goto访问的目标。因此可以使用goto defalut;转到标签。

(实际上,它不能,因为switch块内的目标受到限制以避免无限循环,但这应该说明一点......)

当您发现错误时,可以通过case defalut强制执行错误。

答案 2 :(得分:1)

有趣的是,在我的5.3.2上,这确实失败 IF 在错误的默认值之上没有其他案例陈述。

这会因“T_UNEXPECTED_STRING”语法错误而死:

switch (1) {
   defalut:
       echo "this should never come out";
       break;
   default:
       echo "default matched properly"
}

这个有效:

switch (1) {
   case 2:
        echo "2\n";
        break;
   defalut:
        echo "this should never come out";
        break;
   default:
        echo "the default value\n";
}

看起来你在PHP解析器中发现了一个错误。不会考虑一个严重的错误,但仍然是一个错误。