Phing: a build system for PHP
Phing (recursive acronym for PHing Is Not GNU make) is a PHP project build system closely modelled on Apache's Ant tool for Java development and implemented in PHP. Phing, like Ant, uses simple XML build files to determine what to do as part of the build process. Why would you need a build system? Certain tasks might need to be performed repeatably during application development (on a large project or a small one). These might include:
- collect files from different folders and assemble them in one folder, optionally renaming them in the process
- automatically check that the code adheres to a coding standard
- extract code from a repository and run unit tests
- change configuration files from development settings to production/staging settings
- generate project documentation from code
- strip comments from production code to make it lighter-weight
- automatically search and replace words or phrases in files
Installing Phing
We can't use Phing unless we actually install it - let's get that over with. You can install in two ways:
- PEAR install
- Non-PEAR install
>
pear channel-discover pear.phing.info
>
pear install phing/phing
Use the '-a' flag if you want to install all dependencies (be careful what you wish for):
>
pear install -a phing/phing
Alternatively, you can download a PEAR package, e.g. phing-2.4.2.tgz, and install using PEAR:
>
pear install phing-2.4.2.tgz
See Getting Phing for more on using the non-PEAR installation.
Running Phing
Phing execution on the command line is very simple - we just need to make sure there is a build file or else Phing will whinge. Just change to the folder where your build file (which should be named build.xml) resides and type:
>
phing
You can use command line arguments to configure Phing - see Phing Fact Sheet for the arguments available. Some of these arguments are shown below:
| Parameter | Meaning | Usage |
|---|---|---|
| -h -help | Display the help screen | phing -h |
| -v -version | Print version information and exit | phing -v |
| -l -list | List all available targets in buildfile | phing -l |
| -D<property>=<value> | Set the property to the specified value to be used in the buildfile | phing -Ddbpass=demo -Ddbuser=demo |
| -buildfile <file> | Specify an alternate buildfile name. Default is build.xml | phing -buildfile "/home/demo/project1/mybuild.xml" |
Anatomy of a build file
A valid Phing build file must be a valid XML document with the following basic structure:
- A root element called <project>. Required
- Several Phing type elements (i.e. <property> , <fileset> , <patternset> etc.). Optional
- One or more <target> elements containing built-in or user defined Phing task elements (i.e. <install> , etc). At least one target element must be defined - the default target as specified in the <project> tag.
Here is an example of a very simple build file is which prints out three statements:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Foo" default="main">
<target name="main" description="The default target" >
<echo msg="Simple project build" />
<echo>command line parameter (dbuser): ${dbuser}</echo>
<echo>command line parameter (dbname): ${dbname}</echo>
</target>
</project>
To execute the build, type this on the command line:
>
phing -buildfile C:\Websites\phingbuild.xml -Ddbuser=userdemo -Ddbname=demo
where C:\Websites\phingbuild.xml is the location of the above build file. The output is something like:

The Phing website gives good examples of an XML build file. Here is a more complex example using filterset, patternset, dependencies, and filterchain:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Foo" default="main">
<property name="builddir" value="C:\Websites\demo\foo\output" override="true"
/>
<!-- Define a fileset -->
<fileset dir="/home" id="foobar">
<!-- include all files within /home/foo and its subdirectories -->
<include name="foo/**" />
<!-- include all files within /home/bar and its subdirectories with extension
php -->
<include name="bar/**/*.php" />
<!-- exclude all files within home/foo/tmp and its subdirectories -->
<exclude name="foo/tmp/**" />
</fileset>
<!-- This is the same as:
<fileset dir="/home" id="foobar"
include name="foo/**"
include name="bar/**/*.php"
exclude name="foo/tmp/**" />
-->
<!-- Implementing a filterset using patternset elements -->
<patternset id="php_code">
<include name="**/*.php" />
<include name="**/*.inc" />
</patternset>
<patternset id="template_code">
<exclude name="**/*.tpl.php" />
</patternset>
<fileset dir="${sourcedir}">
<patternset refid="php_code" />
<patternset refid="template_code" />
</fileset>
<target name="main" description="The default target" depends="setsource">
<echo msg="Build to format code and copy files to destination folder" />
<echo>command line parameter (dbuser): ${dbuser}</echo>
<echo>command line parameter (dbname): ${dbname}</echo>
<copy todir="${builddir}" overwrite="yes">
<fileset refid="foobar" />
<!-- Filter chains enable flexible file transformations like rather Unix's
pipe operator -->
<filterchain>
<stripphpcomments />
<tabtospaces tablength="2" />
<replacetokens>
<!-- Token is key enclosed by @ characters by default e.g. @dbname@ -->
<token key="dbname" value="${dbname}/" />
<token key="dbuser" value="${dbuser}" />
</replacetokens>
</filterchain>
</copy>
</target>
<target name="setsource" description="set the source folder">
<property name="sourcedir" value="C:\Websites\demo\foo\source" override="true"
/>
</target>
<target name="anothertarget" description="A target which will not be
automatically run">
<echo>To run this, command line should be something like: phing
anothertarget</echo>
</target>
</project>
Add new comment