此函数可以在 eval() 中使用 - 它将停止 eval,但不会停止调用 eval"() 的脚本。
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
__halt_compiler — 停止编译器执行
停止编译器的执行。这对于在 PHP 脚本中嵌入数据(如安装文件)非常有用。
数据的起始字节位置可以通过 __halt_compiler() 出现的文件中定义的 __COMPILER_HALT_OFFSET__
常量确定。
此函数没有参数。
不返回值。
示例 #1 一个 __halt_compiler() 示例
<?php
// 打开此文件
$fp = fopen(__FILE__, 'r');
// 将文件指针定位到数据
fseek($fp, __COMPILER_HALT_OFFSET__);
// 并输出它
var_dump(stream_get_contents($fp));
// 脚本执行结束
__halt_compiler(); 安装数据 (例如. tar, gz, PHP, 等等.)
注意:
__halt_compiler() 只能在最外层作用域使用。
__halt_compiler 也对调试很有用。如果您需要暂时进行会导致以后出现错误的更改,请使用 __halt_compiler 来防止语法错误。例如
<?php
if ( $something ):
print 'something';
endif; // endif 放在这里是为了调试目的
__halt_compiler();
endif; // endif 的原始位置 - 如果没有 __halt_compiler,会产生语法错误
?>
如果 "__halt_compiler();" 出现在一个被 "include" 或 "require" 的文件中,那么被调用的文件将被视为在 "__halt_compiler();" 处物理切断。换句话说,"__halt_compiler();" 只会影响它所在的物理文件,而拉入它的外部文件将继续执行。
Joey,你说 __halt_compiler 有奇怪的行为,这是错误的。此结构的工作方式与其他内置结构(如 empty 或 isset)完全相同(即使与函数相似;至少在词法分析器级别)。
关于 T_OPEN_TAG - 在出现一个开放标签后,您不希望在当前的 PHP 代码部分中出现其他标签,因此词法分析器尝试以其他方式处理此“东西”,这是完全正常的...
请注意,如果从 pharstub 中使用,__HALT_COMPILER() 必须是大写的:https://php.net/manual/en/phar.fileformat.stub.php
我不完全了解 PHP 内部是如何工作的,但我无法理解 token_get_all 中处理 __halt_compiler 的合理性。
这实际上在那里有效
__halt_compiler/**/ /**/ /**/ /**/ /** */();raw
通常它会弹出任何三个标记,所以您甚至可以在 token _get all 中使用 __halt_compiler***、__halt_compiler))) 等等。
奇怪的是,它也会跳过 T_OPEN_TAG,但在 __halt_compiler 运行的上下文中,此标签是不可能的。相反,它会将 < 和 ? 作为运算符,并将 php 作为 T_STRING 拾取。
它会在任何时候忽略标记,因此这也有效
__halt_compiler()/**/ /**/ /**/ /**/ /** */;raw
当我使用 PHP 文件而不是词法分析器测试它时,它的工作方式相同。
我只能得出结论,PHP/__halt_compiler 非常奇怪。
我认为这是试图弱模仿函数中相同的语法处理(我想您可以在任何地方放置注释/空格)。但我发现它很烦人,而且适得其反。
即使这样也有效
__halt_compiler// comment\n();raw
一个加剧问题的一般问题是,词法分析器不会检查语法是否有效(标记彼此)。当以 PHP 运行时,您必须有 ();。
如果您发现 __COMPILER_HALT_OFFSET__ 的值非常奇怪。也许...
有一些编译器优化工具,如 eAccelator(非常旧)。当程序被预编译并缓存时,__COMPILER_HALT_OFFSET__ 将为 0 = =