Posts Tagged ‘ PHP

A mini adventure with phing

I am a PHP developer by trade and work on some pretty big project from day to day. We have found that Phing is an invaluable tool for handling the complexities of deployment. Phing is a re-implementation of Java’s Ant build system in PHP. For a PHP developer this has the advantage of allowing us to extend and expand it’s functionality in the same language we are using to build the application in the first place.

This isn’t an introduction to Phing. What I actually want to talk about today is minification of your sites JavaScript and CSS.  Minfication (or sometimes simply minify) is the process of removing unnecessary characters from source code to reduce it’s size but not it’s functionality.

Some would consider minifying JavaScript and CSS a micro-optimization and not somehing to worry about too much. However, if you have a JavaScript heavy website or one with large, and complex CSS it can be a small step to make your vistors experience a little more snappy.  You should of course ensure that you JavaScript and set up to be cached for long periods of time to ensure that the visitor doesn’t have to download it every time the visit your website.

Minification does have its diadvantages, especially during development. By removing all the unnecessary characters you are essentually removing all that nice formatting and commenting (…you do comment all you code don’t you?) you have in place to make maintenance and debugging easier.  So ideally you only want to perform the minification as the last step before deployment.

So, back to Phing. Phing has a number of built in filter tasks that allow you to do things like token replacement, convert tabs to spaces, and strip PHP comments. What’s so nice about Phing is that you can adding your own custom tasks and filters.

As part of our on-going push to simplify and automate all our deployments I have put together a couple of customer Phing filters to perform on the fly minification of JavaScript and CSS.   These can be easily included as part of your Phing deployment targets to minify JavaScript and CSS during deployment. Basically, you no need to think about it anymore. It just happens automatically.

You will find attached to this article a zip file containing the code and an example build script to show you how it all fits together. Phing filters are applied during file operation such as copying. For example:

<copy todir="to">
   <filterchain>
      <filterreader classname="filter.JSMinFilter" />
   </filterchain>
   <fileset dir="from">
      <include name="**/*.js" />
   </fileset>
</copy>

The snippet of xml above shows you how you can use the JSMinFilter as part of a file copy process. It will pick up all .js files in the ‘from’ directory and copy them to the ‘to’ directory, minifying them on the way through. The CssMinFilter works in exactly the same way with CSS files.

The CssMinFilter uses some simply string replacement and regular expressions to achieve the minification. The JsMinFilter uses a PHP implementation of Douglas Crockford’s excellent JSMin, which is included in the JsMinFilter file.

To run the examples yourself you will need to first install Phing (pear install phing) if you haven’t got it installed already. Next unzip the filters.zip file attached to this article and open the command prompt in the unzipped folder.

Then simply run:

phing

This will run the default build target in the build.xml file and will minify the example JavaScript, and CSS files in the ‘from’ directory. You can see the results by looking at the files in the ‘to’ directory.

I hope you can see that by using a couple of simply custom Phing filters you can easily continue developing normally, with plenty of comments and white space to make development easy and still reap the benefits of minification without even having to think about it.

Filters example file: filters.zip

A Galaxy Phar, Phar Away

One of the new features of PHP 5.3 that hasn’t got a whole lot of attention is the inclusion of the Phar extension in the main distribution. Phar files are to PHP what Jar files are to Java. Basically they allow you to package up php into a single archive.

What many of you may not know is that the Phar file format has actually been around for quite some time.  It started out as a PEAR package called PHP_Archive and was re-implemented as a PECL extension some time ago and works with PHP versions earlier than 5.3. You just need to install it with PECL.

There have been a number of articles explaining how you can package up entire application into a Phar file and run you site from it.  This is a great idea but does not seem to have attracted much attention.  What I have been looking at recently does go quite that far. Instead of packaging entire application in a Phar file, I have been looking at treating phar files like libraries, or shared objects.

The Phar file format also allows you to specify a stub. The stub is run automatically when the phar file is included in your php script.

This actually gives you a really powerful mechanism for creating libraries.  All you code can sit in the library and any setup needed can be performed by the stub.

As part of my development of the Morph library I have been working on that provides a simple way to use MongoDB with PHP I have a process that builds a phar file of the library.  Morph is designed to work best with an autoloader that translates class names into file paths. To make it super easy I have put together a stub file for the archive that provides and registers the autoloader.

The autoloader is actually dead easy:

class MorphAutoloader {
   private static $classes = array(
      'ClassName' => 'phar://path/within/phar/ClassName.php'
   );
   public static function load($className) {
      $isLoaded = false;
      if (isset(self::$classes[$className])) {
         include self::$classes[$className];
         $isLoaded = true;
      }
      return $isLoaded;
   }
}
spl_autoload_register(array('MorphAutoloader', 'load'));
__HALT_COMPILER();

The Phar::mapPhar() function call at the begining tell php ‘Hey, your in a phar file’, PHP will then go away and read the manifest of the Phar file so it knows what is in it.  I use of spl_autoload_register() rather than just defining a function call __autoload as it actually allow the registering of multiple autoloaders. This means that the library autoloader does not interfere with any defined in the application itself.

Finally, the call to __HALT_COMPILER() is a requirement of the Phar file stub and should appear as the very last line of your stub file.

Then all you project needs to do is include the Phar file. Everything else is a taken care of by the phar file itself. Think how much easier managing upgrades becomes when all you have to do is replace one file.

—-

Moose