2. A Phing fairy tale
About me
Stephan Hochdörfer
Head of IT at bitExpert AG, Germany
enjoying PHP since 1999
S.Hochdoerfer@bitExpert.de
@shochdoerfer
3. A Phing fairy tale
Disclaimer
Warning:
You will see a hell lot of XML.
53. A Phing fairy tale
Phing – What can it do for me?
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<! correct file permissions >
<chmod file="${project.basedir}/cache"
mode="0777" />
<chmod file="${project.basedir}/uploads"
mode="0777" />
</target>
</project>
54. A Phing fairy tale
Phing – What can it do for me?
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<! create API documentation >
<docblox title="My project"
destdir="apidocs"
template="new_black">
<fileset dir="${project.basedir}/src">
<include name="**/*.php" />
</fileset>
</docblox>
</target>
</project>
55. A Phing fairy tale
Phing – What can it do for me?
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<! minify javascript >
<jsMin targetDir="${project.basedir}/web/">
<fileset dir="${project.basedir}/web/js/">
<include name="**/*.js"/>
</fileset>
</jsMin>
</target>
</project>
56. A Phing fairy tale
Phing – What can it do for me?
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<! exec database migrations >
<liquibaseupdate
jar="/opt/liquibase/liquibase.jar"
classpathref="/opt/liquibase/lib/mysql.jar"
changelogFile="${project.basedir}/diff.xml"
username="liquibase"
password="liquibase"
url="jdbc:mysql://localhost/myproject"/>
</target>
</project>
57. A Phing fairy tale
Phing – Task missing? Use exec...
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<! deploy via rsync to dev server >
<exec
command="rsync vraCz ./ ${deploy.dev.url}"
dir="${project.basedir}"
checkreturn="true" />
</target>
</project>
59. A Phing fairy tale
Properties File - Improved version
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="hello" depends="init">
<echo msg="${Hello}" />
</target>
<target name="init" depends="prop, localprop"
<! some more init logic >
</target>
<target name="prop">
<echo message="Load default build.properties"
<property
file="./build.properties" />
</target>
60. A Phing fairy tale
Properties File - Improved version
<target name="localprop"
if="localprop.exists"
depends="localpropcheck">
<echo message="Loading custom properties!"
<property
file="${project.basedir}/local.properties"
override="true"/>
</target>
<target name="localpropcheck">
<available
file="${project.basedir}/local.properties"
property="localprop.exists" />
</target>
</project>
61. A Phing fairy tale
Enforce Internal Targets
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="init"
description="Property initialization">
<property name="Hello" value="Hello, world!" />
</target>
<target name="hello"
depends="init">
<echo msg="${Hello}" />
</target>
</project>
User can call both targets from command line.
We do not want that.
62. A Phing fairy tale
Enforce Internal Targets
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="init"
description="Property initialization">
<property name="Hello" value="Hello, world!" />
</target>
<target name="hello"
depends="init">
<echo msg="${Hello}" />
</target>
</project>
Prefixing a targets with a „-“ prevents the target
from being called from the command line.
63. A Phing fairy tale
Custom Task (Adhoc definition)
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="init">
<adhoctask name="mytask"><![CDATA[
class MyTask extends Task {
/**
* (nonPHPdoc)
* @see Task::main()
*/
public function main() {
// Custom code here...
}
}
]]></adhoctask>
</target>
<target name="hello"
depends="init">
<mytask />
</target>
</project>
64. A Phing fairy tale
Custom Task (External file)
<?php
require_once 'phing/Task.php';
class MyTask extends Task {
/**
* (nonPHPdoc)
* @see Task::main()
*/
public function main() {
// Custom code here...
}
}
66. A Phing fairy tale
Custom Task with Parameters
<?php
require_once 'phing/Task.php';
class MyTask extends Task {
protected $file;
/**
* @param string $file
*/
public function setFile($file) {
$this>file = $file;
}
/**
* @see Task::main()
*/
public function main() {
// Custom code here...
}
}
67. A Phing fairy tale
Custom Task with Parameters
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="init">
<taskdef
name="mytask"
classpath="${project.basedir}"
classname="MyApp.Common.Phing.MyTask" />
</target>
<target name="hello"
depends="init">
<mytask file="myfile.txt" />
</target>
</project>
68. A Phing fairy tale
Imports for Targets can help structuring
<?xml version="1.0"?>
<project name="myproject" default="app:run">
<!
The following target namespaces exist:
db:* Database specific targets
app:* Application specific tasks
ci:* CI server specific tasks
>
<import file="build/build.db.xml" />
<import file="build/build.app.xml" />
<import file="build/build.ci.xml" />
</project>