SlideShare a Scribd company logo
Phing for power users
Stephan Hochdörfer, bitExpert AG
Phing for power users
About me
 Stephan Hochdörfer
 Head of IT at bitExpert AG, Germany
 enjoying PHP since 1999
 S.Hochdoerfer@bitExpert.de
 @shochdoerfer
Phing for power users
I used to be an Ant fanboy...
What is Phing?
Phing for power users
What is Phing?
Phing for power users
It is a PHP project build system or
build tool based on Apache Ant.
What is Phing?
Phing for power users
Domain Specific Language
for an project build system.
Phing for power users
A build system for PHP code? Srsly?
Glue for all 3rd party tools
Phing for power users
How to install Phing?
Phing for power users
$> pear channel­discover pear.phing.info
$> pear install phing/phing
How to install Phing? The PEAR way...
Phing for power users
Installing Phing
$> phing ­v
Phing 2.5.0
$> pear channel­discover pear.phing.info
$> pear install phing/phing
How to install Phing? The PEAR way...
Phing for power users
Installing Phing
Running Phing:
How to install Phing?
Phing for power users
Installing Phing globally? WTF?!?
How to install Phing?
Phing for power users
Phing is „just another“
dependency for your project.
How to install Phing? The Composer way...
Phing for power users
{
"require": {
"phing/phing": "2.5.0"
}
}
How to install Phing? The Composer way...
Phing for power users
composer.json:
{
"require": {
"phing/phing": "2.5.0"
}
}
$> php composer.phar install
Loading composer repositories with package information
Installing dependencies
  ­ Installing phing/phing (2.5.0)
    Downloading: 100%         
Writing lock file
Generating autoload files
How to install Phing? The Composer way...
Phing for power users
composer.json:
Running Composer:
How to install Phing? The Composer way...
Phing for power users
/tmp/myproject
   |­vendor
   |­­­bin
   |­­­­­@phing
   |­­­composer
   |­­­phing
   |­­­­­phing
   |­­­­­­­bin
   |­­­­­­­­­phing
   |­­­­­­­build
   |­­­­­­­classes
   |­­­­­­­docs
   |­­­­­­­etc
   |­­­­­­­test
How to install Phing? The Composer way...
Phing for power users
/tmp/myproject
   |­vendor
   |­­­bin
   |­­­­­@phing
   |­­­composer
   |­­­phing
   |­­­­­phing
   |­­­­­­­bin
   |­­­­­­­­­phing
   |­­­­­­­build
   |­­­­­­­classes
   |­­­­­­­docs
   |­­­­­­­etc
   |­­­­­­­test
$> ./vendor/bin/phing ­v
Phing 2.5.0
Running Phing:
Phing Basics
Phing for power users
Phing Basics
Phing for power users
Project, Target, Task, Properties
Phing Basics: Project
Phing for power users
Root node of a build file
containing one or more targets.
Phing Basics: Target
Phing for power users
A group of tasks that
run as an entity.
Phing Basics: Task
Phing for power users
Custom piece of code to
perform a specific function.
Phing Basics: Properties
Phing for power users
Properties (variables) help to
customize execution.
Phing Basics: Built-In Properties
Phing for power users
e.g. host.os, line.separator,
phing.version, php.version, …
<?xml version="1.0"?>
<project name="myproject" default="init">
<target name="init">
<!­­ insert logic here ­­>
</target>
</project>
Phing Basics: Sample Build File
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="hello" 
description="Says Hello, world!">
 <echo msg="Hello, world!" />
</target>
</project>
Build File – Hello World example
Phing for power users
Why Phing?
Phing for power users
Runs everywhere where PHP runs.
Why Phing?
Phing for power users
No additional depencendies needed
(e.g. Java, …).
Why Phing?
Phing for power users
More than 120 predefined
tasks to choose from.
Why Phing?
Phing for power users
Easy to extend by writing
custom tasks in PHP.
Enforce Internal Targets
Phing for power users
Enforce Internal Targets
Phing for power users
<?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>
Enforce Internal Targets
Phing for power users
$> ./vendor/bin/phing -f build.xml hello
/tmp/myproject/build.xml
myproject > init:
myproject > hello:
[echo] Hello, world!
BUILD FINISHED
Total time: 0.0474 seconds
Enforce Internal Targets
Phing for power users
$> ./vendor/bin/phing -f build.xml init
/tmp/myproject/build.xml
myproject > init:
BUILD FINISHED
Total time: 0.0476 seconds
Enforce Internal Targets
Phing for power users
$> ./vendor/bin/phing -l
Buildfile: /tmp/myproject/build.xml
Default target:
---------------------------------------------------------
hello
Main targets:
---------------------------------------------------------
init Property initialization
Subtargets:
---------------------------------------------------------
hello
Enforce Internal Targets
Phing for power users
Internal targets are just helpers
like private methods.
<?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>
Enforce Internal Targets – The solution
Phing for power users
Enforce Internal Targets – The solution
Phing for power users
$> ./vendor/bin/phing -f build.xml -init
Unknown argument: -init
phing [options] [target [target2 [target3] ...]]
Options:
-h -help print this message
-l -list list available targets
-v -version print the version information
-q -quiet be extra quiet
-verbose be extra verbose
-debug print debugging information
Report bugs to <dev@phing.tigris.org>
Enforce Internal Targets – The solution
Phing for power users
Are the targets really hidden?
Enforce Internal Targets
Phing for power users
$> ./vendor/bin/phing -l
Buildfile: /tmp/myproject/build.xml
Default target:
---------------------------------------------------------
hello
Main targets:
---------------------------------------------------------
-init Property initialization
Subtargets:
---------------------------------------------------------
hello
Enforce Internal Targets
Phing for power users
$> ./vendor/bin/phing -l
Buildfile: /tmp/myproject/build.xml
Default target:
---------------------------------------------------------
hello
Main targets:
---------------------------------------------------------
-init Property initialization
Subtargets:
---------------------------------------------------------
hello
Enforce Internal Targets (Improved Version)
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="-init"
hidden="true"
description="Property initialization">
<property name="Hello" value="Hello, world!" />
</target>
<target name="hello"
depends="-init">
<echo msg="${Hello}" />
</target>
</project>
$> ./vendor/bin/phing -l
Buildfile: /tmp/myproject/build.xml
Default target:
---------------------------------------------------------
hello
Subtargets:
---------------------------------------------------------
hello
Enforce Internal Targets (Improved Version)
Phing for power users
Custom Tasks
Phing for power users
Custom Tasks
Phing for power users
Phing can do way more
than simple exec calls!
Custom Task (Adhoc definition)
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="init">
<adhoc-task name="mytask"><![CDATA[
class MyTask extends Task {
/**
* (non-PHPdoc)
* @see Task::main()
*/
public function main() {
// Custom code here...
}
}
]]></adhoc-task>
</target>
<target name="hello"
depends="init">
<mytask />
</target>
</project>
<?php
require_once 'phing/Task.php';
class MyTask extends Task {
/**
* (non-PHPdoc)
* @see Task::main()
*/
public function main() {
// Custom code here...
}
}
Custom Task (External file)
Phing for power users
<?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 />
</target>
</project>
Custom Task (External file)
Phing for power users
<?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...
}
}
Custom Task with Parameters
Phing for power users
<?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>
Custom Task with Parameters
Phing for power users
Properties File
Phing for power users
Properties File
Phing for power users
Use properties to
cutomize build behaviour.
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="hello" 
description="Says whatever you want to say">
<property
file="./build.properties" />
 <echo msg="${Hello}" />
</target>
</project>
Properties File
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="hello" 
description="Says whatever you want to say">
<property
file="./build.properties" />
 <echo msg="${Hello}" />
</target>
</project>
Properties File
Phing for power users
Hello=Hello, world!
build.properties:
Properties File
Phing for power users
$> phing
Buildfile: /tmp/myproject/build.xml
myproject > hello:
[property] Loading /tmp/myproject/build.properties
[echo] Hello, world!
BUILD FINISHED
Total time: 0.0601 seconds
Properties File - Improved version
Phing for power users
Properties File - Improved version
Phing for power users
Requirement: Externalize properties
but offer customization capabilities!
<?xml version="1.0"?>
<project name="myproject" default="hello">
<target name="hello" depends="init">
<echo msg="${Hello}" />
</target>
<target name="init" depends="prop, local-prop">
<!-- some more init logic -->
</target>
<target name="prop">
<echo
message="Loading default build.properties"/>
<property
file="build.properties" />
</target>
Properties File - Improved version
Phing for power users
<target name="local-prop"
if="local-prop.exists"
depends="local-prop-check">
<echo message="Loading custom properties!"/>
<property
file="local.properties"
override="true"/>
</target>
<target name="local-prop-check">
<available
file="local.properties"
property="local-prop.exists" />
</target>
</project>
Properties File - Improved version
Phing for power users
$> phing
Buildfile: /tmp/myproject/build.xml
myproject > prop:
[echo] Loading default build.properties
[property] Loading /tmp/myproject/build.properties
myproject > local-prop-check:
myproject > local-prop:
myproject > init:
myproject > hello:
[echo] Hello, world!
BUILD FINISHED
Total time: 0.1383 seconds
Properties File - Improved version
Phing for power users
$> phing
Buildfile: /tmp/myproject/build.xml
myproject > prop:
[echo] Loading default build.properties
[property] Loading /tmp/myproject/build.properties
myproject > local-prop-check:
myproject > local-prop:
[echo] Loading custom properties!
[property] Loading /tmp/myproject/local.properties
myproject > init:
myproject > hello:
[echo] Hello my world!
BUILD FINISHED
Total time: 0.0493 seconds
Properties File - Improved version
Phing for power users
build.properties example
Phing for power users
phpunit.path=vendor/bin/phpunit
phpunit.junit.log=build/logs/junit.xml
phpunit.coverage.clover=build/logs/clover.xml
phpunit.coverage.html=build/coverage
phpcs.path=vendor/bin/phpcs
phpcs.log=build/logs/checkstyle.xml
sencha.senchaCmd=/user/local/lib/sencha/sencha
sencha.jsb3File=app.jsb3
build.properties example
Phing for power users
Use distinct naming conventions
for your properties.
Accessing application configuration
Phing for power users
Accessing application configuration
Phing for power users
Duplicating configuration code
is a bad habit.
Accessing application configuration
Phing for power users
<?php
require_once 'phing/Task.php';
class ConfigMapperTask extends Task {
/**
* @see Task::main()
*/
public function main() {
// will import $APP_CONF in local context
require_once('src/bootstrap.php');
$project = $this->project;
$project->setProperty(
'db.host', $APP_CONF['db_host']);
$project->setProperty(
'db.database', $APP_CONF['db_database']);
$project->setProperty(
'db.user', $APP_CONF['db_user']);
$project->setProperty(
'db.password', $APP_CONF['db_passwd']);
}
}
Accessing application configuration
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="hello">
<taskdef name="readAppConfig"
classpath="${phing.dir}/src/"
classname="MyApp.Common.Phing.AppConfigTask" />
<target name="init" depends="prop, local-prop">
<readAppConfig />
</target>
<target name="prop">
<echo message="Load default build.properties"/>
<property file="build.properties" />
</target>
<target name="local-prop"
if="local-prop.exists"
depends="local-prop-check">
<!-- […] -->
</project>
Imports for Targets can help structuring
Phing for power users
<?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>
Imports for Targets can help structuring
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="app:run">
<!--
The following target namespaces exist:
lib1:* - Targets imported from lib1
lib2:* - Targets imported from lib2
app:* - Local application targets
-->
<import file="vendor/vendor1/lib1/build/build.xml" />
<import file="vendor/vendor2/lib2/build/build.xml" />
<import file="build/build.app.xml" />
</project>
Import Targets: Composer packages
Phing for power users
Import Targets: Path handling
Phing for power users
Be aware that imports behave
like include in PHP!
<?xml version="1.0"?>
<project name="myproject" default="lib1:run">
<!--
The following target namespaces exist:
lib1:* - Targets imported from lib1
-->
<import file="vendor/lib1/build/build.xml" />
</project>
Import Targets: Path handling
Phing for power users
build.xml
<?xml version="1.0"?>
<project name="lib1" default="lib1:run">
<target name="lib1:run">
<echo msg="Local dir: ${phing.dir.lib1}" />
<echo msg="Global dir: ${phing.dir}" />
</target>
</project>
<?xml version="1.0"?>
<project name="myproject" default="lib1:run">
<!--
The following target namespaces exist:
lib1:* - Targets imported from lib1
-->
<import file="vendor/lib1/build/build.xml" />
</project>
Import Targets: Path handling
Phing for power users
build.xml
vendor/lib1/build/build.xml
$> ./vendor/bin/phing
Buildfile: /tmp/myproject/build.xml
myproject > lib1:run:
[echo] Local dir: /tmp/myproject/vendor/lib1/build
[echo] Global dir: /tmp/myproject
BUILD FINISHED
Total time: 0.0411 seconds
Import Targets: Path handling
Phing for power users
Import Targets: Path handling
Phing for power users
Be aware to always(!) use the
projects name in lowercase format!
Import Targets: Path handling
Phing for power users
It`s ${phing.dir.myproject}
not ${phing.dir.MyProject}!
Distinct Target Naming
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="ci:run-tests">
<target name="app:clean-cache">
</target>
<target name="app:create-cache">
</target>
<target name="db:migrate">
</target>
<target name="js:minifiy">
</target>
<target name="ci:lint">
</target>
<target name="ci:run-tests">
</target>
</project>
Distinct Target Naming
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="app:create-cache">
<target name="app:clean-cache"
description="Removes all cache files.">
</target>
<target name="app:create-cache"
description="Builds the cache files from the
xml configuration.">
</target>
</project>
Adding meaningful descriptions
Phing for power users
$> phing -l
Buildfile: /tmp/myproject/build.xml
Default target:
-----------------------------------------------------
app:create-cache Builds the cache files from the xml
configuration.
Main targets:
------------------------------------------------------
app:clean-cache Removes all cache files.
app:create-cache Builds the cache files from the xml
configuration.
Adding meaningful descriptions
Phing for power users
Prompt user for input
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<!-- tag the database -->
<input
propertyname="tag"
defaultValue="mytag">Tag to create?</input>
<liquibase-tag
tag="${tag}"
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>
Calling PHP functions from Phing
Phing for power users
Calling PHP functions from Phing
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<!--
Returns canonicalized absolute pathname
-->
<php function="realpath"
returnProperty="app.dir">
<param value="${app.dir}"/>
</php>
</target>
</project>
Restrict user access
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="run">
<target name="run">
<!--
Check for root user
-->
<if>
<not>
<equals arg1="${env.USER}"
arg2="root" />
</not>
<then>
<fail message="Wrong user!" />
</then>
</if>
</target>
</project>
Restrict user access
Phing for power users
Path handling
Phing for power users
Path handling
Phing for power users
<?xml version="1.0"?>
<project name="myproject" default="ci:phpunit">
<!--
...
-->
<target name="ci:phpunit"
depends="-init, -ci:prepare">
<resolvepath propertyName="phpunit.path.abs"
dir="${phing.dir}"
file="${phpunit.path}"/>
<exec executable="${phpunit.path.abs}" />
</target>
</project>
Phing + Jenkins
Phing for power users
Phing + Jenkins
Phing for power users
Install the Jenkins Phing plugin
Phing for power users
Phing for power users
Phing for power users
Phing + Composer + Jenkins
Phing for power users
Phing + Composer + Jenkins
Phing for power users
Install the Jenkins EnvInject plugin
Phing for power users
Phing for power users
Phing for power users
Phing for power users
Follow conventions
Phing for power users
Follow conventions
Phing for power users
Phing expects your build file to be called
build.xml and the build’s properties file
build.properties
Follow conventions
Phing for power users
Pick meaningful, human-readable
names for targets and properties.
Follow conventions
Phing for power users
Make build files self-contained.
Thank you!
http://joind.in/9023
Phing for power users
Image Credits
http://www.sxc.hu/photo/629370
http://www.sxc.hu/photo/615731

More Related Content

What's hot

Best Practices for Front-End Django Developers
Best Practices for Front-End Django DevelopersBest Practices for Front-End Django Developers
Best Practices for Front-End Django Developers
Christine Cheung
 
How does get template part works in twenty ten theme
How does get template part works in twenty ten themeHow does get template part works in twenty ten theme
How does get template part works in twenty ten theme
mohd rozani abd ghani
 

What's hot (20)

Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture Introduction
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
Django Introduction & Tutorial
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial
 
Best Practices for Front-End Django Developers
Best Practices for Front-End Django DevelopersBest Practices for Front-End Django Developers
Best Practices for Front-End Django Developers
 
Django
DjangoDjango
Django
 
Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP Applications
 
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJRealize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
 
GAEO
GAEOGAEO
GAEO
 
Django a whirlwind tour
Django   a whirlwind tourDjango   a whirlwind tour
Django a whirlwind tour
 
Hybrid Web Applications
Hybrid Web ApplicationsHybrid Web Applications
Hybrid Web Applications
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third Plugin
 
How does get template part works in twenty ten theme
How does get template part works in twenty ten themeHow does get template part works in twenty ten theme
How does get template part works in twenty ten theme
 
Django, What is it, Why is it cool?
Django, What is it, Why is it cool?Django, What is it, Why is it cool?
Django, What is it, Why is it cool?
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Free django
Free djangoFree django
Free django
 
Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics Presentation
 
Building and deploying PHP applications with Phing
Building and deploying PHP applications with PhingBuilding and deploying PHP applications with Phing
Building and deploying PHP applications with Phing
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Django Performance Recipes
Django Performance RecipesDjango Performance Recipes
Django Performance Recipes
 

Viewers also liked

Testing untestable code - phpconpl11
Testing untestable code - phpconpl11Testing untestable code - phpconpl11
Testing untestable code - phpconpl11
Stephan Hochdörfer
 
Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11
Stephan Hochdörfer
 
Testing untestable code - STPCon11
Testing untestable code - STPCon11Testing untestable code - STPCon11
Testing untestable code - STPCon11
Stephan Hochdörfer
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12
Stephan Hochdörfer
 
Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11
Stephan Hochdörfer
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffm
Stephan Hochdörfer
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13
Stephan Hochdörfer
 
Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010
Stephan Hochdörfer
 
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
Stephan Hochdörfer
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13
Stephan Hochdörfer
 

Viewers also liked (12)

Testing untestable code - phpconpl11
Testing untestable code - phpconpl11Testing untestable code - phpconpl11
Testing untestable code - phpconpl11
 
Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11Testing untestable code - PHPUGFFM 01/11
Testing untestable code - PHPUGFFM 01/11
 
Testing untestable code - STPCon11
Testing untestable code - STPCon11Testing untestable code - STPCon11
Testing untestable code - STPCon11
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12
 
Testing untestable code - DPC10
Testing untestable code - DPC10Testing untestable code - DPC10
Testing untestable code - DPC10
 
Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11Simplify your external dependency management - DPC11
Simplify your external dependency management - DPC11
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffm
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13
 
Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010Testing untestable Code - PFCongres 2010
Testing untestable Code - PFCongres 2010
 
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13
 

Similar to Phing for power users - frOSCon8

Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009
Helgi Þormar Þorbjörnsson
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11
julien.ponge
 
Juniper Srx quickstart-12.1r3
Juniper Srx quickstart-12.1r3Juniper Srx quickstart-12.1r3
Juniper Srx quickstart-12.1r3
Mohamed Al-Natour
 

Similar to Phing for power users - frOSCon8 (20)

Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
 
Introduction to python scrapping
Introduction to python scrappingIntroduction to python scrapping
Introduction to python scrapping
 
Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009
 
First python project
First python projectFirst python project
First python project
 
Pyhton-1a-Basics.pdf
Pyhton-1a-Basics.pdfPyhton-1a-Basics.pdf
Pyhton-1a-Basics.pdf
 
Django dev-env-my-way
Django dev-env-my-wayDjango dev-env-my-way
Django dev-env-my-way
 
[CON3189] JavaOne 2016 - Introduction to Java ME development for the Raspberr...
[CON3189] JavaOne 2016 - Introduction to Java ME development for the Raspberr...[CON3189] JavaOne 2016 - Introduction to Java ME development for the Raspberr...
[CON3189] JavaOne 2016 - Introduction to Java ME development for the Raspberr...
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHP
 
Introduction to FreeNAS development by John Hixson
Introduction to FreeNAS development by John HixsonIntroduction to FreeNAS development by John Hixson
Introduction to FreeNAS development by John Hixson
 
Getting Started with Embedded Python: MicroPython and CircuitPython
Getting Started with Embedded Python: MicroPython and CircuitPythonGetting Started with Embedded Python: MicroPython and CircuitPython
Getting Started with Embedded Python: MicroPython and CircuitPython
 
Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldDistributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component world
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11
 
Java Device I/O at Raspberry PI to Build a Candy Vending Machine
Java Device I/O at Raspberry PI to Build a Candy Vending MachineJava Device I/O at Raspberry PI to Build a Candy Vending Machine
Java Device I/O at Raspberry PI to Build a Candy Vending Machine
 
Hack Like It's 2013 (The Workshop)
Hack Like It's 2013 (The Workshop)Hack Like It's 2013 (The Workshop)
Hack Like It's 2013 (The Workshop)
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.cat
 
Universal Userland
Universal UserlandUniversal Userland
Universal Userland
 
Pipfile, pipenv, pip… what?!
Pipfile, pipenv, pip… what?!Pipfile, pipenv, pip… what?!
Pipfile, pipenv, pip… what?!
 
Juniper Srx quickstart-12.1r3
Juniper Srx quickstart-12.1r3Juniper Srx quickstart-12.1r3
Juniper Srx quickstart-12.1r3
 
Web Development in Django
Web Development in DjangoWeb Development in Django
Web Development in Django
 

More from Stephan Hochdörfer

Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaOffline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmka
Stephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Stephan Hochdörfer
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Stephan Hochdörfer
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
Stephan Hochdörfer
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Stephan Hochdörfer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012
Stephan Hochdörfer
 
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Stephan Hochdörfer
 
Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012
Stephan Hochdörfer
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12
Stephan Hochdörfer
 
Real World Dependency Injection SE - phpugrhh
Real World Dependency Injection SE - phpugrhhReal World Dependency Injection SE - phpugrhh
Real World Dependency Injection SE - phpugrhh
Stephan Hochdörfer
 
Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Managing variability in software applications - scandev12
Managing variability in software applications - scandev12
Stephan Hochdörfer
 
The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12
Stephan Hochdörfer
 

More from Stephan Hochdörfer (17)

Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaOffline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmka
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012
 
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
 
Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12
 
The state of DI - DPC12
The state of DI - DPC12The state of DI - DPC12
The state of DI - DPC12
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
Real World Dependency Injection SE - phpugrhh
Real World Dependency Injection SE - phpugrhhReal World Dependency Injection SE - phpugrhh
Real World Dependency Injection SE - phpugrhh
 
Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Managing variability in software applications - scandev12
Managing variability in software applications - scandev12
 
The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12
 

Recently uploaded

Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Peter Udo Diehl
 

Recently uploaded (20)

Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 

Phing for power users - frOSCon8