Deploying a PHP project to a production or even a staging environment isn’t always as simple as copying a directory. One project I have been working on recently has benefited from using Phing as a deployment system. To deploy my code, I just have to call a single build script, and let Phing do all the hard work.
So what is Phing? Well Phing is a tool based on Apache Ant, specifically designed to build PHP projects. It takes an XML file that defines specific tasks and executes them. It is designed to be platform independent so should be at home running on Windows as well as Unix based systems.
Phing is available using PEAR, and can be installed quickly using the following commands…
pear channel-discover pear.phing.info pear install phing/phing
Hello World! In Phing
It wouldn’t be an overview without a Hello World example. Save the following as build.xml.
Now let’s run this, we just call phing
on the command line, and we get something like this back.
rob@lamp /tmp/helloworld> phing Buildfile: /tmp/helloworld/build.xml helloworld > helloworld: [echo] Hello World! BUILD FINISHED Total time: 0.0487 seconds rob@lamp /tmp/helloworld>
So what is going on? Well in the project
element we have a default setting of “helloworld”. This tells Phing the target to call by default. We can call this on the command line as well, phing helloworld
, so if we have multiple tasks we can create a target for each of those. As you can see we only have a target of “helloworld” in our example. Inside the target we have tasks. In this example, we have a single EchoTask that just prints out the message “Hello World!”.
Adding A Clean Up
There is so much more Phing can do that just print Hello World!. One of the common tasks you may have is to cleanup a deployment directory. Let’s assume you have a build directory, when you call phing clean
you want this to be removed. We can add a simple task to do this to our build.xml.
As you can see, as well as adding a target called “clean”, I’ve also added a property called “builddir” with the value “./build”. I can access this later as variable, so when I call the DeleteTask, I can reference this value using ${builddir}
, and Phing will delete the directory ./build.
Create an empty directory called build and run this using phing clean
.
rob@lamp /tmp/helloworld> phing clean Buildfile: /tmp/helloworld/build.xml helloworld > clean: [echo] Clean... BUILD FINISHED Total time: 0.0493 seconds rob@lamp /tmp/helloworld>
When you check the contents of your working directory you should have found the build directory has been deleted.
Adding A Deployment Target
Deployment is the area where Phing really comes into it’s own. Let’s create a target that creates a build directory then uploads the contents of that via FTP to a remote server.
We’re doing a few things here, first we are deleting the ${builddir}, and creating it from scratch to ensure it is clean. Then we are copying all the files in the current directory across, except for the build directory, any build file with any extension, the docs directory and the tests directory. Then we are FTP’ing up the contents of the ${builddir} using a FTPDeployTask. Assume I have already set a selection of FTP variables earlier using the same syntax as earlier when I defined ${builddir}.
OK, so that is useful, but there are other useful things that could be done as part of the process. We may want our JavaScript minified on production, but not when we are developing. We can add a task to do this as part of the deploy using the JSMinTask.
There are plenty of other tasks that can be usefully integrated, such as running phpcs
to ensure your code is meeting coding standards, building your documentation using phpdocumentor
, running your phpunit
unit tests. If anything fails you can prevent the deployment and stop your site breaking unnecessarily.
Summary
This has just been a quick overview of how to use Phing. We’ve seen various simple tasks take place, and we’ve seen we can easily add more tasks to increase functionality and usefulness. In the real world adding tests to check your code before it gets deployed is essential and prevents silly errors hitting your production environment. Taking the time to write a build script will also save you time in the future when you come to make changes to your site and you can’t quite remember how your production environment was setup. Using Phing, you just have to run your build script.