PHP 允许 switch 语句中存在无效代码
我无法理解为什么以下内容不会在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它可能会将其解释为另一个标签(这是有道理的,因为从技术上来说,
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 andcase
could be interpreted as a special kind of label too) that could be used withgoto
. Try agoto
and find out. I would, but I don't have PHP 5.3.3, sorry.问题是你的代码没有按照你的想法去做。
case
块仅在下一个case
块发生时结束,或者当找到default:
时,或者当结束} 已达到。这意味着
defalut
是case 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 nextcase
block occurs, or whendefault:
is found, or when the closing}
is reached. This means thatdefalut
is part of thecase 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 thegoto
operator was introduced in PHP 5.3. The syntaxword:
at the beginning of a PHP statement is now a target accessible viagoto
. Sogoto 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.有趣的是,在我的 5.3.2 上,如果在拼写错误的默认值之上没有其他 case 语句,这确实会失败。
这会因“T_UNEXPECTED_STRING”语法错误而终止:
这个有效:
看起来您在 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:
This one works:
It would appear you've found a bug in the PHP parser. Wouldn't consider a serious bug, but a bug nonetheless.