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

发布于 2024-11-19 07:27:28 字数 649 浏览 1 评论 0原文

我无法理解为什么以下内容不会在 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 ...

这是为什么?是否有一个设置可以禁止我告诉它对此类事情严格?

I'm having some trouble understanding why the following doesn't result in a compiler error in 5.3.3 (errored-out correctly on my coworkers 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";

Instead of giving me a compiler error (or even a warning) it just gives this:

starting
ending

However, if I use it in an if-statement it gives me what I'd expect:

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

gives:

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

Why is this? Is there a setting somewhere I can disable to tell it to be strict about this sort of thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

删除→记忆 2024-11-26 07:27:28

它可能会将其解释为另一个标签(这是有道理的,因为从技术上来说,default一个标签,而case可以解释为一个特殊类型的标签)可以与goto一起使用。尝试一下 goto 并找出答案。我愿意,但抱歉,我没有 PHP 5.3.3。

It could possibly be interpreting it as just another label (which makes sense, given that technically default is a label and case could be interpreted as a special kind of label too) that could be used with goto. Try a goto and find out. I would, but I don't have PHP 5.3.3, sorry.

旧故 2024-11-26 07:27:28

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

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

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

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

The problem is that your code isn't doing what you think. A case block only ends when the next case block occurs, or when default: is found, or when the closing } is reached. This means that defalut is part of the case 2: block. So it is never even interpreted.

However, it doesn't even fire a syntax error (not even if you do switch (2). This is because the goto operator was introduced in PHP 5.3. The syntax word: at the beginning of a PHP statement is now a target accessible via goto. So goto defalut; can be used to go to the label.

(Actually, it can't, because of a restriction on targets inside switch blocks to avoid infinite loops, but this should illustrate the point...)

You can make it force an error by doing case defalut, when the error that you expect is found.

倚栏听风 2024-11-26 07:27:28

有趣的是,在我的 5.3.2 上,如果在拼写错误的默认值之上没有其他 case 语句,这确实会失败。

这会因“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 解析器中发现了一个错误。不会认为是一个严重的错误,但仍然是一个错误。

Interesting, on my 5.3.2, this does fail IF there is NO other case statement above the mispelled default.

This dies with a "T_UNEXPECTED_STRING" syntax error:

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

This one works:

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

It would appear you've found a bug in the PHP parser. Wouldn't consider a serious bug, but a bug nonetheless.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文