2

我有非常简单的测试用例,带有结束标签,额外a的目的:

<?php echo 'test'; a?>

而且,没有结束标签,故意没有结束标签:

<?php echo 'test'; a

什么时候display_errors = On

  • 带有结束标签 => 测试 注意:使用未定义的常量 a - 在第 3 行的 test.php 中假定为“a”

  • 没有结束标记 => 解析错误:语法错误,第 3 行 test.php 中的意外 $end

什么时候display_errors = Off

  • 带有结束标签 => 测试

  • 没有结束标签 => HTTP 500

为什么我收到 HTTP 500 错误?为什么输出(错误消息除外)依赖于 display_errors 选项?我认为它只确定是否会打印错误。这是一个错误吗?

4

4 回答 4

0

原因如下:

当 PHP 看到结束?>标记时,它会添加一个隐式分号。这允许这样的语法:

<?php echo "something" ?>

为什么这很重要?

因为这意味着当你有结束标签时,你的流浪a实际上被视为a;.

这种差异足以让 PHP 尝试解析它。它无法识别它,因此它猜测它是一个未知常数,并且您会收到您看到的通知消息。

如果没有结束标记,也没有分号,PHP 会看到未终止的代码行。这是一个语法错误;PHP根本无法解析它,所以它放弃了。

希望能解释差异。

(在旁注中,整个未知常量所以我会假设一个字符串是 PHP 最严重的错误之一。它的存在是出于历史原因,但我真的希望他们在某个时候弃用它未来;它使代码对由小错字引起的可怕错误敞开大门)

于 2012-10-26T21:51:10.147 回答
0

如果没有结束标记,php 解释器将无法确定脚本的结束位置(因此以解析器错误结束)。

但是随着关闭它,它会将“a”解析为常量。但是没有常量 'a',所以它会认为它是一个字符串,解析器会返回这个字符串值。由于没有变量接收它,它只会被丢弃。(可能解析器只会删除这个 a,因为它不会影响应用程序)。

于 2012-10-26T21:45:45.357 回答
0

我有不同的结果。正如 OP 所说,没有结束标签的代码不会对我造成 500 错误。

<?php
error_reporting(0);
ini_set('display_errors', 0);
echo 'test'; a

相反,我得到:

Parse error: syntax error, unexpected $end in /my-path/test/index.php on line 4

于 2012-10-26T22:02:51.023 回答
0

这是PHP的解析器和语法的粗俗。

PHP 允许您在 T_CLOSE_TAG 之前省略分号,所以当 PHP 解析器看到这个时:

a?>

它假设您的意思是:

a; ?>

然后它将未定义的常量 a强制转换为字符串并发出E_NOTICE. (这是 PHP 的一个可怕的错误特性。)所以这实际上等同于:

'a'; ?>

由于这不是致命错误,并且此表达式没有副作用,因此程序正常执行。

但是,如果省略结束标记,则会出现语法错误,因为没有任何东西表示表达式的结束。语法错误是致命500 Internal Server Error的,响应也是如此。

display_errors设置仅影响错误是否打印到响应中(即,您是否看到noticeparse error消息。)

于 2012-10-26T21:56:01.133 回答