{"id":1362,"date":"2012-11-21T22:48:28","date_gmt":"2012-11-21T22:48:28","guid":{"rendered":"http:\/\/www.robertprice.co.uk\/robblog\/?p=1362"},"modified":"2012-11-21T22:48:28","modified_gmt":"2012-11-21T22:48:28","slug":"using-phing-to-deploy-a-php-project","status":"publish","type":"post","link":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/","title":{"rendered":"Using Phing To Deploy A PHP Project"},"content":{"rendered":"<p>Deploying a PHP project to a production or even a staging environment isn&#8217;t always as simple as copying a directory. One project I have been working on recently has benefited from using <a href=\"http:\/\/www.phing.info\/\">Phing<\/a> as a deployment system. To deploy my code, I just have to call a single build script, and let Phing do all the hard work.<\/p>\n<p>So what is Phing? Well Phing is a tool based on <a href=\"http:\/\/ant.apache.org\/\">Apache Ant<\/a>, specifically designed to build PHP projects. It takes an XML file that defines specific tasks and executes them. It is designed to be platform independent so should be at home running on Windows as well as Unix based systems.<\/p>\n<p>Phing is available using PEAR, and can be installed quickly using the following commands&#8230;<\/p>\n<pre>\npear channel-discover pear.phing.info\npear install phing\/phing\n<\/pre>\n<h2>Hello World! In Phing<\/h2>\n<p>It wouldn&#8217;t be an overview without a Hello World example. Save the following as <var>build.xml<\/var>.<\/p>\n<pre>\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project name=\"helloworld\" basedir=\".\" default=\"helloworld\">\n    <target name=\"helloworld\">\n        <echo msg=\"Hello World!\" \/>\n    <\/target>\n<\/project>\n<\/pre>\n<p>Now let&#8217;s run this, we just call <code>phing<\/code> on the command line, and we get something like this back.<\/p>\n<pre>\nrob@lamp \/tmp\/helloworld> phing\nBuildfile: \/tmp\/helloworld\/build.xml\n\nhelloworld > helloworld:\n\n     [echo] Hello World!\n\nBUILD FINISHED\n\nTotal time: 0.0487 seconds\n\nrob@lamp \/tmp\/helloworld>\n<\/pre>\n<p>So what is going on? Well in the <code>project<\/code> element we have a default setting of &#8220;helloworld&#8221;. This tells Phing the target to call by default. We can call this on the command line as well, <code>phing helloworld<\/code>, so if we have multiple tasks we can create a target for each of those. As you can see we only have a target of &#8220;helloworld&#8221; in our example. Inside the target we have tasks. In this example, we have a single <a href=\"http:\/\/www.phing.info\/docs\/guide\/stable\/chapters\/appendixes\/AppendixB-CoreTasks.html#EchoTask\">EchoTask<\/a> that just prints out the message &#8220;Hello World!&#8221;.<\/p>\n<h2>Adding A Clean Up<\/h2>\n<p>There is so much more Phing can do that just print Hello World!. One of the common tasks you may have is to cleanup a deployment directory. Let&#8217;s assume you have a <var>build<\/var> directory, when you call <code>phing clean<\/code> you want this to be removed. We can add a simple task to do this to our <var>build.xml<\/var>.<\/p>\n<pre>\n<property name=\"builddir\" value=\".\/build\"\/>\n<target name=\"clean\">\n    <echo msg=\"Clean...\" \/>\n    <delete dir=\"${builddir}\" \/>        \n<\/target>\n<\/pre>\n<p>As you can see, as well as adding a target called &#8220;clean&#8221;, I&#8217;ve also added a property called &#8220;builddir&#8221; with the value &#8220;.\/build&#8221;. I can access this later as variable, so when I call the <a href=\"http:\/\/www.phing.info\/docs\/guide\/stable\/chapters\/appendixes\/AppendixB-CoreTasks.html#DeleteTask\">DeleteTask<\/a>, I can reference this value using <code>${builddir}<\/code>, and Phing will delete the directory .\/build.<\/p>\n<p>Create an empty directory called <var>build<\/var> and run this using <code>phing clean<\/code>.<\/p>\n<pre>\nrob@lamp \/tmp\/helloworld> phing clean\nBuildfile: \/tmp\/helloworld\/build.xml\n\nhelloworld > clean:\n\n     [echo] Clean...\n\nBUILD FINISHED\n\nTotal time: 0.0493 seconds\n\nrob@lamp \/tmp\/helloworld>\n<\/pre>\n<p>When you check the contents of your working directory you should have found the <var>build<\/var> directory has been deleted.<\/p>\n<h2>Adding A Deployment Target<\/h2>\n<p>Deployment is the area where Phing really comes into it&#8217;s own. Let&#8217;s create a target that creates a <var>build<\/var> directory then uploads the contents of that via FTP to a remote server.<\/p>\n<pre>\n<target name=\"deploy\">\n    <echo msg=\"preparing local build directory...\" \/>\n    <delete dir=\"${builddir}\" \/>\n    <mkdir dir=\"${builddir}\" \/>\n    <copy todir=\"${builddir}\" overwrite=\"true\">\n        <fileset dir=\".\/\" id=\"Files\">\n            <include name=\"**\" \/>\n            <exclude name=\"build\/\" \/>\n            <exclude name=\"build.*\" \/>\n            <exclude name=\"docs\/\" \/>\n            <exclude name=\"tests\/\" \/>\n        <\/fileset>\n    <\/copy>\n\n    <echo msg=\"FTPing up build...\" \/>\n    <ftpdeploy\n        host=\"${ftp.destination.host}\"\n        port=\"${ftp.destination.port}\"\n        username=\"${ftp.destination.username}\"\n        password=\"${ftp.destination.password}\"\n        dir=\"${ftp.destination.dir}\"\n        mode=\"${ftp.destination.mode}\" >\n        <fileset dir=\"${builddir}\">\n            <include name=\"**\" \/>\n        <\/fileset>\n    <\/ftpdeploy>\n\n    <echo msg=\"Site deployed...\" \/>\n<\/target>\n<\/pre>\n<p>We&#8217;re doing a few things here, first we are deleting the <var>${builddir}<\/var>, and creating it from scratch to ensure it is clean. Then we are copying all the files in the current directory across, except for the build directory, any build file with any extension, the docs directory and the tests directory. Then we are FTP&#8217;ing up the contents of the <var>${builddir}<\/var> using a <a href=\"http:\/\/www.phing.info\/docs\/guide\/stable\/chapters\/appendixes\/AppendixC-OptionalTasks.html#FtpDeployTask\">FTPDeployTask<\/a>. Assume I have already set a selection of FTP variables earlier using the same syntax as earlier when I defined <var>${builddir}<\/var>.<\/p>\n<p>OK, so that is useful, but there are other useful things that could be done as part of the process. We may want our JavaScript minified on production, but not when we are developing. We can add a task to do this as part of the deploy using the <a href=\"http:\/\/www.phing.info\/docs\/guide\/stable\/chapters\/appendixes\/AppendixC-OptionalTasks.html#JsMinTask\">JSMinTask<\/a>. <\/p>\n<p>There are plenty of other tasks that can be usefully integrated, such as running <code>phpcs<\/code> to ensure your code is meeting coding standards, building your documentation using <code>phpdocumentor<\/code>, running your <code>phpunit<\/code> unit tests. If anything fails you can prevent the deployment and stop your site breaking unnecessarily.<\/p>\n<h2>Summary<\/h2>\n<p>This has just been a quick overview of how to use Phing. We&#8217;ve seen various simple tasks take place, and we&#8217;ve seen we can easily add more tasks to increase functionality and usefulness. In the real world adding tests to check your code before it gets deployed is essential and prevents silly errors hitting your production environment. Taking the time to write a build script will also save you time in the future when you come to make changes to your site and you can&#8217;t quite remember how your production environment was setup. Using Phing, you just have to run your build script.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Deploying a PHP project to a production or even a staging environment isn&#8217;t always as simple as copying a directory. One project I have been working on recently has benefited from using Phing as a deployment system. To deploy my code, I just have to call a single build script, and let Phing do all &hellip; <a href=\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using Phing To Deploy A PHP Project&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[2],"tags":[49,50],"class_list":["post-1362","post","type-post","status-publish","format-standard","hentry","category-dev","tag-phing","tag-php"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using Phing To Deploy A PHP Project - Robert Price<\/title>\n<meta name=\"description\" content=\"An overview on using Phing to deploy PHP projects, and carry out various useful tasks.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Phing To Deploy A PHP Project - Robert Price\" \/>\n<meta property=\"og:description\" content=\"An overview on using Phing to deploy PHP projects, and carry out various useful tasks.\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\" \/>\n<meta property=\"og:site_name\" content=\"Robert Price\" \/>\n<meta property=\"article:published_time\" content=\"2012-11-21T22:48:28+00:00\" \/>\n<meta name=\"author\" content=\"rob\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rob\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/#article\",\"isPartOf\":{\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\"},\"author\":{\"name\":\"rob\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"headline\":\"Using Phing To Deploy A PHP Project\",\"datePublished\":\"2012-11-21T22:48:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\"},\"wordCount\":725,\"keywords\":[\"Phing\",\"PHP\"],\"articleSection\":[\"Dev\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\",\"url\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\",\"name\":\"Using Phing To Deploy A PHP Project - Robert Price\",\"isPartOf\":{\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/#website\"},\"datePublished\":\"2012-11-21T22:48:28+00:00\",\"author\":{\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"description\":\"An overview on using Phing to deploy PHP projects, and carry out various useful tasks.\",\"breadcrumb\":{\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\/\/www.robertprice.co.uk\/robblog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Phing To Deploy A PHP Project\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/#website\",\"url\":\"http:\/\/www.robertprice.co.uk\/robblog\/\",\"name\":\"Robert Price\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/www.robertprice.co.uk\/robblog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5\",\"name\":\"rob\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"caption\":\"rob\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using Phing To Deploy A PHP Project - Robert Price","description":"An overview on using Phing to deploy PHP projects, and carry out various useful tasks.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/","og_locale":"en_GB","og_type":"article","og_title":"Using Phing To Deploy A PHP Project - Robert Price","og_description":"An overview on using Phing to deploy PHP projects, and carry out various useful tasks.","og_url":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/","og_site_name":"Robert Price","article_published_time":"2012-11-21T22:48:28+00:00","author":"rob","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rob","Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/#article","isPartOf":{"@id":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/"},"author":{"name":"rob","@id":"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"headline":"Using Phing To Deploy A PHP Project","datePublished":"2012-11-21T22:48:28+00:00","mainEntityOfPage":{"@id":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/"},"wordCount":725,"keywords":["Phing","PHP"],"articleSection":["Dev"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/","url":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/","name":"Using Phing To Deploy A PHP Project - Robert Price","isPartOf":{"@id":"http:\/\/www.robertprice.co.uk\/robblog\/#website"},"datePublished":"2012-11-21T22:48:28+00:00","author":{"@id":"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"description":"An overview on using Phing to deploy PHP projects, and carry out various useful tasks.","breadcrumb":{"@id":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/www.robertprice.co.uk\/robblog\/using-phing-to-deploy-a-php-project\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/www.robertprice.co.uk\/robblog\/"},{"@type":"ListItem","position":2,"name":"Using Phing To Deploy A PHP Project"}]},{"@type":"WebSite","@id":"http:\/\/www.robertprice.co.uk\/robblog\/#website","url":"http:\/\/www.robertprice.co.uk\/robblog\/","name":"Robert Price","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/www.robertprice.co.uk\/robblog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5","name":"rob","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"http:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","caption":"rob"}}]}},"_links":{"self":[{"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/1362","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/comments?post=1362"}],"version-history":[{"count":0,"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/1362\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/media?parent=1362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/categories?post=1362"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/tags?post=1362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}