Managing PHP Application Builds with Phing


One of the things I have been focusing on lately is trying to to a better job of mechanizing and automating the process of building and deploying an application.  The reason for this is pretty simple:  applications just seem to keep getting more and more complicated and intricate as time goes on.  This is not a bad thing, but every step or piece that gets added to the process introduces another opportunity for error.  If you think about all of the things you could potentially do to get an application ready for testing or deployment, the list can get long in a hurry.  Here is an example of things you might think about:

  • Are there any fatal errors?
  • Is my code too complex?
  • Do I have an repeated code?
  • Is my Git repo current?
  • Did I remember to put everything into the zip file?
  • Did I clean out the cache & temp files?
  • Did I remember to refresh the API documentation?
  • Are my external libraries up to date?

The list is basically limitless.  The worst part is, most of the list will be riddled with tasks that are not adding value to the application.  As a rule, time that a developer spends that doesn’t add value is time wasted.  Everyone in every segment of every industry seems to always be looking for ways to “do more with less”.  No matter how you feel about the concept, the reality of it is pretty much inescapable.  Personally, I like to spend my development time actually developing, and I lament the idea of doing repetitive tasks to get my apps from my laptop to a production environment.  That’s where Phing comes in…

Phing is a “project build system” that helps developers manage repetitive tasks associated with preparation and deployment of applications.  Phing uses XML based files to allow you the ability to customize the build process to the individual application.  It is very powerful and has a number of built in tasks that will greatly enhance your ability to automate the build process.

Installing Phing

Phing is easy enough to install, especially if you are already set up to use PEAR.  To install Phing via PEAR, simply use the instructions below:

The --alldeps switch is actually pretty important in my opinion.  If you don’t use it, you can easily find yourself frustrated because tasks will not run due to not having the underlying task installed on your computer.  This kind of blows up a crater in the whole “speed things up and make my life easier” concept.  Do yourself a favor and install with all dependencies, you will be glad you did.

Setting Your Project up for Phing

All Phing really needs at the project level is a build file.  Normally, you will want to name this file  build.xml .  This is the default file name that Phing will look for, so in most cases, this is your best bet.  I am kind of psychotic about what files are in the project root, so normally I but the file in a directory called build, but you can absolutely keep it in the root if you wish. From there it is all about customizing the content of the build file to work with your project.  Let’s start with the obligatory header-type information you will need:

The outermost tag is the project tag and all of the other tags like targets and filesets will be contained within it.  I set my project tags up with a name and description, mostly so I can remember better what I am working on later.  The other 2 properties in this tag are “default” and “basedir”.  Default is the name of the target (which I will explain shortly) that phing will run if none is provided, and basedir is the base directory of the project, relative to the location of the build file.  Since my build file is in the “build” directory, my basedir is one level up.

Picking Files for Phing

Next you will want to describe what files Phing should be concerned about when it runs a target and or task.  During the development process, I typically only want to check and work with files that I am modifying, or that are part of the actual application.  I don’t like waiting for the core of the framework to be checked because I am not going to change anything there, so I don’t want to be bothered with anything relating to it.  Using the  fileset tag will allow your to specify what files to deal with, and you can have multiple filesets in a build file.

The fileset above is for a project in CodeIgniter and it starts in the application directory.  I include the directories that will contain PHP files that I will actually be working with.  I also gave the fileset an “id” property so that I can easily reference it by name when running tasks.  For deployment, I would have another fileset called “allFiles” that contains the entire application, but leaves out things like the temp directory, etc.

Managing Tasks and Targets in Phing

A task is just what it sounds like, something that gets done.  A target is like a group of tasks that will get executed together.  In my projects, before I commit & push to Git, there are a few things I want to check for like fatal errors, overly complex functions & classes, and also repeated code.  I find that refactoring as I go is very helpful and keeps me from taking shortcuts.  To do this, I use three Phing tasks wrapped into one target.  The tasks are PHPLint, PHP Mess Detector, and PHP Copy-Paste Detector, and they are set up as follows:

The target is called precheck (which also happens to be my default task).   Now if I run Phing on the project and execute the project, each of these tasks will run, and if there is a fatal error, Phing will stop because I have specified that it should with the “haltonfailure” property.  The output will be similar to the below:

Screen Shot 2013-02-03 at 12.11.19 PM

 

More Functionality

There are other targets I will set up as well to manage other parts of the process more closely related to development and those targets use a variety of Phing tasks.  Here is a list of some of the other tasks that I routinely run, and this is not even close to everything that Phing is capable of.

  • Composer: You can set Phing up to run Composer and keep your dependencies up to date
  • CodeSniffer: Phing will check your code against your specified coding convention
  • Command Line: You can execute command line tasks to clean out temporary files, etc.
  • Zip/Archive: You can create a zip file of the application
  • FTP: You can deploy the app with FTP
  • Git: You can work with the project’s git repo.
  • Unit Testing: Phing will work with PHPUnit
  • Documentation: Phing will call ApiGen or PHPDocumentor to build documentation
  • Versioning:  You can event set up Phing to prompt you for what kind of release you are building (Major, Minor, Bugfix) and it will update a text file with your current version number, and make that number available to other Phing tasks like ApiGen for example.  Actually that one is pretty cool, so an example of how to do it is below:

I counted nearly 120 documented tasks in the Phing user guide, not to mention that you can create your own through customization.  These tasks cover just about everything you can think of.  Phing really does a fantastic job of helping developers automate the build process, and with the depth of its out of the box functionality, most of us are only going to be limited by our imagination.  I highly recommend it to any developer looking to save time and make sure that every step of the build is properly executed every time.   As long as this article has been, it really only scratches the surface of Phing, and the more you use it, the more you will want to use it.

Happy Coding

Andy

 

, , ,

  1. No comments yet.

Comments are closed.