What is Phing (PHP build tool) used for?

in

Think of phing as bash scripting with xml. It allows us to do things like:

  1. Make a directory
  2. Give it x permissions
  3. Copy some files into it

Instead of us using bash to script all these, we can use phing. Phing allows us to script all of these tasks using xml. Phing is based off a more popular tool (which if i’m honest I prefer) called Apache Ant.

Here’s a very basic example of a Phing build script.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Every project starts with a project node -->
<!-- the `default` property specifies which `target` will be run if none specified via CLI -->
<project name="YourProjectName" default="dist">

    <!-- ============================================  -->
    <!-- Target: prepare                               -->
    <!-- ============================================  -->
    <target name="prepare">
        <!-- Make a build directory in the current dir `.` -->
        <echo msg="Making directory ./build" />
        <mkdir dir="./build" />
    </target>

    <!-- ============================================  -->
    <!-- Target: build - Dependant on `prepare`        -->
    <!-- ============================================  -->
    <target name="build" depends="prepare">
        <!-- Create our file - (we dont have to do this   -->
        <!-- the echo below creates it if it don't exist) -->
        <!-- It's here as a simple example                -->
        <echo msg="Making new README.txt file in build directory..." />
        <touch file="./build/README.txt" millis="102134111" />
    </target>

    <!-- ============================================  -->
    <!-- (DEFAULT) Target: dist - Dependant on `build` -->
    <!-- ============================================  -->
    <target name="dist" depends="build">
        <echo msg="Writing text to the file README.txt..." />
        <echo file="./build/README.txt" append="false">Writing this msg to README.txt</echo>
    </target>

</project>

So what’s happening?

It’s very simple, we first define our <project> node which defines the name (optional) and the default value (required).

<project name="YourProjectName" default="dist">

Within that we have targets which are nodes of commands (think of them as functions). Each target will have specific Tasks which can do things for you. In this example, we make a directory (./build), create a new file within it using the TouchTask, and then write to the file using the EchoTask.

<target name="prepare">
    <echo msg="Making directory ./build" />
    <mkdir dir="./build" />
</target>

<target name="build" depends="prepare">
    <echo msg="Making new README.txt file in build directory..." />
    <touch file="./build/README.txt" millis="102134111" />
</target>

There are loads of Tasks available for Phing, you can even write your own. Targets can be dependent on other targets using the depends property, in the above example the default dist is dependent on build which is dependent on prepare. So it would execute prepare, build, dist.

Phing is what we’ll use to run all the programs I describe in the following post Setup Jenkins with PHP, Phing, Symfony & PHPUnit. We’ll setup everything using xml (like above) and have Jenkins execute them all for us & save the output to a directory, Jenkins will then parse that output and if everything was OK, we have successful build. If there was an error, we will see it in the Console Output tab within the build properties after the build has finished executing.