Programming
Article

__halt_compiler() – how nuts?

By Harry Fuecks

Simon blogmarked PHP’s new(ish) __halt_compiler function which, according to the packet;

… halts the execution of the compiler. This can be useful to embed data in PHP scripts, like the installation files. Byte position of the data start can be determined by the __COMPILER_HALT_OFFSET__ constant which is defined only if there is a __halt_compiler() presented in the file.

It may or may not be an elegant solution (it’s certainly relatively simple) but it does have a very valid use case – to allow PHP applications which install themselves from a single script, all related pieces (other PHP scripts, CSS, HTML, images, etc.) being packed at the end of the script in a binary form.

The prime example is Ilia’s fudforum – if you download a recent version, you’ll see it makes use of this – simply run the install.php script an it unpacks everything from there. Greg mentioned __halt_compiler as well a while back, in conjunction with all the stuff he’s been doing on phar archives.

Anyway – personally don’t find it so nuts. And consider the opportunities for building job security ;)

Otherwise noticed Sara Golemon has a book coming on writing PHP extensions – much needed. Also a related note Bruce Eckel has published a free seminar in this “Thinking in ” series – Thinking in C.

  • http://simon.incutio.com/ Skunk

    Nope, it’s definitely nuts. If you want to stash binary data in a PHP install file you can always base64 encode it and whack it in a heredoc.

  • http://simon.incutio.com/ Skunk

    OK, so from Greg’s post I see that the main concern is compressing the data and keeping the file size down. Still think it’s nuts though!

  • Greg Beaver

    see http://pear.php.net/install-pear-nozlib.phar

    If you have uncompressed data, the parser will die if it encounters duplicate classes (as it should). As such, you can’t include a tarball for PEAR and use PEAR to install it without __HALT_COMPILER();

    Hardly nuts.

    base64decode() is also noticeably slower. running install-pear-nozlib.phar is literally just as fast as running the install-pear.php that it is based on, and this is with tons of code. Definitely a good thing.

  • Sara Golemon

    Not nuts.

    __halt_compiler does exactly what it says, it HALTS the compiler, which means that it doesn’t have to load the entire contents of the file into memory.

    Non script data (e.g. inline HTML) is duped and droped into a ZEND_ECHO op so that it can be displayed when script execution reaches that point. If your script simply issues a die/exit, then you’ve copied that stuff into memory for NO REASON. Now apply this to a multi-megabyte script designed to be run in place (rather than executed once at the command line. Feeling wasteful yet?

    Add in the fact that that __halt_compiler will populated a magic constant with the boundary of where your code stops and your data begins and suddenly you’re saving the cost of having to look for that delimiter the hard (read: slow, memory expensive) way.

    P.S. – No ‘a’ in my last name, ‘kay thanks.

  • http://www.phppatterns.com HarryF

    P.S.—No ‘a’ in my last name, ‘kay thanks

    Whoops – fixed. Got it right last time – 1 in 2 hit rate.

  • chrisb

    Ok, I really don’t see the point of this? Granted, I’m not coming from a php background, but I can’t see much benefit from the examples you’ve provided? Is it meant to facilitate an equivalent of embedded resources or just as some strange way to install stuff?

  • http://www.phppatterns.com HarryF

    Ok, I really don’t see the point of this? Granted, I’m not coming from a php background, but I can’t see much benefit from the examples you’ve provided?
    Is it meant to facilitate an equivalent of embedded resources or just as some strange way to install stuff?

    Answering the last question first, this enables both – you can embed resources this way which in turn, enables stuff like building installers.

    As to the point – specific to installers, in general the mission is to make life easy for end users of PHP applications and (arguable) to discourage them from doing silly things with your code (fudforum is the case in point there).

    When it comes to installing a PHP application, perhaps the trickiest issue for many is setting up PHP’s include paths correctly. For people writing applications, the easiest approach, to prevent giving users headaches, is to use relative paths so people can just “unzip and go”. Unfortunately that typically means dropping a bunch of code below the document root which really shouldn’t be there (for security), in particular config files. The other issue with the “unzip and go” approach is you don’t tend to run into problems (like missing extensions) until your application is actually running. An installer can check the environment for requirements in advance.

    Arguably fudforum’s installer takes things a step further in that it handles stuff like setting filesystem permissions and, in effect, actively discourages hacking. Depending on your point of view, that can be a very good thing (you know pretty much what a user has installed).

    Anyway – this helps in building “self installing” PHP scripts.

  • Ren

    Could see a use for digitally signing scripts too.

  • chrisb

    Cheers Harry, makes a bit more sense now… Spoilt by .net it seems ;)

  • http://blog.ianbicking.org ianbicking

    I think what’s nuts is that this is definitely not a function. This is a set of *tokens* that halts the compiler — the “__halt_compiler” token followed by a “(” token and a “)” token. It’s a reasonable bit of functionality, but it’s also yet another case of PHP being sloppy about language definition and terminology.

  • http://www.phppatterns.com HarryF

    I think what’s nuts is that this is definitely not a function. This is a set of *tokens* that halts the compiler—the “__halt_compiler” token followed by a “(” token and a “)” token. It’s a reasonable bit of functionality, but it’s also yet another case of PHP being sloppy about language definition and terminology.

    That’s a fair point (evidence here).

    Could see a use for digitally signing scripts too.

    Really good idea!

  • dreamscape

    The only thing bad about self installing PHP web scripts is that usually you’re web root & application root will have to have world-writeable permissions in order for PHP to write the files, and then once they are written, they will usually be owned by “apache”, “nobody”, or “www”, so you [your account user] won’t be able to do shit with them unless PHP sets the permissions on the new files & folders as world-writable.

    The only ways to avoid that is to run PHP as your user, which means either banking on the very slim chance that all your users are running PHPSuExec or similar, or making the self-installing script a PHP shell script instead of a web script and have users run it from command line, which again banks on the chance that users will have SSH access (which is a fair bet, but still not everyone does).

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Front-end, once a week, for free.