What's __halt_compiler in PHP for?
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 outermost 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%
{
}