Search This Blog

5/29/2011

Binary Data at PHP Script

There is a feature in PHP that allows to embed data (including binary data) into PHP scripts and it are not parsed by PHP interpreter. It is diferent from exit instruction, that stops script execution, but does not stop the PHP parser. The feature is provided by "__halt_compiler" instruction, that ignores all data after the point it was called.

Not often this feature is used. Although, it allows:

  • Create self-extractor PHP scripts (a PHP script with attached package of data).
  • Create file that requires authentication to be accessed.
  • Keep meta-information about the PHP script.

The right use of this feature is one script read data after "__halt_compiler" of the same script. To do that, there is a special constant called __COMPILER_HALT_OFFSET__, that keeps the position of the first byte after the __halt_compiler() call.

Let's see an example:

<?php

// Open the file itself to read
$f = fopen(__FILE__, 'r');

// Position the cursor at byte after "__halt_compiler()" + 1
// (+1 because we use a "\n" before start data)
fseek($f, __COMPILER_HALT_OFFSET__ + 1);

// Read all content from cursor to end of file and close it
$data = stream_get_contents($f);
fclose($f);

// Do anything with $data
echo $data;
exit(0);


__halt_compiler();
all this code is ignored
bla bla bla

The syntax of the stretch of code after the __halt_compiler() call will not be evaluated.

The doubt is: why do not we place value in a variable and use it when needed?

The reply is: because sometimes the value is too long, and it is impracticable to put it all in memory (it could exceed memory limit). Using this feature, it is posible to read the data by piece. Also the compiler do not need to parse all data as it should do in a string delimited by quotes.

Other doubt: if I put binary data after the file, how can I edit this file?

Well, you can create a "template script" (generic) only with PHP code, and it might be ended with a __halt_compiler() call. After, you can create the final file appending binary data after the template script and generate a new file. To edit the code, you should edit the template script and recreate the final file.

When doing that, remember that some code editors include a new line at end of file. So, take care of the position of the begining of binary data (the value of __COMPILER_HALT_OFFSET__ constant).

No comments:

Post a Comment