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

Jer*_*gan 8 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";
Run Code Online (Sandbox Code Playgroud)

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

starting
ending
Run Code Online (Sandbox Code Playgroud)

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

<?php
    if (1 == deflaut)
        echo "deflaut2\n";
Run Code Online (Sandbox Code Playgroud)

得到:

PHP Notice:  Use of undefined constant deflaut - assumed 'deflaut' in ...
Run Code Online (Sandbox Code Playgroud)

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

Ry-*_*Ry- 8

它可能只是将它解释为另一个标签(这是有道理的,因为技术上default 一个标签,case也可以被解释为一种特殊的标签),可以与之一起使用goto.试一试goto,找出答案.我会,但我没有PHP 5.3.3,抱歉.

  • @fiXedd:错误清楚地表明这是一个goto标签,因为goto知道它在哪里并且它不能跳到那里.只是注意到. (4认同)

lon*_*day 4

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

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

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

case defalut当发现您期望的错误时,您可以通过执行 来使其强制发生错误。