FilterChain Element In Phing

12th January 2009 - 5 minutes read time

The FilterChain element is where the power of Phing really comes into its own. This element will allow you to change the contents of the files of a fileset. This can range from a simple stripping of comments, to replacing values and numerous other filters.

One of the simplest thing that can be done with filterset is to strip all comments from the files in question. Take the following PHP file with two comments.

  1. <?php
  2. /**
  3.  *
  4.  * This is a comment
  5.  *
  6.  *
  7.  **/
  8. echo 'Hello World!';
  9.  
  10. // another comment.

These comments can be stripped out of the file by using the stripphpcomments element. This is added to the copy element in the following way.

  1. <?xml version="1.0"?>
  2. <!-- build xml -->
  3. <project name="myProject" default="main">
  4.  
  5. <fileset dir="./" id="myProjectFiles">
  6. <include name="**/*.php" />
  7. <exclude name="myProject_build/**" />
  8. </fileset>
  9.  
  10. <target name="main">
  11. <copy todir="./myProject_build">
  12. <fileset refid="myProjectFiles" />
  13. <filterchain>
  14. <stripphpcomments />
  15. </filterchain>
  16. </copy>
  17. </target>
  18. </project>

The PHP file now looks like this.

  1. <?php
  2.  
  3. echo 'Hello World!';

Although this might be a nightmare to maintain it might be useful if reducing the size of your files is necessary. You might want to do this if you plan to sell your PHP software as it would make alteration by your customer a little bit more difficult.

Another use of the filterchain is to replace values within the code base. This is useful if you want to set a version number or a default database password. To replace a token with a value you need a property that can will store the value. You then need to go into your source code and replace any instance of the term you want to replace with the property name within @ symbols. Take the following PHP file.

  1. <?php
  2. /**
  3.  *
  4.  * This is a comment
  5.  *
  6.  *
  7.  **/
  8. $property1 = '@[email protected]';
  9. echo 'Hello World!';
  10.  
  11. // another comment.

To replace the myProperty property with the value of "test", you need to use the replacetokens element, which can contain one or more token elements. The following build.xml file will replace all instances of the key myProperty with the value "test".

  1. <?xml version="1.0"?>
  2. <!-- build xml -->
  3. <project name="myProject" default="main">
  4. <property name="myProperty" value="test" />
  5.  
  6. <fileset dir="./" id="myProjectFiles">
  7. <include name="**/*.php" />
  8. <exclude name="myProject_build/**" />
  9. </fileset>
  10.  
  11. <target name="main">
  12. <copy todir="./myProject_build">
  13. <fileset refid="myProjectFiles" />
  14. <filterchain>
  15. <replacetokens>
  16. <token key="myProperty" value="${myProperty}" />
  17. </replacetokens>
  18. </filterchain>
  19. </copy>
  20. </target>
  21. </project>

You will now see in your build output something like the following:

[filter:ReplaceTokens] Replaced "@[email protected]" with "test"

The token in each of the files will now be changed with the value of the property.

To see a list of the core filters available, take a look at the Phing filter appendix on the Phing website. You can even do something odd like only include the first 3 lines from each file, and append each line with the word "wibble".

  1. <filterchain>
  2. <headfilter lines="3" />
  3. <prefixlines prefix="wibble: " />
  4. </filterchain>

I can see why the headfilter might be useful in some instances where you want to test that your build file adds the correct file to each folder/zip file without including the whole thing. But where would you ever need to append a string to every line?

One final thing, if you change anything within your build file that replaces values then remember that phing will save time by not copying across any file that has already been copied and that hasn't changed. This means that if you change a filter and update you will see no changes unless you do one or both of the following:

  • Manually delete any files in the target directories.
  • Add an overwrite attribute to the copy element(s) in your target element(s). This will force phing to simply overwrite the files every time, even if they haven't changed.

Automated Build With Phing

Comments

Permalink

Phil, yet another great Phing article, this one was particularly useful - FilterChains are great, as is ReplaceTokens - currently weighing up our build process and how we can rewrite it with Phing, your blog posts have speeded things up

Michael Leach (Fri, 07/15/2011 - 15:24)

Add new comment

The content of this field is kept private and will not be shown publicly.