From the manual:
void __halt_compiler ( void )
This function halts the execution of the compiler. This can be useful to embed data in PHP scripts, like the installation files.
Note:
__halt_compiler()
can only be used from the oute开发者_Go百科rmost scope.
Can anyone provide an actually case where this function is useful?
Assume you have one script with some php code and lots and lots of binary clutter.
<?php doStuff(); __halt_compliler(); [BIG_BINARY_MESS]
then you want the compiler to NOT try to parse the binary because if there is <?
somewhere in the binary it would break.
The point is being able to just ship one file with binary data and php code.
For a little example see this blog post
So you want not only to stop the execution
of a script (like exit()
would) but to stop the parsing
so that you can have "invalid syntax" at the end of file and php still can execute the first part.
Another example:
This will get parsed as valid php and execute just fine:
<?php $a = 1; echo $a; __halt_compiler(); §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();
To access the data:
<?php
$file = fopen(__FILE__, 'rb');
// Go to the end of the __halt_compiler();
fseek($file, __COMPILER_HALT_OFFSET__);
echo stream_get_contents($file);
__halt_compiler(); §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();
This will output §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();
Previously, The ClassGenerator in the PhpSpec unit testing library provided a good example of using __halt_compiler()
, which the PHP class contains a code template for a PHP class.
They've recently update to read the template from a seperate file, but initially the getTemplate()
method will attempt to read the PHP code template provided in the file that follows the __halt_compiler()
call. This avoids the <?php
token from getting parsed.
/**
* The Class Generator is responsible for generating the classes from a resource
* in the appropriate folder using the template provided
*/
class ClassGenerator
{
//...
/**
* @return string
*/
protected function getTemplate()
{
return file_get_contents(__FILE__, null, null, __COMPILER_HALT_OFFSET__);
}
}
__halt_compiler();<?php%namespace_block%
class %name%
{
}
Here's another possible use. I have a long file of PHP functions. Many of these aren't currently valid, but might be required soon. I want to disable them, but not entirely delete them. I want the code to remain visible to all developers so that they can reinstate the code if they need it. Also anyone searching via grep would still find the code.
So I move the code to the end of the file, and want to "comment it out". However the functions themselves have comments in. So I would need to start a new block comment after the end of each block comment in the original code. __halt_compiler(); does the job without changing any other lines.
(If I delete the code and commit that to a version control system, that does allow me to reinstate the code, but it wouldn't be visible to other developers unless they new to look.)
精彩评论