Jan 22, 2012

Packaging the Yii framework as an archive

With PHP 5.3 came the new phar extension, which allows you to package scripts and other files into an archive, and enables you to run scripts or serve documents from that archive.

I've built several applications on the Yii Framework, my personal PHP framework of choice. Deploying most frameworks, with dozens of megabytes and typically several thousand files, has a tendency to dwarf the actual application somewhat. Checking 1700 files into subversion can be a real chore. (and God forbid you ever have to update the framework.)

I've been thinking for a while how it would be nice if you could check-in the framework as a single file - using a phar archive, that is now possible, and I decided to try it on an existing application I built on Yii, which needed a framework upgrade anyhow.

Archiving Yii

First things first, I had to get the Yii Framework codebase into phar archive format - so I went ahead and wrote a script, which you can drop into a Yii framework folder and run from a command-line.

The documentation for the phar extension completely fails to mention the command-line utility, which comes with the PHP distribution, which does something very similar. (You may not need my script, which doesn't really do anything Yii-specific at the moment.)

Bootstrapping the Yii archive

Assuming you ran my script, you now have a file with a name like "yii-1.1.9.r3527.phar", containing the just over 1,700 files, neatly packaged and ready to ship.

Eager to prove my point, I went ahead and deleted my Yii folder at this point, placing the new phar archive in my application's "protected" folder. Bootstrapping your application to run the packaged Yii framework is easy - in your dispatch script ("index.php") add the following at the top:
new Phar('./protected/yii-1.1.9.r3527.phar');
This makes the Yii framework available through the phar stream-wrapper - configure the path to the Yii framework root folder as follows:
"phar://yii"
And you're good to go - anything under this path will address files in the Yii framework package, which will be unpacked as needed, on the fly.

CAssetManager

I did run into one little problem with CAssetManager, which was built with the assumption that the framework's built-in assets (jQuery, etc.) are stored as physical files on the local filesystem.

Fortunately, this was relatively painless to fix - I submitted a patch for this issue, which you should apply if you're going to attempt this.

Performance Considerations

You'll find some posts around the net from early after the PHP 5.3 release, claiming that phar archives slow down your applications. Not so - perhaps surprisingly, running a framework like Yii (with a bytecode cache, such as APC) from a phar archive, is actually slightly faster than running from flat files!

The bytecode cache normally has to check the modification-time of every script when retrieving from the cache - and because there is only one physical file (the archive) that needs to be checked, most of this file-system overhead goes away.

Conclusion

I can't guarantee that there aren't any other incompatibilities - although I am already using this solution in production, on a fairly large Yii-based application, which is currently running smoothly.

If you run into any other problems, please submit a comment below.

Update

I recently forked the Yii-framework on Github and implemented a shell-command that lets you package the Yii-framework as a Phar-archive:

https://github.com/mindplay-dk/yii

No comments:

Post a Comment

Post a Comment