__halt_compiler()
In this article, we will focus on the PHP __halt_compiler() function. We will provide you with an overview of the function, how it works, and examples of its
In this article, we will focus on the PHP __halt_compiler() language construct. We will provide you with an overview of the construct, how it works, and examples of its use.
Introduction to the __halt_compiler() construct
The __halt_compiler() language construct is a unique and powerful feature of PHP. It allows you to embed data directly into your PHP code. This data can be anything, including text, binary data, or even an entire script.
When the PHP interpreter encounters the __halt_compiler() construct in your code, it halts the PHP parser and treats everything after the call as raw data. This means that you can embed any type of data into your code and access it later as a string or binary data.
__halt_compiler() is a language construct, not a regular function, so you call it without arguments and it does not return a value. It is most often used to build single-file tools where code and data ship together — for example self-extracting archives (PHP's PHAR format uses exactly this technique) or installers that carry their own payload.
How to use the __halt_compiler() construct
The __halt_compiler() construct is very easy to use. Simply call it in your PHP code, followed by the data that you want to embed. Here is an example:
How to use the __halt_compiler() construct?
In this example, we have a simple PHP script that prints out some text using the echo construct. We then call the __halt_compiler() construct and embed some raw data after it. When the PHP interpreter encounters the __halt_compiler() construct, it halts the parser and treats everything after it as raw data.
Accessing the embedded data with __COMPILER_HALT_OFFSET__
When a file contains __halt_compiler(), PHP defines a special constant, __COMPILER_HALT_OFFSET__, that holds the byte position of the first character after the call. This is the canonical, fastest way to read the embedded payload from within the same file — you don't have to search the file for a marker yourself.
Reading embedded data from the same file
<?php
// File: bundle.php
echo "Reading the embedded payload...\n";
// Open this very file and jump straight to the data.
$fp = fopen(__FILE__, 'rb');
fseek($fp, __COMPILER_HALT_OFFSET__);
$data = stream_get_contents($fp);
fclose($fp);
echo $data;
__halt_compiler();
Hello from the embedded data!Here __COMPILER_HALT_OFFSET__ points at the byte right after __halt_compiler();, so we seek to it and read everything that follows as the raw payload. The constant only exists in a file that actually contains the construct.
Accessing the embedded data from another file
If you need to read the payload from a different file, that file's __COMPILER_HALT_OFFSET__ is not available to you, so you locate the marker manually with strpos() and slice the data out with substr() after loading it via file_get_contents().
Here is an example of how to read the embedded data from a separate script:
Accessing the embedded data in PHP
<?php
// File: embed.php
echo "This is some PHP code.";
__halt_compiler();
This is some raw data.
?><?php
// File: extract.php
// Read the script file and extract the data
$content = file_get_contents('embed.php');
$pos = strpos($content, '__halt_compiler();');
if ($pos !== false) {
$offset = $pos + strlen('__halt_compiler();');
$data = substr($content, $offset);
echo $data;
}
?>In this example, we first create a file with embedded data. We then use a separate script to read the original file and extract the data by locating the __halt_compiler(); marker and calculating the offset. Finally, we print out the extracted data using the echo construct.
Note: The __COMPILER_HALT_OFFSET__ constant is only defined inside the file that actually contains __halt_compiler(). When reading a different file, strpos() returns false if the marker is missing, so always verify the position with a !== false check before computing the offset.
Restrictions and gotchas
Keep these rules in mind when using __halt_compiler():
- It must be called at the top level of a file. You cannot place it inside a function, method, conditional, loop, or any other block. Doing so is a fatal error.
- One per file. A file can contain
__halt_compiler()only once — it marks a single cut-off point. - Everything after it is ignored as code. The closing
?>tag (if present) and anything past the call are treated as raw bytes, never parsed. Because of this you usually omit the trailing?>and just let the data follow. - It is not a function. You can't take its address, pass it as a callback, or call it dynamically.
Conclusion
In conclusion, the __halt_compiler() language construct is a powerful and flexible feature of PHP that allows you to embed data directly into your code. By understanding how the construct works and how to access the embedded data, you can take advantage of this feature to create more powerful and flexible PHP scripts. Common practical use cases include self-extracting archives, bundling static assets (like CSS or JavaScript) with PHP logic, and creating single-file PHP applications. If you mainly need to pull in code from other files rather than embed raw data, see include instead.