SlideShare a Scribd company logo
A Phing fairy tale
Stephan Hochdörfer, bitExpert AG
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
A Phing fairy tale

 Disclaimer




                    Warning:
          You will see a hell lot of XML.
A Phing fairy tale

 What is Phing?
A Phing fairy tale

 What is Phing?




      It is a PHP project build system or
       build tool based on Apache Ant.
A Phing fairy tale

 What is Phing?




       Domain Specific Language for an
           project build system.
A Phing fairy tale

 What is Phing?




   Enables one button push automation.
A Phing fairy tale

 Project build system?
A Phing fairy tale

 Project build system?




  Automation of non-development tasks
A Phing fairy tale

 Project build system?




       Automate absolutely everything.
A Phing fairy tale

 Project build system?




       If you use Phing, only use Phing.
A Phing fairy tale

 Why Phing?
A Phing fairy tale

 Why Phing?




     Runs everywhere where PHP runs.
A Phing fairy tale

 Why Phing?




     No additional depencendies needed
               (e.g. Java, …).
A Phing fairy tale

 Why Phing?




             More than 120 predefined
              tasks to choose from.
A Phing fairy tale

 Why Phing?




            Easy to extend by writing
              custom tasks in PHP.
A Phing fairy tale

 How to install Phing?
A Phing fairy tale

 How to install Phing? The PEAR way...
 Installing Phing
 $> pear channel­discover pear.phing.info
 $> pear install phing/phing
A Phing fairy tale

 How to install Phing? The PEAR way...
 Installing Phing
 $> pear channel­discover pear.phing.info
 $> pear install phing/phing




 Running Phing:
 $> phing ­v
 Phing 2.4.14
A Phing fairy tale

 How to install Phing? The Composer way...
 composer.json:
 {
     "require": {
         "phing/phing": "2.4.14"
     }
 }
A Phing fairy tale

 How to install Phing? The Composer way...
 composer.json:
 {
     "require": {
         "phing/phing": "2.4.14"
     }
 }




 Running Composer:
 $> php composer.phar install
 Loading composer repositories with package information
 Installing dependencies
   ­ Installing phing/phing (2.4.14)
     Downloading: 100%         

 Writing lock file
 Generating autoload files
A Phing fairy tale

 How to install Phing? The Composer way...
 /home/shochdoerfer/myproject
    |­vendor
    |­­­bin
    |­­­­­@phing
    |­­­composer
    |­­­phing
    |­­­­­phing
    |­­­­­­­bin
    |­­­­­­­­­phing
    |­­­­­­­build
    |­­­­­­­classes
    |­­­­­­­docs
    |­­­­­­­etc
    |­­­­­­­test
A Phing fairy tale

 How to install Phing? The Composer way...
 /home/shochdoerfer/myproject
    |­vendor
    |­­­bin
    |­­­­­@phing
    |­­­composer
    |­­­phing
    |­­­­­phing
    |­­­­­­­bin
    |­­­­­­­­­phing
    |­­­­­­­build
    |­­­­­­­classes
    |­­­­­­­docs
    |­­­­­­­etc
    |­­­­­­­test


 Running Phing:
 $> ./vendor/bin/phing ­v
 Phing DEV
A Phing fairy tale

 Phing Basics
A Phing fairy tale

 Phing Basics




       Project, Target, Task, Properties
A Phing fairy tale

 Phing Basics: Project




           Root node of a build file
        containing one or more targets.
A Phing fairy tale

 Phing Basics: Target




                A group of tasks that
                  run as an entity.
A Phing fairy tale

 Phing Basics: Task




            Custom piece of code to
           perform a specific function.
A Phing fairy tale

 Phing Basics: Properties




         Properties (Variables) help to
             customize execution.
A Phing fairy tale

 Phing Basics: Built-In Properties




          e.g. host.os, line.separator,
         phing.version, php.version, …
A Phing fairy tale

 Phing Basics: Sample Build File
 <?xml version="1.0"?>
 <project name="myproject" default="init">

     <target name="init">

          <!­­ insert logic here ­­>
     </target>
 </project>
A Phing fairy tale

 Build File – Hello World example
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="hello" 
         description="Says Hello, world!">

           <echo msg="Hello, world!" />
     </target>
 </project>
A Phing fairy tale

 Build File – Hello World example
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="hello" 
         description="Says Hello, world!">

           <echo msg="Hello, world!" />
     </target>
 </project>


 $> phing
 Buildfile: /home/shochdoerfer/build.xml

 myproject > hello:

      [echo] Hello, world!

 BUILD FINISHED

 Total time: 0.0595 seconds
A Phing fairy tale

 Build File – Introducing Properties
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="hello" 
         description="Says Hello, world!">

           <property name="Hello" 
                 value="Hello, world!" />

           <echo msg="${Hello}" />
     </target>
 </project>
A Phing fairy tale

 Build File – Introducing Properties
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <property name="Hello" value="Hello, world!" />
      
     <target name="hello" 
         description="Says Hello, world!">

           <echo msg="${Hello}" />
     </target>
 </project>
A Phing fairy tale

 Build File – Externalizing Properties
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="hello" 
         description="Says whatever you want to say"

           <echo msg="${Hello}" />
     </target>
 </project>
A Phing fairy tale

 Build File – Externalizing Properties (CLI)
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="hello" 
         description="Says whatever you want to say"

           <echo msg="${Hello}" />
     </target>
 </project>


 $> phing ­DHello="Hello from CLI"
 Buildfile: /tmp/build.xml

 myproject > hello:

      [echo] Hello from CLI

 BUILD FINISHED

 Total time: 0.0599 seconds
A Phing fairy tale

 Build File – Externalizing Properties (File)
 <?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>
A Phing fairy tale

 Build File – Externalizing Properties (File)
 <?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>




 build.properties:
 Hello=Hello, world!
A Phing fairy tale

 Build File – Externalizing Properties (File)
 $> phing
 Buildfile: /home/shochdoerfer/build.xml

 myproject > hello:

  [property] Loading /home/shochdoerfer/build.properties
      [echo] Hello, world!

 BUILD FINISHED

 Total time: 0.0601 seconds
A Phing fairy tale

 Build File – Defining multiple targets
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <property name="Hello" value="Hello, world!" />
      
     <target name="hello" 
         description="Says Hello, world!">

          <echo msg="${Hello}" />
     </target>

     <target name="goodbye" 
         description="Says goodbye!">

           <echo msg="Goodbye!" />
     </target>
 </project>
A Phing fairy tale

 Build File – Defining multiple targets
 $> phing hello
 Buildfile: /tmp/build.xml

 myproject > hello:

      [echo] Hello, world!

 BUILD FINISHED

 Total time: 0.0612 seconds
A Phing fairy tale

 Build File – Defining multiple targets
 $> phing hello
 Buildfile: /tmp/build.xml

 myproject > hello:

      [echo] Hello, world!

 BUILD FINISHED

 Total time: 0.0612 seconds

 $> phing goodbye
 Buildfile: /tmp/build.xml

 myproject > goodbye:

      [echo] Goodbye!

 BUILD FINISHED

 Total time: 0.0619 seconds
A Phing fairy tale

 Build File – Target dependencies
 <?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>
A Phing fairy tale

 Build File – Target dependencies
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="init" 
         description="Property initialization">

         <property name="Hello" value="Hello, world!" />
     </target>

     <target name="customcode" 
         description="Some custom logic">
     </target>

     <target name="hello" 
         depends="init, customcode">

           <echo msg="${Hello}" />
     </target>
 </project>
A Phing fairy tale

 Build File – Target dependencies
 <?xml version="1.0"?>
 <project name="myproject" default="hello">

     <target name="pre­init">
         <property name="World" value="world" />
     </target>

     <target name="init" 
          depends="pre­init">
          <property name="Hello" 
                value="Hello, ${World}!" />
     </target>

     <target name="hello" 
         depends="init">

           <echo msg="${Hello}" />
     </target>
 </project>
A Phing fairy tale

 Build File – Calling targets programmatically I
 <?xml version="1.0"?>
 <project name="myproject" default="run">

     <target name="print">
         <echo msg="Processing: ${filename}" />
     </target>

     <target name="run">
          <!­­ 
            loop through files and call print target ­­>
          <foreach param="filename" 
              absparam="filename" target="print">

              <fileset dir=".">
                   <include name="*.php"/>
              </fileset>
          </foreach>
     </target>
 </project>
A Phing fairy tale

 Build File – Calling targets programmatically II
 <?xml version="1.0"?>
 <project name="myproject" default="run">

     <target name="print">
         <echo msg="Processing: ${filename}" />
     </target>

     <target name="run">

          <!­­ calling target with given property ­­>
          <phingcall target="print">
              <property name="filename" 
                   value="test.php" />
          </phingcall>
     </target>
 </project>
A Phing fairy tale

 Build File – Calling targets programmatically III
 <?xml version="1.0"?>
 <project name="myproject" default="run">

     <target name="run">

          <!­­ calling target in print.xml with 
               given property ­­>
          <phing phingfile="print.xml" target="print">
              <property name="filename" 
                  value="test.php" />
          </phing>
     </target>
 </project>
A Phing fairy tale

 Build File – Fileset
 <?xml version="1.0"?>
 <project name="myproject" default="run">

     <target name="run">

           <!­­ Copy files matching the expression ­­>
           <copy todir="/tmp/deploy">
              <fileset dir="." includes="**/*.php">
                  <and>
                       <size value="1024" when="more" />
                       <date 
                           datetime="01/01/2013 10:00 AM" 
                           when="after" />
                  </and>
              </fileset>
           </copy>
     </target>
 </project>
A Phing fairy tale

 Build File – Filters
 <?xml version="1.0"?>
 <project name="myproject" default="run">

     <target name="run">
           <!­­ Copy files and replace tokens ­­>
           <copy todir="/tmp/deploy">
              <filterchain>
                  <replacetokens begintoken="##"
                        endtoken="##">
                       <token key="VERSION" 
                               value="${app.version}"
                  </replacetokens>
              </filterchain>

              <fileset dir=".">
                    <include name="**/*.php"/>
              </fileset>
           </copy>
     </target>
 </project>
A Phing fairy tale

 Phing – What can it do for me?
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>
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>
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>
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 ­­>

          <liquibase­update
              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>
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>
A Phing fairy tale

 Build File – Advanced usage
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, local­prop"
         <!­­ some more init logic ­­>
     </target>

     <target name="prop">
         <echo message="Load default build.properties"
         <property
              file="./build.properties" />
     </target>
A Phing fairy tale

  Properties File - Improved version
     <target name="local­prop"
         if="local­prop.exists"
         depends="local­prop­check">

         <echo message="Loading custom properties!"
         <property
              file="${project.basedir}/local.properties"
              override="true"/>
     </target>

     <target name="local­prop­check">
          <available
              file="${project.basedir}/local.properties"
              property="local­prop.exists" />
     </target>
 </project>
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.
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.
A Phing fairy tale

 Custom Task (Adhoc definition)
 <?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>
A Phing fairy tale

 Custom Task (External file)
 <?php
 require_once 'phing/Task.php';

 class MyTask extends Task {
     /**
      * (non­PHPdoc)
      * @see Task::main()
      */
     public function main() {
          // Custom code here...
     }
 }
A Phing fairy tale

 Custom Task (External file)
 <?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>
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...
     }
 }
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>
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>
A Phing fairy tale

 Distinct Target Naming
 <?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>
A Phing fairy tale

 Prompt user for input
 <?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>
A Phing fairy tale

 Calling PHP functions from Phing
 <?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>
A Phing fairy tale

 Follow conventions



 Phing expects your build file to be called
  build.xml and the build’s properties file
              build.properties
A Phing fairy tale

 Follow conventions



      Pick meaningful, human-readable
      names for targets and properties.
A Phing fairy tale

 Follow conventions




         Make build files self-contained.
Thank you!
http://joind.in/7949

More Related Content

What's hot

Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)
Michiel Rook
 
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 thememohd rozani abd ghani
 
"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo
Yandex
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | Basics
Shubham Kumar Singh
 
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
Michiel Rook
 
Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919
Paul Bearne
 
Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP Applications
Pavan Kumar N
 
Phing
PhingPhing
Phing
mdekrijger
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
Tatsuhiko Miyagawa
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
Nathan Eror
 
Phing: Building with PHP
Phing: Building with PHPPhing: Building with PHP
Phing: Building with PHP
hozn
 
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Edureka!
 
Automated Deployment With Phing
Automated Deployment With PhingAutomated Deployment With Phing
Automated Deployment With Phing
Daniel Cousineau
 
Web develop in flask
Web develop in flaskWeb develop in flask
Web develop in flask
Jim Yeh
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third Plugin
Justin Ryan
 
Putting Phing to Work for You
Putting Phing to Work for YouPutting Phing to Work for You
Putting Phing to Work for You
hozn
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Stephan Hochdörfer
 
Api Design
Api DesignApi Design

What's hot (18)

Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)Phing - A PHP Build Tool (An Introduction)
Phing - A PHP Build Tool (An Introduction)
 
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
 
"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | Basics
 
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
 
Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919
 
Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP Applications
 
Phing
PhingPhing
Phing
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
Phing: Building with PHP
Phing: Building with PHPPhing: Building with PHP
Phing: Building with PHP
 
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
 
Automated Deployment With Phing
Automated Deployment With PhingAutomated Deployment With Phing
Automated Deployment With Phing
 
Web develop in flask
Web develop in flaskWeb develop in flask
Web develop in flask
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third Plugin
 
Putting Phing to Work for You
Putting Phing to Work for YouPutting Phing to Work for You
Putting Phing to Work for You
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12
 
Api Design
Api DesignApi Design
Api Design
 

Viewers also liked

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 - wmkaStephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Stephan 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! - WDC12Stephan Hochdörfer
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Stephan 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 - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Stephan Hochdörfer
 

Viewers also liked (7)

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
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13
 
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
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
 
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 - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 

Similar to A Phing fairy tale - ConFoo13

Building and Deploying PHP apps with Phing
Building and Deploying PHP apps with PhingBuilding and Deploying PHP apps with Phing
Building and Deploying PHP apps with Phing
Michiel Rook
 
Phing i Fabric - Budowanie i deployment aplikacji webowych
Phing i Fabric - Budowanie i deployment aplikacji webowychPhing i Fabric - Budowanie i deployment aplikacji webowych
Phing i Fabric - Budowanie i deployment aplikacji webowych
leafnode
 
Deploying PHP applications with Phing
Deploying PHP applications with PhingDeploying PHP applications with Phing
Deploying PHP applications with Phing
Michiel Rook
 
Getting Started with Pelican
Getting Started with PelicanGetting Started with Pelican
Getting Started with Pelican
Nazrul Kamaruddin
 
Acceptance testing plone sites and add ons with robot framework and selenium
Acceptance testing plone sites and add ons with robot framework and seleniumAcceptance testing plone sites and add ons with robot framework and selenium
Acceptance testing plone sites and add ons with robot framework and selenium
Asko Soukka
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11julien.ponge
 
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on HerokuRapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Salesforce Developers
 
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)Fabien Potencier
 
Phing101 or How to staff a build orchestra
Phing101 or How to staff a build orchestraPhing101 or How to staff a build orchestra
Phing101 or How to staff a build orchestra
raphaelstolt
 
Creating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoCreating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with Hugo
Brian Hogan
 
Fabric for fun_and_profit
Fabric for fun_and_profitFabric for fun_and_profit
Fabric for fun_and_profit
Javier Jair Trejo García
 
The Modern Developer Toolbox
The Modern Developer ToolboxThe Modern Developer Toolbox
The Modern Developer Toolbox
Pablo Godel
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaRobert Nyman
 
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
Robert Lemke
 
Write php deploy everywhere
Write php deploy everywhereWrite php deploy everywhere
Write php deploy everywhere
Michelangelo van Dam
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
Ryan Weaver
 
2019 11-bgphp
2019 11-bgphp2019 11-bgphp
2019 11-bgphp
dantleech
 
Building com Phing - 7Masters PHP
Building com Phing - 7Masters PHPBuilding com Phing - 7Masters PHP
Building com Phing - 7Masters PHP
iMasters
 
Php task runners
Php task runnersPhp task runners
Php task runners
Ignacio Velazquez
 
GettingStartedWithPHP
GettingStartedWithPHPGettingStartedWithPHP
GettingStartedWithPHPNat Weerawan
 

Similar to A Phing fairy tale - ConFoo13 (20)

Building and Deploying PHP apps with Phing
Building and Deploying PHP apps with PhingBuilding and Deploying PHP apps with Phing
Building and Deploying PHP apps with Phing
 
Phing i Fabric - Budowanie i deployment aplikacji webowych
Phing i Fabric - Budowanie i deployment aplikacji webowychPhing i Fabric - Budowanie i deployment aplikacji webowych
Phing i Fabric - Budowanie i deployment aplikacji webowych
 
Deploying PHP applications with Phing
Deploying PHP applications with PhingDeploying PHP applications with Phing
Deploying PHP applications with Phing
 
Getting Started with Pelican
Getting Started with PelicanGetting Started with Pelican
Getting Started with Pelican
 
Acceptance testing plone sites and add ons with robot framework and selenium
Acceptance testing plone sites and add ons with robot framework and seleniumAcceptance testing plone sites and add ons with robot framework and selenium
Acceptance testing plone sites and add ons with robot framework and selenium
 
IzPack at LyonJUG'11
IzPack at LyonJUG'11IzPack at LyonJUG'11
IzPack at LyonJUG'11
 
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on HerokuRapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
 
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
 
Phing101 or How to staff a build orchestra
Phing101 or How to staff a build orchestraPhing101 or How to staff a build orchestra
Phing101 or How to staff a build orchestra
 
Creating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoCreating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with Hugo
 
Fabric for fun_and_profit
Fabric for fun_and_profitFabric for fun_and_profit
Fabric for fun_and_profit
 
The Modern Developer Toolbox
The Modern Developer ToolboxThe Modern Developer Toolbox
The Modern Developer Toolbox
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
 
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
 
Write php deploy everywhere
Write php deploy everywhereWrite php deploy everywhere
Write php deploy everywhere
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
 
2019 11-bgphp
2019 11-bgphp2019 11-bgphp
2019 11-bgphp
 
Building com Phing - 7Masters PHP
Building com Phing - 7Masters PHPBuilding com Phing - 7Masters PHP
Building com Phing - 7Masters PHP
 
Php task runners
Php task runnersPhp task runners
Php task runners
 
GettingStartedWithPHP
GettingStartedWithPHPGettingStartedWithPHP
GettingStartedWithPHP
 

More from Stephan Hochdörfer

Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Stephan 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 - oscon13Stephan Hochdörfer
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Stephan 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
 
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 - bedcon13Stephan Hochdörfer
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Stephan 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 - WMMRN12Stephan 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 - pfCongres2012Stephan 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 - Herbstcampus12Stephan Hochdörfer
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Stephan Hochdörfer
 
Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Testing untestable code - oscon 2012
Testing untestable code - oscon 2012Stephan Hochdörfer
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Stephan Hochdörfer
 
Real World Dependency Injection SE - phpugrhh
Real World Dependency Injection SE - phpugrhhReal World Dependency Injection SE - phpugrhh
Real World Dependency Injection SE - phpugrhhStephan Hochdörfer
 
Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Stephan 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 - phpbnl12Stephan Hochdörfer
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmStephan Hochdörfer
 

More from Stephan Hochdörfer (18)

Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
 
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
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - 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
Offline Strategien für HTML5 Web Applikationen - dwx13
 
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
 
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
 
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 - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - 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
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffm
 

Recently uploaded

UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
ThomasParaiso2
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 

Recently uploaded (20)

UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 

A Phing fairy tale - ConFoo13

  • 1. A Phing fairy tale Stephan Hochdörfer, bitExpert AG
  • 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.
  • 4. A Phing fairy tale What is Phing?
  • 5. A Phing fairy tale What is Phing? It is a PHP project build system or build tool based on Apache Ant.
  • 6. A Phing fairy tale What is Phing? Domain Specific Language for an project build system.
  • 7. A Phing fairy tale What is Phing? Enables one button push automation.
  • 8. A Phing fairy tale Project build system?
  • 9. A Phing fairy tale Project build system? Automation of non-development tasks
  • 10. A Phing fairy tale Project build system? Automate absolutely everything.
  • 11. A Phing fairy tale Project build system? If you use Phing, only use Phing.
  • 12. A Phing fairy tale Why Phing?
  • 13. A Phing fairy tale Why Phing? Runs everywhere where PHP runs.
  • 14. A Phing fairy tale Why Phing? No additional depencendies needed (e.g. Java, …).
  • 15. A Phing fairy tale Why Phing? More than 120 predefined tasks to choose from.
  • 16. A Phing fairy tale Why Phing? Easy to extend by writing custom tasks in PHP.
  • 17. A Phing fairy tale How to install Phing?
  • 18. A Phing fairy tale How to install Phing? The PEAR way... Installing Phing $> pear channel­discover pear.phing.info $> pear install phing/phing
  • 19. A Phing fairy tale How to install Phing? The PEAR way... Installing Phing $> pear channel­discover pear.phing.info $> pear install phing/phing Running Phing: $> phing ­v Phing 2.4.14
  • 20. A Phing fairy tale How to install Phing? The Composer way... composer.json: { "require": { "phing/phing": "2.4.14" } }
  • 21. A Phing fairy tale How to install Phing? The Composer way... composer.json: { "require": { "phing/phing": "2.4.14" } } Running Composer: $> php composer.phar install Loading composer repositories with package information Installing dependencies   ­ Installing phing/phing (2.4.14)     Downloading: 100%          Writing lock file Generating autoload files
  • 22. A Phing fairy tale How to install Phing? The Composer way... /home/shochdoerfer/myproject    |­vendor    |­­­bin    |­­­­­@phing    |­­­composer    |­­­phing    |­­­­­phing    |­­­­­­­bin    |­­­­­­­­­phing    |­­­­­­­build    |­­­­­­­classes    |­­­­­­­docs    |­­­­­­­etc    |­­­­­­­test
  • 23. A Phing fairy tale How to install Phing? The Composer way... /home/shochdoerfer/myproject    |­vendor    |­­­bin    |­­­­­@phing    |­­­composer    |­­­phing    |­­­­­phing    |­­­­­­­bin    |­­­­­­­­­phing    |­­­­­­­build    |­­­­­­­classes    |­­­­­­­docs    |­­­­­­­etc    |­­­­­­­test Running Phing: $> ./vendor/bin/phing ­v Phing DEV
  • 24. A Phing fairy tale Phing Basics
  • 25. A Phing fairy tale Phing Basics Project, Target, Task, Properties
  • 26. A Phing fairy tale Phing Basics: Project Root node of a build file containing one or more targets.
  • 27. A Phing fairy tale Phing Basics: Target A group of tasks that run as an entity.
  • 28. A Phing fairy tale Phing Basics: Task Custom piece of code to perform a specific function.
  • 29. A Phing fairy tale Phing Basics: Properties Properties (Variables) help to customize execution.
  • 30. A Phing fairy tale Phing Basics: Built-In Properties e.g. host.os, line.separator, phing.version, php.version, …
  • 31. A Phing fairy tale Phing Basics: Sample Build File <?xml version="1.0"?> <project name="myproject" default="init"> <target name="init"> <!­­ insert logic here ­­> </target> </project>
  • 32. A Phing fairy tale Build File – Hello World example <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says Hello, world!">  <echo msg="Hello, world!" /> </target> </project>
  • 33. A Phing fairy tale Build File – Hello World example <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says Hello, world!">  <echo msg="Hello, world!" /> </target> </project> $> phing Buildfile: /home/shochdoerfer/build.xml myproject > hello:      [echo] Hello, world! BUILD FINISHED Total time: 0.0595 seconds
  • 34. A Phing fairy tale Build File – Introducing Properties <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says Hello, world!">  <property name="Hello"                  value="Hello, world!" />  <echo msg="${Hello}" /> </target> </project>
  • 35. A Phing fairy tale Build File – Introducing Properties <?xml version="1.0"?> <project name="myproject" default="hello"> <property name="Hello" value="Hello, world!" />   <target name="hello"  description="Says Hello, world!">  <echo msg="${Hello}" /> </target> </project>
  • 36. A Phing fairy tale Build File – Externalizing Properties <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says whatever you want to say"  <echo msg="${Hello}" /> </target> </project>
  • 37. A Phing fairy tale Build File – Externalizing Properties (CLI) <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="hello"  description="Says whatever you want to say"  <echo msg="${Hello}" /> </target> </project> $> phing ­DHello="Hello from CLI" Buildfile: /tmp/build.xml myproject > hello:      [echo] Hello from CLI BUILD FINISHED Total time: 0.0599 seconds
  • 38. A Phing fairy tale Build File – Externalizing Properties (File) <?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>
  • 39. A Phing fairy tale Build File – Externalizing Properties (File) <?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> build.properties: Hello=Hello, world!
  • 40. A Phing fairy tale Build File – Externalizing Properties (File) $> phing Buildfile: /home/shochdoerfer/build.xml myproject > hello:  [property] Loading /home/shochdoerfer/build.properties      [echo] Hello, world! BUILD FINISHED Total time: 0.0601 seconds
  • 41. A Phing fairy tale Build File – Defining multiple targets <?xml version="1.0"?> <project name="myproject" default="hello"> <property name="Hello" value="Hello, world!" />   <target name="hello"  description="Says Hello, world!">  <echo msg="${Hello}" /> </target> <target name="goodbye"  description="Says goodbye!">  <echo msg="Goodbye!" /> </target> </project>
  • 42. A Phing fairy tale Build File – Defining multiple targets $> phing hello Buildfile: /tmp/build.xml myproject > hello:      [echo] Hello, world! BUILD FINISHED Total time: 0.0612 seconds
  • 43. A Phing fairy tale Build File – Defining multiple targets $> phing hello Buildfile: /tmp/build.xml myproject > hello:      [echo] Hello, world! BUILD FINISHED Total time: 0.0612 seconds $> phing goodbye Buildfile: /tmp/build.xml myproject > goodbye:      [echo] Goodbye! BUILD FINISHED Total time: 0.0619 seconds
  • 44. A Phing fairy tale Build File – Target dependencies <?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>
  • 45. A Phing fairy tale Build File – Target dependencies <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="init"  description="Property initialization"> <property name="Hello" value="Hello, world!" /> </target> <target name="customcode"  description="Some custom logic"> </target> <target name="hello"  depends="init, customcode">  <echo msg="${Hello}" /> </target> </project>
  • 46. A Phing fairy tale Build File – Target dependencies <?xml version="1.0"?> <project name="myproject" default="hello"> <target name="pre­init"> <property name="World" value="world" /> </target> <target name="init"  depends="pre­init"> <property name="Hello"                 value="Hello, ${World}!" /> </target> <target name="hello"  depends="init">  <echo msg="${Hello}" /> </target> </project>
  • 47. A Phing fairy tale Build File – Calling targets programmatically I <?xml version="1.0"?> <project name="myproject" default="run"> <target name="print"> <echo msg="Processing: ${filename}" /> </target> <target name="run"> <!­­             loop through files and call print target ­­> <foreach param="filename"               absparam="filename" target="print"> <fileset dir="."> <include name="*.php"/> </fileset> </foreach> </target> </project>
  • 48. A Phing fairy tale Build File – Calling targets programmatically II <?xml version="1.0"?> <project name="myproject" default="run"> <target name="print"> <echo msg="Processing: ${filename}" /> </target> <target name="run"> <!­­ calling target with given property ­­> <phingcall target="print"> <property name="filename"                    value="test.php" /> </phingcall> </target> </project>
  • 49. A Phing fairy tale Build File – Calling targets programmatically III <?xml version="1.0"?> <project name="myproject" default="run"> <target name="run"> <!­­ calling target in print.xml with                given property ­­> <phing phingfile="print.xml" target="print"> <property name="filename"                   value="test.php" /> </phing> </target> </project>
  • 50. A Phing fairy tale Build File – Fileset <?xml version="1.0"?> <project name="myproject" default="run"> <target name="run">       <!­­ Copy files matching the expression ­­>       <copy todir="/tmp/deploy"> <fileset dir="." includes="**/*.php"> <and> <size value="1024" when="more" /> <date                            datetime="01/01/2013 10:00 AM"                            when="after" /> </and> </fileset>       </copy> </target> </project>
  • 51. A Phing fairy tale Build File – Filters <?xml version="1.0"?> <project name="myproject" default="run"> <target name="run">       <!­­ Copy files and replace tokens ­­>       <copy todir="/tmp/deploy"> <filterchain> <replacetokens begintoken="##"                        endtoken="##"> <token key="VERSION"                                value="${app.version}" </replacetokens> </filterchain> <fileset dir=".">       <include name="**/*.php"/> </fileset>       </copy> </target> </project>
  • 52. A Phing fairy tale Phing – What can it do for me?
  • 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 ­­>      <liquibase­update     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>
  • 58. A Phing fairy tale Build File – Advanced usage
  • 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, local­prop" <!­­ 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="local­prop" if="local­prop.exists" depends="local­prop­check"> <echo message="Loading custom properties!" <property file="${project.basedir}/local.properties" override="true"/> </target> <target name="local­prop­check"> <available file="${project.basedir}/local.properties" property="local­prop.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">  <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>
  • 64. A Phing fairy tale Custom Task (External file) <?php require_once 'phing/Task.php'; class MyTask extends Task { /**  * (non­PHPdoc)  * @see Task::main()  */ public function main() { // Custom code here... } }
  • 65. A Phing fairy tale Custom Task (External file) <?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>
  • 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>
  • 69. A Phing fairy tale Distinct Target Naming <?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>
  • 70. A Phing fairy tale Prompt user for input <?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>
  • 71. A Phing fairy tale Calling PHP functions from Phing <?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>
  • 72. A Phing fairy tale Follow conventions Phing expects your build file to be called build.xml and the build’s properties file build.properties
  • 73. A Phing fairy tale Follow conventions Pick meaningful, human-readable names for targets and properties.
  • 74. A Phing fairy tale Follow conventions Make build files self-contained.