<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Mayflower Blog - PHP</title>
    <link>http://blog.mayflower.de/</link>
    <description>the php &amp; javascript experts</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.5.3 - http://www.s9y.org/</generator>
    <pubDate>Fri, 03 Feb 2012 20:24:39 GMT</pubDate>

    <image>
        <url>http://blog.mayflower.de/templates/mayflower/img/s9y_banner_small.png</url>
        <title>RSS: Mayflower Blog - PHP - the php &amp; javascript experts</title>
        <link>http://blog.mayflower.de/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Zend Framework application.ini Cheat-Sheet</title>
    <link>http://blog.mayflower.de/archives/828-Zend-Framework-application.ini-Cheat-Sheet.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/828-Zend-Framework-application.ini-Cheat-Sheet.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=828</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=828</wfw:commentRss>
    

    <author>nospam@example.com (Florian Eibeck)</author>
    <content:encoded>
    &lt;p&gt;With the release of Zend Framework 1.8 came the long awaited component for bootstrapping a Zend Framework application. Many different bootstrapping-solutions became obsolete with Zend_Application.&lt;/p&gt; &lt;br /&gt; 
&lt;p&gt;In the beginning of the framework most developers didnt give much thought on bootstrapping. Most of the initialisation work was done directly in index.php, the central starting point of the application. Teams often moved that bootstrapping code to a separate configuration script. The solution worked, but many people wanted a more standardised process for application initialisation.&lt;/p&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/828-Zend-Framework-application.ini-Cheat-Sheet.html#extended&quot;&gt;Continue reading &quot;Zend Framework application.ini Cheat-Sheet&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Fri, 03 Feb 2012 10:01:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/828-guid.html</guid>
    <category>php</category>
<category>zend framework</category>
<category>zf</category>

</item>
<item>
    <title>24.12. PHP and the Lean Startup</title>
    <link>http://blog.mayflower.de/archives/819-24.12.-PHP-and-the-Lean-Startup.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/819-24.12.-PHP-and-the-Lean-Startup.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=819</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=819</wfw:commentRss>
    

    <author>nospam@example.com (johann)</author>
    <content:encoded>
    &lt;p&gt;About ten years ago there was a rumour. If you want to get things done, and if you want to get them done fast, go for PHP. Yes, it&#039;s been like a badly done perl ripoff with even worse object orientation and inconsistent apis, but somehow the people creating in software in PHP were able to deliver. And they were able to deliver fast, open for changes in the last 24 hours and they fixed bugs in production fast. From a software engineering professionals point of view this sounded risky, unprofessional and dangerous. This could only lead to crappy code. A proper software engineer would never use this language, and he won&#039;t ever accept changes in the last minute nor work with a customer that does not know exactly what he wants. &lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/819-24.12.-PHP-and-the-Lean-Startup.html#extended&quot;&gt;Continue reading &quot;24.12. PHP and the Lean Startup&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Sat, 24 Dec 2011 14:47:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/819-guid.html</guid>
    
</item>
<item>
    <title>21.12. Agile Developer Skills (ADS)</title>
    <link>http://blog.mayflower.de/archives/817-21.12.-Agile-Developer-Skills-ADS.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/817-21.12.-Agile-Developer-Skills-ADS.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=817</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=817</wfw:commentRss>
    

    <author>nospam@example.com (Nina Schmitt)</author>
    <content:encoded>
    &lt;p&gt;Last week I had the chance to attend an Agile Developer Skills Workshop in Berlin.&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;The 3 day workshop is, next to a Scrum Master or PO Certification, a prerequisite  for the &lt;strong&gt;Certified Scrum Developer&lt;/strong&gt;, short CSD.&lt;/p&gt; 
&lt;br /&gt;
&lt;p&gt;I was very excited about the ADS workshop and I found it an intersting approach to hold a workshop which focusses on developers rather than on the management side of scrum.  Especially as in my experience all the other scrum workshops mainly concentrate on the rituals, artefacts and organisation of Scrum, without giving answers on how to develop high quality software.&lt;p&gt;
&lt;br /&gt;



 &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/817-21.12.-Agile-Developer-Skills-ADS.html#extended&quot;&gt;Continue reading &quot;21.12. Agile Developer Skills (ADS)&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Wed, 21 Dec 2011 08:00:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/817-guid.html</guid>
    <category>ads</category>
<category>agile</category>
<category>agile developer skills</category>
<category>agile entwicklung</category>
<category>architecture</category>
<category>certified scrum developer</category>
<category>collaboration</category>
<category>continuous-integration</category>
<category>csd</category>
<category>java</category>
<category>php</category>
<category>refactoring</category>
<category>scrum</category>
<category>tdd</category>
<category>test</category>
<category>test driven development</category>
<category>workshop</category>

</item>
<item>
    <title>19.12. Test Driven JavaScript Development</title>
    <link>http://blog.mayflower.de/archives/816-19.12.-Test-Driven-JavaScript-Development.html</link>
            <category>Development</category>
            <category>JavaScript</category>
            <category>Labs</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/816-19.12.-Test-Driven-JavaScript-Development.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=816</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=816</wfw:commentRss>
    

    <author>nospam@example.com (Martin Ruprecht)</author>
    <content:encoded>
    &lt;p&gt;
A couple of weeks ago, I was attending a three-day workshop for agile developer skills. The workshop was split into five topics: Colaboration, Refactoring, Design &amp;amp; Architecture, Continious Integration and Test Driven Development. Especially the session about Test Driven Development was very interesting. Although I know the principles of TDD I was really impressed by the demonstration of solving a simple exercise (a coding kata) done in Java by the instructors of the workshop. It was not so much the coding in Java that was interesting for me, it was the combination of writing a test, executing the test with a shortcut from the IDE, see the test fail, write the implementation and re-start the test again within the IDE. You will say that´s test driven development- it´s nothing new! and you are right! But is there a way to do Test Driven Development in the same way for JavaScript? I mean writing a test, execute the tests with a shortcut from the IDE, see the test fail, implement the method and re-start the test? Yes, there is a way! So let me show you what I have done to do the same coding kata (called Fizzbuzz) with JavaScript.
&lt;/p&gt;
 &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/816-19.12.-Test-Driven-JavaScript-Development.html#extended&quot;&gt;Continue reading &quot;19.12. Test Driven JavaScript Development&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Sun, 18 Dec 2011 22:26:27 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/816-guid.html</guid>
    <category>agile</category>
<category>agile entwicklung</category>
<category>best practises</category>
<category>code</category>
<category>development</category>
<category>javascript</category>
<category>refactoring</category>
<category>tdd</category>
<category>test driven development</category>
<category>unittests</category>
<category>web2.0</category>

</item>
<item>
    <title>18.12. Cloud2Go Services for your web development</title>
    <link>http://blog.mayflower.de/archives/814-18.12.-Cloud2Go-Services-for-your-web-development.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/814-18.12.-Cloud2Go-Services-for-your-web-development.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=814</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=814</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Hallmann)</author>
    <content:encoded>
    &lt;em&gt;From simple to full featured cloud capacity&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Cloud technologies and services increase every day. Global players like Amazon &lt;strong&gt;put continuously new features to their cloud&lt;/strong&gt; and products to provide sufficiently functionality of actually web development activities and requirements.&lt;/p&gt;
&lt;br/&gt;
&lt;em&gt;Services for us&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;In fact, Amazon starts with the &lt;strong&gt;S3&lt;/strong&gt; (Simple Storages Service) to provide cloud storage space since &lt;strong&gt;2006&lt;/strong&gt; and only a few months later &lt;strong&gt;EC2&lt;/strong&gt; (Elastic Compute Cloud) was launched a service to provide computing power to manage capacity as many as we need over time. Now, &lt;strong&gt;RDS&lt;/strong&gt; (Relational Database Service) is available to get elastic database power as much as we need to cover all components that we require to implement the whole stack of current web applications.&lt;/p&gt;
&lt;br/&gt;
&lt;em&gt;Liquid applications&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Use that services to transform the development and of course every application in a liquid and full dynamic status. Every service&lt;strong&gt; increase productivity&lt;/strong&gt; and can be used to cover architecture requirements in sufficient way. That means, use every service as long as we need and &lt;strong&gt;allocate capacity as many as we need&lt;/strong&gt; in the finest way up to &lt;strong&gt;100%&lt;/strong&gt; not more, not less to reduce resources and costs.&lt;/p&gt;
&lt;br/&gt;
&lt;em&gt;Swim a little bit around&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Ok let us start to introduce each important service below to get more details and show examples what we have to do to use these services. Amazon provides a &lt;strong&gt;SDK especially for PHP developers&lt;/strong&gt; to connect each service. You can download the SDK under the following URL:&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;http://aws.amazon.com/sdkforphp/&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;To start, download and install the SDK to your destination directory in your application root folder. Before we can start edit the configuration file and change the privacy settings with your AWS (Amazon Web Services) credentials (see Listing 1). To get credentials please create an AWS account on:&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;http://aws.amazon.com/de/ and follow the instructions.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;69&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/aws_credentials.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;S3&lt;/h2&gt;
&lt;br/&gt;
&lt;em&gt;Store data in S3 and handle it similar to our local storages&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;S3&lt;/strong&gt; is the storages service from Amazon where we can store (&lt;strong&gt;C&lt;/strong&gt;reate), retrieve (&lt;strong&gt;R&lt;/strong&gt;ead), overwrite (&lt;strong&gt;U&lt;/strong&gt;pdate) and remove (&lt;strong&gt;D&lt;/strong&gt;elete) data. The logical structure based on &lt;strong&gt;buckets&lt;/strong&gt; that &lt;strong&gt;contains items&lt;/strong&gt; like files e.g. &lt;strong&gt;images&lt;/strong&gt;, &lt;strong&gt;videos&lt;/strong&gt; or &lt;strong&gt;documents&lt;/strong&gt; or any data that we want to store. Buckets must have a unique developer-assigned key across the account each item can be contain 1 byte up to 5 terabytes.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;221&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/create_bucket.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;em&gt;Create our bucket&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;First, to store our objects we create a bucket with the method &lt;strong&gt;create_bucket&lt;/strong&gt;. All what we have to do is specify a name of the bucket testbucket and the region where we want to create it. In our case the region is EU_E1 (European 1- Region). Additionally, a simple if check covers the return value whether the call was correct.&lt;/p&gt;
&lt;br/&gt;
&lt;em&gt;Store our private data&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;In the next step, we put files to the bucket and store some data to the cloud. Simply, call the &lt;strong&gt;create_object&lt;/strong&gt; method to handle our request.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;144&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/create_object.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Listing 3 shows the PHP snippet to create a test file. Call the method with the bucket name testbucket, name of the file testfile.txt and some additional parameters in our case body, acl and contentType to specify the characteristic of our data.&lt;/p&gt;
&lt;br/&gt;
&lt;em&gt;Get data from the cloud storage&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Now we want to get back our stored data. To finalize that request we have to use the method get_object.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;85&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/get_object.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Listing 4 visualizes that request and shows the method call with the parameters testbucket that is our bucket name and the name (key) of the file testfile.txt where our data will be stored.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Execute our get_object.php file and receive the entire string from the cloud storage for further use.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;61&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/execute_data.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Listing 5 covers our example and echoed the string that we have inserted a few minutes before.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;To see it is very simple to communicate to our cloud storage with the SDK and execute the proper methods. If you do not know the right method take a look in the library service file where every single method is described well that enclose every required parameter and excepted return values.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;EC2&lt;/h2&gt;
&lt;br/&gt;
&lt;em&gt;Allocate computing resources as much as we need&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;EC2&lt;/strong&gt; is the next create cloud services that we can use to allocate computing resources for our web environment. Through defined methods from the SDK and the proper service file you can easily start an &lt;strong&gt;AMI&lt;/strong&gt; (Amazon Machine Image) with an &lt;strong&gt;operating system that match our requirements&lt;/strong&gt;. There are images from the market leaders like &lt;strong&gt;Linux&lt;/strong&gt; and &lt;strong&gt;Windows&lt;/strong&gt; systems and you can upload an own image as well whether you need a &lt;strong&gt;self defined system&lt;/strong&gt; e.g. pre-installed web, db or chat server. Please go to the Amazon website:&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;http://aws.amazon.com/ec2/&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;to see which kind of images are available that fits your requirements. After we have chosen a suitable images we can start it with a method call from the SDK similar create a bucket in S3.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;129&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/run_instances.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Listing 6 shows that method call &lt;strong&gt;run_instances&lt;/strong&gt; with the parameter ami-48aa4921 with specifies the machine images that will be loaded and some optional parameters in that case the type of the underlying hardware configuration which is specified by m1.micro instance - currently the smallest type with 2 processor kernels (CPUs) - and round about 613MB RAM. Check the response value with the method &lt;strong&gt;isOk&lt;/strong&gt;. If everything is fine we can connect our recently started machine through a secure shell.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;611&quot; height=&quot;57&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/access_to_our_machine.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Listing 7 visualize a connection to the virtual machine that we have started. We need only our private key that you can download from the AWS account and the hostname of the machine that you can find on the EC2 overview simply go to the AWS website:&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;http://aws.amazon.com/ec2/.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;After the login (see Listing 8) we see our secure shell of the machine where we can input commands like on our self administrated local systems.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;229&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/console_after_login.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Similar S3, EC2 is also pretty easy to use with some SDK commands like run_instances that helps us to integrate this service into our web application. You need only a valid AWS account (key credentials) to access the service, a machine image like ami-48aa4921 and a proper instance type e.g. m1.micro with sufficient processor and memory power.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;RDS&lt;/h2&gt;
&lt;br/&gt;
&lt;em&gt;RDS a service to handle relational database capacity&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;The final service that we want to cover is the &lt;strong&gt;RDS&lt;/strong&gt; service the third part to complete our web environment stack. It is also pretty easy to use it with the SDK. Call only a single method to start a new RDS instance and connect to the machine.&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;129&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/create_a_database_instance.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;See Listing 9 to show an example how to create a database instance. Execute simple the method &lt;strong&gt;create_db_instance&lt;/strong&gt; with the parameter testinstance the name of the instance, 5 specifies the size of the db storages in GB, db.m1.small clarifies the size of the underlying instance type (varies in processor and memory power), MySQL the type of the database system, testuser a user name and testpassword the password to connect the database. Check also with the isOk method the response value to guarantee the availability of the system.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Now we can connect to our new instantiated database through a secure shell. Input only the following known MySQL client command to connect. Specify the user name, password and the database host (see Listing 10).&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;61&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/connect_to_out_database.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;p&gt;After we have connected to the database server we will see the start screen where we can input commands (see Listing 11).&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;117&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/mysql_console.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;p&gt;Check out which tables are available and execute the &lt;strong&gt;show databases&lt;/strong&gt; command. Additionally, show all tables in the MySQL database with the &lt;strong&gt;show tables&lt;/strong&gt; command (see Listing 12).&lt;/p&gt;
&lt;br/&gt;
&lt;img class=&quot;serendipity_image_center&quot; width=&quot;623&quot; height=&quot;344&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/working_with_our_db_instance.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;em&gt;What happens at the cloud front?&lt;/em&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;In this blog post we have &lt;strong&gt;cover common cloud services&lt;/strong&gt; from the Amazon service. S3, EC2 and the RDS are services to &lt;strong&gt;extend and of course to replace current development architectures&lt;/strong&gt; where normally dedicated machines and systems work. With the SDK it is very simple to connect all the services, request commands and response values e.g. S3 items. These proposed services cover a small overview about available services. There are much more excellent functionalities we can use to integrate.&lt;/p&gt;
&lt;br/&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt; and &lt;strong&gt;ELB&lt;/strong&gt; (Elastic Load Balancer) combined work as a service to &lt;strong&gt;measure system values&lt;/strong&gt; e.g. processor load, RAM utilization and control capacity. &lt;strong&gt;Start more or stop EC2 machines&lt;/strong&gt; to balance the current load up to &lt;strong&gt;100%&lt;/strong&gt;.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;SimpleDB&lt;/strong&gt; is an additional database service that based on a key value store without any relation between items unlike relational database systems. Handle data in domains similar buckets in S3 and retrieve values with proper SQL statements.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Last but not least, &lt;strong&gt;SQS&lt;/strong&gt; (Simple Queue Service) integrate a SOA service. Loosely coupled items communicate through defined interfaces. Add values to a queue at one application point and retrieve items on another. Works asynchronous and can be used to handle jobs that &lt;strong&gt;converts large data like image or video rendering&lt;/strong&gt;. Thank you for your attention to read until the end ;-) if you have any comments please add your notes and ideas after that post.&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sun, 18 Dec 2011 08:00:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/814-guid.html</guid>
    
</item>
<item>
    <title>17.12. Zend Framework (1) vs. Symfony2</title>
    <link>http://blog.mayflower.de/archives/808-17.12.-Zend-Framework-1-vs.-Symfony2.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/808-17.12.-Zend-Framework-1-vs.-Symfony2.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=808</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=808</wfw:commentRss>
    

    <author>nospam@example.com (Paul Seiffert)</author>
    <content:encoded>
    &lt;style&gt;
    .serendipity_entry h1 {
        font-size: 20px;
        margin: 13px 0;
    }

    .serendipity_entry h2 {
        margin: 7px 0;
    }

    .serendipity_entry ul {
        padding-left: 3em;
    }

    .gist-data {
        max-height: 250px;
        overflow: auto;
    }
&lt;/style&gt;

&lt;p&gt;
	In this article, I want to highlight some differences between the two PHP frameworks that have been the most popular ones at the time of writing.
	Zend Framework (ZF) is currently a quasi-standard in many PHP companies and Symony2&#039;s popularity is constantly increasing. Symfony2 is pretty new now and many developers are thinking about if and when to make the switch from ZF to Symfony2 which is why I think we should spend time looking at the frameworks&#039; differences.&lt;br /&gt;
I selected three topics that are implemented differently in these frameworks and will describe how each of them does it. 
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Project Setup&lt;/h2&gt;

&lt;p&gt;
	I took the setup of new projects as one category of comparison because it is an important to make this step as easy as possible for developers that are learning a new framework. In my opinion, the adoption time of a new technology somehow correlates with the easiness of starting a project with using this technology.
&lt;/p&gt;

&lt;h3&gt;Zend Framework Project Setup&lt;/h3&gt;

&lt;p&gt;
	To set up a Zend Framework (ZF) project, download the framework&#039;s &lt;a href=&quot;http://framework.zend.com/download/latest&quot; title=&quot;ZF download page&quot;&gt;minimal package&lt;/a&gt; and extract it to an empty directory. You will see two new folders: &lt;code&gt;bin&lt;/code&gt; and &lt;code&gt;library&lt;/code&gt;. To initialize the project structure, run the included cli script in the project directory like this: &lt;br /&gt;&lt;br /&gt;
	&lt;code&gt;php bin/zf.php create project .&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;
	When you now go to &lt;code&gt;http://&amp;lt;hostname&amp;gt;/&lt;/code&gt; with your web browser, you see a blue welcome page which indicates that the installation was successful. To configure a database connection, you will have to manually edit the file &lt;code&gt;application/configs/application.ini&lt;/code&gt; and add the following lines to the &lt;code&gt;[production]&lt;/code&gt; environment.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461948.js?file=ZF%20DB%20configuration&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
	After this step, you have a fully functional Zend Framework project which can be configured using different environments. The next step is to implement custom controllers, views and model classes.
&lt;/p&gt;

&lt;h3&gt;Symfony2 Project Setup&lt;/h3&gt;

&lt;p&gt;
	Setting up a project with Symfony2 is pretty easy. You start by &lt;a href=&quot;http://symfony.com/download&quot; title=&quot;Symfony2 Download page&quot;&gt;downloading&lt;/a&gt; a copy of the &lt;i&gt;Symfony2 Standard Edition&lt;/i&gt;, extract it to an empty directory and can start to configure your project. However your system has to fulfill some requirements which can be checked by running the script &lt;code&gt;check.php&lt;/code&gt; in the &lt;code&gt;app&lt;/code&gt; folder (just run &lt;code&gt;php check.php&lt;/code&gt; in the command line). When all requirements are fulfilled (and you created a virtual host with its &lt;code&gt;DocumentRoot&lt;/code&gt; pointing to the project&#039;s &lt;code&gt;web&lt;/code&gt; directory), you can navigate your browser to &lt;code&gt;http://&amp;lt;hostname&amp;gt;/config.php&lt;/code&gt; and configure the project via a fancy web UI. After checking all requirements again, the Symfony2 sandbox asks you to enter your database configuration which will be written to a configuration file afterwards. The sandbox also includes a sample page where you can see that everything is up and running: &lt;code&gt;http://&amp;lt;hostname&amp;gt;/app_dev.php/demo/hello/World&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;
	To use the sandbox for a real project, I suggest removing the demo pages visited before. Remove the line registering the demo bundle from the file &lt;code&gt;app/AppKernel.php&lt;/code&gt; and the demo bundle&#039;s router configuration from &lt;code&gt;app/config/routing_dev.yml&lt;/code&gt;. Last you can delete the bundle&#039;s folder &lt;code&gt;src/Acme&lt;/code&gt;.
&lt;/p&gt;
&lt;br /&gt;
&lt;b&gt;app/AppKernel.php&lt;/b&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461955.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;b&gt;app/routing_dev.yml&lt;/b&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461961.js?file=gistfile1.yml&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
	To be able to define different database connection parameters for the various environments (as with ZF), copy the file &lt;code&gt;app/config/parameters.ini&lt;/code&gt; to (this example uses the environment &lt;i&gt;dev&lt;/i&gt;, of course you can to the same for any other environment!) &lt;code&gt;app/config/parameters_dev.ini&lt;/code&gt; and adjust the other config files accordingly:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461969.js?file=gistfile1.yml&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461971.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461974.js?file=gistfile1.yml&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;h3&gt;Project Setup - Conclusion&lt;/h3&gt;

&lt;p&gt;
	The initialization process of a new project is very easy with both of the compared frameworks. One benefit of ZF is that it eases the differentiation between different environments when it comes to configuration - all configuration options can appear in one file in multiple configuration environments that inherit default values from other environments in a defined hierarchy. With Symfony2 you have to create a separate config file and include it into your project&#039;s configuration as described above.&lt;br /&gt;
	Symfony2 on the other hand comes with a nice example bundle that contains a sample configuration, controllers, views and even a very basic authentication infrastructure which can be used as template for your own bundles. Of course, the initial project structure of a ZF project has some default controllers as well, but they don&#039;t show you how to configure e.g. security.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Model View Controller&lt;/h2&gt;

&lt;p&gt;
	The &lt;a href=&quot;http://martinfowler.com/eaaDev/uiArchs.html#ModelViewController&quot; target=&quot;_blank&quot; title=&quot;MVC explained by Martin Fowler&quot;&gt;Model View Controller&lt;/a&gt; (MVC) pattern is one of the basic structural patterns used in application development. It basically applies the concept of &lt;i&gt;Separation of Concerns&lt;/i&gt; to the structure of applications in a way that separates business logic (Model), the rendering of user interfaces (View) and user interaction handling (Controller) from each other. Most object-oriented frameworks provide scaffolding for MVC implementations - so do Zend Framework and Symfony2. Let&#039;s have a look how MVC is applied in both cases.
&lt;/p&gt;

&lt;h3&gt;MVC in Zend Framework Projects&lt;/h3&gt;

&lt;p&gt;
	In a classical project infrastructure, ZF projects use controllers that contain multiple actions. Every HTTP request sent to the application is being handled by one (in some cases also multiple) controller&#039;s action and most of the times, one action is mapped to one view (This is of course due to the fact that in the WWW, user interaction required a reload of the complete web page - at least for a long time. Nowadays, many web pages (so-called single-page- or Ajax-applications) do not need reloads to change the displayed data and views.).&lt;br /&gt;
	Views are implemented as templates that contain HTML markup code with inlined PHP snippets. To pass data to a view, the controller has to set this data as a member variable on its view. In the view script you can later access this data by using &lt;code&gt;$this-&gt;variable&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
	In web development, the term &lt;i&gt;Model Class&lt;/i&gt; is often mistaken for &lt;i&gt;Persistent Entity Class&lt;/i&gt;. Model objects do not only represent data stored in a database, but should also contain all the business logic of your applications. I have seen many applications that do all the logic inside of controller classes and only use models to have an abstraction over the database.&lt;br /&gt;
	ZF cannot force you to have model classes for all your logic and it also does not try to do so. What it does is giving you a utility for implementing your database abstraction: &lt;code&gt;Zend_Db&lt;/code&gt;. &lt;br /&gt;
	&lt;code&gt;Zend_Db&lt;/code&gt; is a component of ZF that provides several APIs to access databases and have an abstraction for persistent records. In times of &lt;a href=&quot;http://blog.mayflower.de/archives/792-05.12.-Doctrine-2.html&quot; title=&quot;My article about Doctrine 2&quot; target=&quot;_blank&quot;&gt;Doctrine 2&lt;/a&gt;, I would suggest neither to learn the use of &lt;code&gt;Zend_Db&lt;/code&gt; nor to implement a custom database abstraction. Doctrine 2 can be integrated into ZF projects very easily as you can look up in my &lt;a href=&quot;http://blog.mayflower.de/archives/799-06.12.-Doctrine-2-Zend-Framework-Integration.html&quot; title=&quot;My article about Doctrine 2 in ZF projects&quot; target=&quot;_blank&quot;&gt;article from December 6th&lt;/a&gt; and it probably will do a better and more efficient job than a custom solution, too.
&lt;/p&gt;

&lt;p&gt;
	Besides my own affinity for Doctrine 2, there are several impartial reasons for not using &lt;code&gt;Zend_Db&lt;/code&gt;. In my opinion, the biggest disadvantage is that to add custom logic to your entity objects, you end up writing subclasses of &lt;code&gt;Zend_Db_Table_Row_Abstract&lt;/code&gt;. This is a thing I really don&#039;t like. Dealing with business logic entities that map the application domain should not require you to think about persistence at all (espacially not to subclass a certain class just to make your objects persistable)! You might say &quot;but this is &lt;i&gt;Active Record&lt;/i&gt;!&quot; now. Yes, you are right - &lt;code&gt;Zend_Db_Table_Row&lt;/code&gt; implements the &lt;a href=&quot;http://martinfowler.com/eaaCatalog/activeRecord.html&quot; title=&quot;Martin Fowler - Active Record&quot; target=&quot;_blank&quot;&gt;Active Record&lt;/a&gt; pattern. But: Active Record has not heard a word about separation of concerns. Hence it is just a collection of &lt;a href=&quot;http://kore-nordmann.de/blog/why_active_record_sucks.html&quot; title=&quot;Kore Nordmann - Why active record sucks&quot; target=&quot;_blank&quot;&gt;bad OO code&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;MVC in Symfony2 Projects&lt;/h3&gt;

&lt;p&gt;
	Using Symfony2, you split your application into one or more bundles. Each bundle has its own controller and model classes, configuration and views. Similar to ZF&#039;s modules, controllers and the related model classes are grouped into bundles together with views used by these controllers. This way it is easy to reuse code from other projects by just copying the required bundle.&lt;br /&gt;
	One difference regarding controllers is the definition of the term &lt;i&gt;controller&lt;/i&gt; in Symfony2: &lt;i&gt;A controller is a PHP function that houses all the logic necessary to return a Response object that represents a particular page.&lt;/i&gt; (from the &lt;a href=&quot;http://symfony.com/doc/2.0/glossary.html&quot; target=&quot;_blank&quot; title=&quot;Symfony2 Gloassary&quot;&gt;Symfony2 Glossary&lt;/a&gt;)&lt;br /&gt;
	Thus a controller does not have to be a full-blown class with differnt actions but only a function handling a specific type of requests. Inside your controller functions, you have to create and return a &lt;code&gt;Response&lt;/code&gt; object. How you do this is up to you. There are cases in which you use a templating language (Symfony2 comes with &lt;a href=&quot;http://twig.sensiolabs.org/&quot; target=&quot;_blank&quot; title=&quot;Twig homepage&quot;&gt;Twig&lt;/a&gt; which might take some getting used to it but is very powerful eventually) for rendering HTML but you can always just serialize some data to provide it via a REST API, too.&lt;br /&gt;
	As with ZF, views are implemented using templates in Symfony2. To use a template, you call the &lt;code&gt;render&lt;/code&gt; method in your controller and pass all data required to replace the placeholders in the template. The &lt;code&gt;render&lt;/code&gt; method will create a &lt;code&gt;Response&lt;/code&gt; object for you which can be returned by your action directly.
&lt;/p&gt;

&lt;p&gt;
	When it comes to model classes, there are no restrictions in Symfony2. It is recommended to use Doctrine 2 (which also is included in the distribution package of Symfony2) as your applications&#039; ORM system. Doctrine 2 is already integrated into Symfony2 which makes the configuration really easy. If you follwed the steps in the Project Setup section above, you even configured Doctrine 2 already!
&lt;/p&gt;

&lt;h3&gt;MVC Round-Up&lt;/h3&gt;

&lt;p&gt;
	Real MVC is hard to implement the correct way. This is espacially true when it comes to web applications. One major component missing to a real MVC implementation in classic web applications is the synchronity of model and view (which is normally done using an &lt;i&gt;Observer Pattern&lt;/i&gt;). Using PHP, HTTP and HTML, you normally render a web page once and the user has to reload the page to see whether there have been changes on the displayed data. By using Ajax in combination with XMPP or any other RealTime-Web implementation, you can imitate this mechanisms. Doing so, you will end up with two MVC implementations: One on the server side and one inside the browser.&lt;br /&gt;
	After the comparison of ZF and Symfony2 regarding MVC, you cannot say that one does a better job at it. Both frameworks help you separating your code, but the real work has still to be done by the developer using the framework.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Dependency Handling&lt;/h2&gt;

&lt;p&gt;
	Dependency Injection (DI) has been a buzzword in the last few years (again, PHP adopted this technique some years after the Java world did) and still is, so we will have a look on how the ZF and Symfony2 are handling objects dependent on each other. 
&lt;/p&gt;

&lt;h3&gt;Dependencies in ZF&lt;/h3&gt;

&lt;p&gt;
	There is no real DI mechanism in Zend Framework by now. It comes however with multiple components that do something similar to dependency injection. We will have a short look at two of them: The &lt;code&gt;Zend_Registry&lt;/code&gt; and &lt;code&gt;Zend_Application_Resource&lt;/code&gt;s.
&lt;/p&gt;

&lt;p&gt;
	The &lt;b&gt;&lt;code&gt;Zend_Registry&lt;/code&gt;&lt;/b&gt; is a container for services that should be available globally in an application. You can access the registry statically, store values in it and access them somewhere else. This approach can be seen as an implementation of the &lt;a href=&quot;http://martinfowler.com/articles/injection.html#UsingAServiceLocator&quot; target=&quot;_blank&quot;&gt;Service Locator&lt;/a&gt; pattern. If you have external dependencies in your controller and/or model classes, you can just read them from the registry every time you need them. Two downsides of the &lt;code&gt;Zend_Registry&lt;/code&gt; is that it does support lazy initialization of dependencies and that it cannot provide non-shared objects (to achive this, you can always put factory objects into the registry!).&lt;br /&gt;
	Another mechanism related to DI is provided by the package &lt;code&gt;Zend_Application_Resource&lt;/code&gt;. Resources are dependencies configured at the time the &lt;code&gt;Zend_Application&lt;/code&gt; is being bootstrapped. You can access all application resources in your controller by calling &lt;code&gt;$this-&gt;getFrontController()-&gt;getParam(&#039;bootstrap&#039;)-&gt;getResource($resourceName)&lt;/code&gt;. 
&lt;/p&gt;

&lt;h3&gt;Dependency Injection in Symfony2&lt;/h3&gt;

&lt;p&gt;
	Symfony2 is shipped with a &lt;a href=&quot;http://components.symfony-project.org/dependency-injection/&quot; target=&quot;_blank&quot; title=&quot;Symfony Dependency Injection&quot;&gt;dependency injection component&lt;/a&gt; which can be used as a standalone package, too. Every Symfony2 project uses it since the framework itself makes use of it in its core components. Besides that, you can benefit from DI in your own bundles as well. Symfony2&#039;s dependency injection container is configured via extensions that specify their services and the objects required to build these services. Imagine for example a user management bundle which sends welcome emails to new users. Therefore there might be a service called &lt;code&gt;&lt;a href=&quot;http://de.wikipedia.org/wiki/ACME&quot; target=&quot;_blank&quot; title=&quot;A company that makes everything&quot;&gt;Acme&lt;/a&gt;\UserBundle\WelcomeMailer&lt;/code&gt; which requires a mailer object to perform its work. In this case you would create an extension for the DI container and define your service like this:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1461978.js?file=gistfile1.xml&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
	To access the welcome mailer in a controller, you just call &lt;code&gt;$this-&gt;get(&#039;welcome.mailer.acme.user&#039;)&lt;/code&gt; and receive a lazily created instance of the class &lt;code&gt;Acme\UserBundle\WelcomeMailer&lt;/code&gt;. Objects defined as arguments of a service will be provided to the service&#039;s constructor as parameters. If you want to use the welcome mailer somewhere else, just define it as an argument of this other class and you will have an instance of the service injected.
&lt;/p&gt;

&lt;h3&gt;Dependency Management: Conclusion&lt;/h3&gt;

&lt;p&gt;
	As we have seen, the winner of this discipline is Symfony2. It enables developers to define their objects&#039; dependencies explicitely in a very flexible way. Zend Framework on the other side provides mechanisms that ease the distribution of service objects, but does not implement lazi dependency initialization or and injection of dependencies at all.
&lt;/p&gt;

&lt;br /&gt;&lt;br /&gt;
&lt;p&gt;
    These were just a few differences between Symfony2 and Zend Framework 1. If you got interested in Symfony2 by this article, you should have a look at the framework&#039;s website and read the &lt;a href=&quot;http://symfony.com/doc/current/book/index.html&quot; title=&quot;The Symfony2 Book&quot; target=&quot;_blank&quot;&gt;Symfony2 bible&lt;/a&gt;.&lt;br /&gt;
All in all I prefer Symfony2 for new projects because it makes me write better OO code. Zend Framework is fine, too, but it looks kind of outdated to me. Anyways I&#039;m also excited to see how ZF 2 (currently beta) works and will spend some time comparing it to Symfony2 as well - maybe in another blog article.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 17 Dec 2011 08:00:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/808-guid.html</guid>
    <category>doctrine</category>
<category>doctrine 2</category>
<category>framework</category>
<category>object orientation</category>
<category>php</category>
<category>zend framework</category>

</item>
<item>
    <title>16.12. Eine Einführung in Behavior Driven Development</title>
    <link>http://blog.mayflower.de/archives/815-16.12.-Eine-Einfuehrung-in-Behavior-Driven-Development.html</link>
            <category>Development</category>
            <category>Open Source</category>
            <category>PHP</category>
            <category>PHP-DE</category>
    
    <comments>http://blog.mayflower.de/archives/815-16.12.-Eine-Einfuehrung-in-Behavior-Driven-Development.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=815</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=815</wfw:commentRss>
    

    <author>nospam@example.com (Alberto Assmann)</author>
    <content:encoded>
    Testdriven Development, also das Schreiben eines oder mehrerer Tests bevor der eigentliche Code entsteht, ist inzwischen ein alter Hut. &lt;br /&gt;
Ein großer Nachteil dieses Verfahrens ist, dass im agilen Umfeld die User Stories erst verstanden werden müssen. &lt;br /&gt;
Wenn die Story aber falsch verstanden wurde, dann wird auch der Test falsch implementiert.
Knackpunkt ist also immer noch der Abgrund zwischen Analyse und Verdeutlichung der Geschäftsprozesse sowie dem korrekten Erfassen und testen eben jener. &lt;br /&gt;
Eine Lösung hierfür soll Behavior Driven Development - kurz BDD - bieten. &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/815-16.12.-Eine-Einfuehrung-in-Behavior-Driven-Development.html#extended&quot;&gt;Continue reading &quot;16.12. Eine Einführung in Behavior Driven Development&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 15 Dec 2011 13:39:32 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/815-guid.html</guid>
    <category>bdd</category>
<category>behat</category>
<category>behavior driven development</category>
<category>php</category>
<category>test driven development</category>

</item>
<item>
    <title>15.12. Using custom annotations in PHP</title>
    <link>http://blog.mayflower.de/archives/785-15.12.-Using-custom-annotations-in-PHP.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/785-15.12.-Using-custom-annotations-in-PHP.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=785</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=785</wfw:commentRss>
    

    <author>nospam@example.com (Dominik Liebler)</author>
    <content:encoded>
    When developing enterprise software one should always keep an eye on writing code that is easily maintainable, testable and extendable. Design patterns already propose a way to implement a loosely coupled architecture. With annotations you can take a step forward to make your code look even more expressive, focusing on the primary problem instead of writing a lot of boilerplate code. A single comment line can save you many more lines of code but as it is written in the project&#039;s domain language it will be much more meaningful to the developer. &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/785-15.12.-Using-custom-annotations-in-PHP.html#extended&quot;&gt;Continue reading &quot;15.12. Using custom annotations in PHP&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 15 Dec 2011 08:30:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/785-guid.html</guid>
    <category>annotations</category>
<category>development</category>
<category>php</category>
<category>php5</category>

</item>
<item>
    <title>14.12. Backbone VS Knockout VS JavaScriptMVC</title>
    <link>http://blog.mayflower.de/archives/813-14.12.-Backbone-VS-Knockout-VS-JavaScriptMVC.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/813-14.12.-Backbone-VS-Knockout-VS-JavaScriptMVC.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=813</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=813</wfw:commentRss>
    

    <author>nospam@example.com (Marco Francke)</author>
    <content:encoded>
    &lt;p&gt;In this article Id like to compare Backbone, Knockout and JavaScriptMVC under the following points:&lt;/p&gt;

&lt;/br&gt;
&lt;ul&gt;
  &lt;li&gt;documentation&lt;/li&gt;
  &lt;li&gt;installation&lt;/li&gt;
  &lt;li&gt;understanding&lt;/li&gt;
  &lt;li&gt;complexity&lt;/li&gt;
  &lt;li&gt;for what kind of project&lt;/li&gt;
&lt;/ul&gt;
&lt;/br&gt;

&lt;p&gt;
So lets start with Backbone.&lt;/br&gt;
The documentation of Backbone is available under the following &lt;a href=&quot;http://documentcloud.github.com/backbone/&quot; title=&quot;Documentation of BackboneJS&quot;&gt;link&lt;/a&gt;. The complete documentation is written on a single page. Its very easy to search for topics you are interested in. After a short introduction youll find one or more code examples for each topic. These examples are nicely short and well described. Some of them are testable right away. Everything is easy to understand. The only thing missing is a short demonstration how all parts of Backbone work together. But if you search for Backbone snippets on &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt; you will find lots of examples because it has a wide acceptance among frontend developers.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
Backbone is lightweight with just 4.6KB (compressed and Gzipped). It comes along with models, views and controllers to separate the contexts of your application. The only hard dependency of Backbone is underscore.js, a library full of useful utilities and JavaScript functions. For DOM manipulation you are advised to include either jQuery (&gt;1.4.2) or Zepto. To use Backbone just download the backbone.js and underscore.js files and include them in your application. If you include jQuery as well you have a very powerful set to implement complex applications. One thing I experienced myself and read a lot about it on the Internet is the error handling of Backbone. If something went wrong (i. e. you forgot to include underscore.js) a JavaScript error occurs with a message that has nothing to do with the real error.
Compared to other implemented MVC patterns, the Backbone.View is a kind of controller. It dispatches events that originate from the UI, with the HTML template serving as the true view. They called it view because it represents a logical chunk of UI, responsible for the contents of a single DOM element. Backbones main structure exists of Backbone.Model, Backbone.View, Backbone.Collection and Backbone.Router.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
&lt;b&gt;Backbone.Model&lt;/b&gt;&lt;/br&gt;
It wraps a row of data into business logic. The backbone.Model provides a basic set of functionality for managing changes.
An easy model could look like this:
&lt;/p&gt;
&lt;/br&gt;
&lt;script src=&quot;https://gist.github.com/1472538.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
In this piece of code we extend Backbone.Model with our domain-specific method promptName. The this.set function sets a hash of attributes on the model and triggers a change event. Its one of the base functions in Backbone.Model and really handy for updating your view if something changed. You easily bind a change&quot; listener to the instance of your model to observe any changes. Within the callback of your binding you can place your view changes or whatever you like. Lets have a look at an example.
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472552.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
&lt;b&gt;Backbone.View&lt;/b&gt;&lt;/br&gt;
The general idea of Backbone.View is to organize the interface to logical views. Backed by models each view can be updated independently when the model changes. As well as the model, the view comes along with basic methods like (initialize, render, remove, ...).
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472559.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
In the example we overwrite the function initialize&quot; which is the constructor of the view class. It is always invoked if an instance is created. Within this constructor we bind the change:name listener to the instance of the PersonModel and bind a callback. This callback would be invoked if the name in the model changes. If this happens the new name would be rendered between the body tags.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
&lt;b&gt;Backbone.Collection&lt;/b&gt;&lt;/br&gt;
Backbone.Collections are ordered sets of models. Like the model you can bind change events as well, so the collection get notified if any model changes. It provides a full suite of underscore.js methods to improve the collection handling.
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472565.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
&lt;b&gt;Backbone.Router&lt;/b&gt;&lt;/br&gt;
Backbone.Router maps URLs to functions and connects them to actions and events. For history routing it uses the history API. So you can use standard URLs like /page instead of #page. Backbone provides a graceful fallback for browsers without support of the history API.
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472568.js&quot;&gt; &lt;/script&gt;

&lt;/br&gt;
&lt;p&gt;
To compare the complexity of each library I built a simple wish list application. This application should be able to add wishes, remove them and count all added wishes. An implementation with Backbone could look like this:
&lt;/p&gt;&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472571.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
Backbone is very flexible in the way you want to use it. The view as kind of controller keeps your code small and avoids useless overhead (in JavaScript). Backbone is really easy to understand and with the functions of underscore.js its very powerful as well. To use a proper template engine is always a good idea and eases the developing process. Backbone is well known, so you find lots of code examples or solutions for problems in the Internet. Initially you have to write more code as you probably would write normally. But this code is easy to maintain and extend. If you have the base structure of your application its much faster to work with Backbone. I am using Backbone for a while now and I absolutely recommend it. Its best used in medium to large projects. For small projects its probably sufficient to just use a library like jQuery. 
&lt;/p&gt;
&lt;/br&gt;

&lt;h2&gt;KnockoutJS&lt;/h2&gt;
&lt;p&gt;
The website of &lt;a href=&quot;http://knockoutjs.com/&quot; title=&quot;KnockoutJS&quot;&gt;Knockout&lt;/a&gt; is well organized and the key concepts are visible at first sight. It teasers Declarative Bindings, Automatic UI Refresh, Dependency Tracking and Templating. The documentation is well written and easy to read. Its pretty short and lots of code examples are provided. The best way to get through the documentation is to read and try the examples. With only reading the documentation it could be difficult to understand Knockout. Have a look at the impressive 20-minute demo video from Steve Sanderson. It gives you a good roundup of knockout. After reading and testing a little while you are able to start programming applications. Awesome.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
Knockout is a JavaScript library and not a framework like Backbone or JavaScriptMVC. It doesnt provide classes to extend or inherit from. Anyway it helps to create rich user interfaces with an underlaying data model. It has features like Observables and dependency tracking which automatically updates the UI whenever your data model changes. Declarative bindings to connect parts of your UI to your data model. With Templating you can build complex, dynamic UIs with nested templates. Knockout is written in pure JavaScript and works with any server or client-side technology. Its light weight as well with 29KB (minified). Like Backbone you just have to download knockout.js and include it in your application.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
Knockout is related to the Model-View-View-Model (MVVM) design pattern to build rich user interfaces. The model is independent of any UI and stores the data of your application. The view model is the representation layer of the data and operates on a UI. Its important to understand that the view model is not the UI itself. Its a pure JavaScript object without knowledge of any HTML. It just holds the unsaved data the user is currently working with.
The view represents the state of the view model. It displays information from the view model, delegates commands (i.e. click events) to the view model and updates itself if the state of the view model changes. A short example will demonstrate that.
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472587.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
In the view (HTML) the text binding clause will associate the DOM element with our view model parameter personName. After Knockout is activated via ko.applyBindings(viewModel) the view reads the content of this parameter and renders the text between the span tags. So the result of executing this code looks like:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472591.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
Youve seen how to create a basic view model and how to display its property via binding. But more interesting is how to update the view automatically. Its pretty simple and achieved with so called observables. Just change the previous code into this:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472592.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
Thats it. Try it in the JavaScript console of your browser and you will see the view being updated automatically.
&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/1472596.js&quot;&gt; &lt;/script&gt;

&lt;/br&gt;

&lt;p&gt;
Now I&#039;d like to demonstrate Knockout with the same wish list example like I used in Backbone. So it could look like this:
&lt;/p&gt;&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472597.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
Its awesome to see the same example application as written in backbone earlier with much less JavaScript code. But we have to think about readable and understandable code and how hard it is to explain the code to new developers. I think the declarative binding in the HTML is probably hard to read and understand because you dont really know where it belongs to. Some developers just wont like mixing JavaScript and HTML together. If you bring your knockout code into good shape, use namespaces in your HTML bindings and create conventions how to use knockout in your application it could be easier to understand and maintain. Because knockout is just&quot; a library and not a framework you dont have the benefits of classes, inheritance, fixtures and so on. You have to implement that all by yourself. For huge projects you have to look closer into Knockout to check performance issues.
I think knockoutJS is absolutely worth a try. Its a good decision if you have to implement rich user interfaces. If you organize your code well, its possible to build bigger applications. But I think the best use case is in small to medium projects. 
&lt;/p&gt;
&lt;/br&gt;

&lt;h2&gt;JavaScriptMVC&lt;/h2&gt;
&lt;p&gt;
The documentation on the website of &lt;a href=&quot;http://javascriptmvc.com/docs.html#!&quot; title=&quot;JavaScriptMVC&quot;&gt;JavaScriptMVC&lt;/a&gt; (JMVC) seems to be complicated and could be overstraining. Its not that well structured like the previous ones and it is not really clear where to start. The installation process looks really complicated and could keep some developers from using JMVC. You have to download Java JRE and the full download size of JMVC with 27MB will probably surprising you. I can assure you its not that bad as it seems. A little bit more description why we have to do all these things could help to understand it easier. Anyway the whole installation process runs without problems and it works like described.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
JavaScriptMVC is a really powerful framework. It consists of standalone components like StealJS, FuncUnit, jQueryMX and DocumentJS which are well tested and loved by many developers. This powerful stack provides everything you need to build well organized, tested and documented applications. Lets have a look how everything fits together.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
&lt;b&gt;jQueryMX&lt;/b&gt;&lt;/br&gt;
With this component you have a collection of useful jQuery libraries to implement and organize large-scaled applications. It puts the Model-View-Controller pattern in JavaScript. It comes along with other useful things like an observable system, a DOM extension and special events as well as a browser history routing.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
&lt;b&gt;StealJS&lt;/b&gt;&lt;/br&gt;
This awesome component is a code manager to keep your code beautiful and well organized. Its a collection of command line and browser based utilities to do things like:&lt;/br&gt;
&lt;ul&gt;
  &lt;li&gt;load JavaScript, CSS, LESS and CoffeeScript files&lt;/li&gt;
  &lt;li&gt;build all files into a single production file&lt;/li&gt;
  &lt;li&gt;generate a file and folder structure with tests and documentation scripts&lt;/li&gt;
  &lt;li&gt;install third party dependencies&lt;/li&gt;
  &lt;li&gt;check your code with JSLint and beautify it with steals clean&lt;/li&gt;
  &lt;li&gt;make your AJAX application crawlable&lt;/li&gt;
  &lt;li&gt;log messages in development mode&lt;/li&gt;
&lt;/ul&gt;
&lt;/br&gt;

&lt;p&gt;
To generate an application simply execute the following command:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472614.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
This will generate your application structure with everything you need.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
The scaffold generator helps you to create a model quickly. It creates fixtures to simulate a service, widgets with basic actions and all dependencies are automatically included. You can just start editing the widgets for your purpose. All you have to do is to execute the following command:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472630.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
There are lots of awesome commands to simplify the developing process.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
&lt;b&gt;FuncUnit&lt;/b&gt;&lt;/br&gt;
FuncUnit is a web application testing framework. It provides automated unit and functional testing. You can run these tests practically on every browser or system.
You can start your tests easily within the browser with:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472635.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
or run your tests in Envjs with the command:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472638.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
&lt;b&gt;DocumentJS&lt;/b&gt;&lt;/br&gt;
This component generates a documentation application of your application. The only thing you have to do is to run the following command:
&lt;/p&gt;
&lt;/br&gt;

&lt;script src=&quot;https://gist.github.com/1472642.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
JMVC is so modular you can easily install all the components or just the ones you need.
&lt;/p&gt;
&lt;/br&gt;

&lt;p&gt;
I like JMVC! Its easy to structure your code, generate everything you like, check your code all the time and with a single command your application is ready to go. Of course its a heavy framework and for the shown example absolutely oversized. Its not that easy to understand like the previous ones but definitive worth to try it anyway. We use JavaScriptMVC for big projects where unit tests and an API documentations are essential. The framework has proven its power over a long time so you will find lots of code examples and solutions for your problems. I would recommend JMVC for big projects or projects with the need of high code quality and well documented API.&lt;/p&gt;&lt;/br&gt;

&lt;p&gt;
The following code demonstrates the wish list example implemented with the help of JavaScriptMVC. I put the code into one single file to improve readability here.
&lt;/p&gt;&lt;br/&gt;

&lt;script src=&quot;https://gist.github.com/1473327.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;
In summery I would say Backbone, Knockout and JavaScriptMVC are all pretty good libraries. I would prefer KnockoutJS for smaller projects to create user interfaces in a short amount of time. For bigger projects I would use BackboneJS. It&#039;s easy to implement and well organized. I would choose JavaScriptMVC for large projects where high quality and long term support is expected.
&lt;/p&gt;&lt;/br&gt;

&lt;h1&gt;Links/Sources&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://documentcloud.github.com/backbone/&quot; title=&quot;Backbone Documentation&quot;&gt;BackboneJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://knockoutjs.com/&quot; title=&quot;KnockoutJS Documentation&quot;&gt;KnockoutJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://javascriptmvc.com/docs.html#!&quot; title=&quot;JavaScriptMVC Documentation&quot;&gt;JavaScriptMVC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Book: JavaScript Web Applications - Alex MacCaw&lt;/li&gt;
&lt;/ul&gt; 
    </content:encoded>

    <pubDate>Wed, 14 Dec 2011 07:05:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/813-guid.html</guid>
    
</item>
<item>
    <title>11.12.: Migrate to HTML5!</title>
    <link>http://blog.mayflower.de/archives/803-11.12.-Migrate-to-HTML5!.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/803-11.12.-Migrate-to-HTML5!.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=803</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=803</wfw:commentRss>
    

    <author>nospam@example.com (Thorsten Rinne)</author>
    <content:encoded>
    HTML5 is one of the hottest buzzwords in the web and everyone is using 
or talking about it. Google is ahead everyone else for sure with Google 
Docs, their web based office suite and with Chrome OS, an operating 
system which only needs a browser (from the users view). But also 
Facebook, they working on their own application platform codenamed 
Spartacus is based on HTML5. Even classic software companies like 
Adobe and Microsoft are joining the competition: Microsofts upcoming 
WIndows 8 operating system will include small HTML5 based apps (another 
buzzword) and Adobe has a double-tracked strategy: they release new 
HTML5 development tools almost every month and they still try to rescue 
their old, main product, Flash.&lt;br /&gt;&lt;br /&gt;HTML5 became reality due to the 
real life challenges in the last 10 years when Microsoft decided to stop
 their future browser development after releasing the Microsoft Internet
 Explorer 6 back in 2001. But in the same time more and more business 
critical applications moved from desktop apps into the web and the World
 Wide Web Consortium (W3C) wanted to push the web into a XML based world
 with their XHTML 2.0 draft standard. Today we know it was good everyone
 ignored the XHTML 2.0 development. Because of this, companies like 
Google, Mozilla, Apple and Opera started a project called Web Hypertext 
Application Technology Working Group (WHAT WG) to create an evolutionary
 path for HTML and the web.&lt;br /&gt;&lt;br /&gt;While Microsoft was working on their 
Windows Vista disaster, the members of the WHAT WG worked on a draft for
 the so called HTML5 based on HTML 4.01 and they added new features into
 their browsers. The development was based upon the challenges for 
things like Google Mail (2005) or Web Apps for iPhone (2007) and many 
web developers cant wait for these new features and then even Microsoft
 and the W3C couldnt refuse to see the reality. Nowadays XHTML 2.0 is 
gone and even Microsoft is working on a browser called Windows Internet 
Explorer 10 without any plugin interface, without crappy conditional 
comments and almost full HTML5 support.&lt;br /&gt;&lt;br /&gt;The question for web 
developers is wether we already should use HTML5 in our web 
applications. HTML5 is for all of us who want to push their documents to
 online apps and dont want to use plugins or hacks. The update from 
your HTML 4.01 or XHTML 1.0 markup is quite easy.&lt;br /&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;h2&gt;HTML5 revised&lt;/h2&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;p&gt;The first and even most simple modification of HTML5 compare to HTML 4.01 or XHTML 1.0 is the document type, which changed from &lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;to&lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;As
 you can see immediately the version number is missing. The WHAT working
 group even calls the HTML5 specification now HTML living standard and
 there are updates in the specification almost every week. This 
shouldnt be a problem for anyone because all modern browser like 
Firefox, Chrome, Safari, Opera and even Internet Explorer 10 are using 
their HTML5 rendering engine if the HTML5 document type is parsed.&lt;br /&gt;&lt;br /&gt;Another
 goal during the HTML5 draft was a cleanup and removal of obsolete and 
bad defined elements in HTML 4.01 and XHTML 1.0. HTML5 should have been 
much more simpler and all redundant elements should be removed. Tags 
like&amp;#160; &amp;lt;acronym&amp;gt;, &amp;lt;applet&amp;gt;, &amp;lt;dir&amp;gt;, &amp;lt;frame&amp;gt; and 
&amp;lt;frameset&amp;gt; are not part of the spec anymore. As you can see with 
the removal of the last two elements its not possible to build frame 
based web pages with HTML5. HTML5 also requires to use Cascading Style 
Sheets (CSS) for the representation of web pages, all elements and 
attributes for styling content were also removed. This removal includes 
attributes like plaintext, isindex, align, alink, vlink and HTML tags 
like &amp;lt;basefont&amp;gt;, &amp;lt;big&amp;gt;, &amp;lt;center&amp;gt;, &amp;lt;font&amp;gt;, 
&amp;lt;s&amp;gt;, &amp;lt;strike&amp;gt;, &amp;lt;tt&amp;gt;, &amp;lt;u&amp;gt;.&lt;br /&gt; &lt;/p&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;h2&gt;HTML5 improvements&lt;/h2&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;p&gt;There are a lot of small improvements to 
solve daily web development problems. Embedded images now have a border 
with 0 pixels instead an ugly blue border by default and the 
&amp;lt;script&amp;gt; tag now assumes to have JavaScript included. If you add 
links or images to your webpage, please use the id attribute instead 
name because its much easier for DOM manipulations. One really great 
improvement is the character set declaration. Instead of adding&lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;meta http-equiv=Content-Type content=text/html;charset=UTF-8&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;you only need this:&lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;meta charset=UTF-8&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;And, please only use UTF-8, nothing else.&lt;br /&gt;&lt;br /&gt;A
 lot of stuff was added to the HTML specification which everyone used 
but never was part of the standard. HTML5 now officially features the 
&amp;lt;iframe&amp;gt; element and the &amp;lt;embed&amp;gt; tag for embedding Plugins 
like our beloved Flash.&lt;br /&gt;&lt;br /&gt; &lt;/p&gt; 
&lt;h2&gt;Semantic improvements&lt;/h2&gt;&lt;br /&gt;A lot of changes within HTML5 
describes the requirement to improve the semantics of web pages. The 
draft standard adds the new media attribute for links to set media 
type. So its possible to add a link to the mobile Twitter page by using
 the following code: &lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;a href=http://m.twitter.com rel=alternate media=handheld&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160; &amp;#160;Twitter Mobile&lt;br /&gt;&amp;lt;/a&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Some common attributes are now available for all HTML elements: &lt;br /&gt; 
&lt;ul&gt; 
&lt;li&gt;id to identify elements in the DOM tree&lt;/li&gt; 
&lt;li&gt;title for setting a title of the element&lt;/li&gt; 
&lt;li&gt;lang for the language, e.g. de for German language&lt;/li&gt; 
&lt;li&gt;dir to set the text direction&lt;/li&gt; 
&lt;li&gt;class for CSS classes&lt;/li&gt; 
&lt;li&gt;style for CSS inline styles&lt;/li&gt; 
&lt;/ul&gt;&lt;br /&gt;A note on CSS3: the specification is still in the works and you
 dont need CSS3 to use HTML5. HTML5 works just fine with CSS 1 and CSS 
2.1.&lt;br /&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;h2&gt;New elements for page structure&lt;/h2&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;p&gt;For many people the new HTML5 
tags like &amp;lt;audio&amp;gt; and &amp;lt;video&amp;gt; are the most visible change 
looking deeper into HTML source code. With the new &amp;lt;section&amp;gt; 
element its now possible to group section within a web page. Its not 
for design definition, only for semantic structures. For design proposes
 you should still use the &amp;lt;div&amp;gt; element like you do today. To mark
 content inside a section, HTML5 introduces the &amp;lt;article&amp;gt; element.
 For example, you can use this new tag for board postings in a forum, 
for blog postings, for user comments in your content management system 
or even a whole article in a online magazine. In these parts of the page
 you can add side content boxes with the &amp;lt;aside&amp;gt; element. If you 
e.g. want to add a skyscraper ad on the left side, put it into an 
&amp;lt;aside&amp;gt; tag.&lt;br /&gt;&lt;br /&gt;The navigation should be marked with the 
&amp;lt;nav&amp;gt; element and the navigation items should be listed as an 
unordered list inside the root element. If you have to group headers 
like &amp;lt;h1&amp;gt; to &amp;lt;h6&amp;gt; you can now use the &amp;lt;hgroup&amp;gt; tag. A 
group of headers are part of a section of a document according to the 
HTML5 standard. The document header and footer have to own tags which 
are - quite easy to guess - &amp;lt;header&amp;gt; and &amp;lt;footer&amp;gt;. A HTML5 
document can consist of multiple headers, for example at the beginning 
of a document or to group a header for an introduction and a header:&lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;header&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;p&amp;gt;Welcom to&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;h1&amp;gt;Mayflower Blog&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;/header&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;br /&gt;The
 &amp;lt;footer&amp;gt; element can be used multiple times, too. You can use it 
for example to mark the end of a section or usally to mark the end of 
the HTML document. This is the area to add relevant links or copyright 
hints, the contact address for the author should be added by using the 
&amp;lt;address&amp;gt; tag.&lt;br /&gt;&lt;br /&gt;Its also quite easy to migrate the current structures of your web page to HTML5. For example it would be in most cases just a &lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;div id=&amp;quot;footer&amp;quot;&amp;gt;This is the end.&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;converted to&lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;courier new,courier,monospace&quot;&gt;&amp;lt;footer&amp;gt;This is the end.&amp;lt;/footer&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;The Future &lt;br /&gt;&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This
 blog post is just a very short overview what you can do with HTML5, I 
didnt mentioned the possibilities of Web Workers, Web Sockets, Canvas, 
SVG or Web Storage. But you can test a lot of things now and you should 
do it. The world will move to HTML5, at the end of 2012 more than one 
billion HTML5 capable smartphones and Microsofts Windows 8 will wait for
 your HTML5 applications.&lt;br /&gt; &lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 11 Dec 2011 10:58:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/803-guid.html</guid>
    
</item>
<item>
    <title>09.12. 10 good reasons why to learn a css meta language like sass or less</title>
    <link>http://blog.mayflower.de/archives/802-09.12.-10-good-reasons-why-to-learn-a-css-meta-language-like-sass-or-less.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/802-09.12.-10-good-reasons-why-to-learn-a-css-meta-language-like-sass-or-less.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=802</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=802</wfw:commentRss>
    

    <author>nospam@example.com (Florian Fackler)</author>
    <content:encoded>
    &lt;p&gt;There&#039;s a bunch of really usefull online css tools like css code shrinkers, validators,
    sprite generators, px to em calculators just to name a few. &lt;br /&gt;
    But what I like the
best is &lt;a href=&quot;http://sass-lang.com/&quot; title=&quot;Homepage of SASS&quot;&gt;SASS&lt;/a&gt; and &lt;a href=&quot;https://github.com/cloudhead/less&quot; title=&quot;Git homepage of LESS&quot;&gt;LESS&lt;/a&gt;. &lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/802-09.12.-10-good-reasons-why-to-learn-a-css-meta-language-like-sass-or-less.html#extended&quot;&gt;Continue reading &quot;09.12. 10 good reasons why to learn a css meta language like sass or less&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 08 Dec 2011 19:51:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/802-guid.html</guid>
    <category>css</category>
<category>less</category>
<category>sass</category>
<category>twitter-bootstrap</category>

</item>
<item>
    <title>07.12. One-click Deployment</title>
    <link>http://blog.mayflower.de/archives/800-07.12.-One-click-Deployment.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/800-07.12.-One-click-Deployment.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=800</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=800</wfw:commentRss>
    

    <author>nospam@example.com (Florian Anderiasch)</author>
    <content:encoded>
    &lt;p&gt;Today&#039;s topic is deployment. It&#039;s called one-click deployment for a reason: Developers are lazy.&lt;br /&gt;
It&#039;s hard to do less than clicking on one button, so that&#039;s our goal.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;With the growing need for lower time-to-market and faster response to user feedback it is inevitable to not be limited by technical factors (there are enough other obstacles already). The focus lies on reproducible results.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;So, what do we need? Actually, not much. Disregarding the tools and practices that build the foundation of agile software development, you only need a central build server. But you&#039;ve already got that one covered, right?&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;If you don&#039;t, you should get one. It&#039;s a huge help to discover errors quickly and be alerted instantly. This usually leads to a shorter time frame until a fix is done. Tests are run continuously and new parts are integrated into the whole code base.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Everything written here is based on &lt;a href=&quot;http://ant.apache.org&quot;&gt;Apache ant&lt;/a&gt;, so the easy choices here are &lt;a href=&quot;http://hudson-ci.org&quot;&gt;Hudson&lt;/a&gt; and &lt;a href=&quot;http://jenkins-ci.org&quot;&gt;Jenkins&lt;/a&gt;. We&#039;re focusing on Jenkins here, but we&#039;ve successfully used some variation of this continuous integration/deployment script on both.&lt;br/&gt;&lt;br /&gt;
We&#039;ve also used CruiseControl/phpUnderControl and Atlassian Bamboo in the past for continuous integration, so the deployment parts should work as well.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Back to the hard facts. We&#039;re using the &lt;a href=&quot;http://jenkins-php.org/&quot;&gt;Template for Jenkins Jobs for PHP Projects&lt;/a&gt; here for our basic checks, so let&#039;s assume you got it installed and your build server is working.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;The basics&lt;/h2&gt;

&lt;p&gt;The typical workflow for a developer now consists of these steps:
&lt;ul&gt;
&lt;li&gt;write some unit tests
&lt;li&gt;write some lines of code to get the tests to green
&lt;li&gt;commit to git/svn, let&#039;s call it &quot;release 1.32c&quot;
&lt;li&gt;build server integrates the commit automatically and runs all configured checks
&lt;li&gt;build status is green (hopefully)
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;There&#039;s not much deployment in this, so a few more steps:
&lt;ul&gt;
&lt;li&gt;after the build is done, a new ant task is started, called &quot;create-package&quot;
&lt;li&gt;developer clicks on &quot;deploy-to-staging&quot; (yes, another ant task)
&lt;li&gt;some 5 minutes later the staging environment has &quot;release 1.32c&quot; installed
&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;How does this work?&lt;/h2&gt;

&lt;p&gt;There are a few preconditions in our environment that haven&#039;t been named yet. Not all of them are hard requirements, but they make some things a lot easier:
&lt;ul&gt;
&lt;li&gt;all developers have a VM image for this project, based on Ubuntu 11.04
&lt;li&gt;this VM image is personalized to a certain degree (user/hostname)
&lt;li&gt;it is managed by puppet, all developers can edit puppet manifests
&lt;li&gt;the staging environment also consists of 4 VMs&lt;ul&gt;
  &lt;li&gt;Ubuntu 11.04 for the 2 frontend nodes
  &lt;li&gt;Ubuntu 10.04 for the 2 backend nodes
  &lt;li&gt;(hindsight is 20/20, we should&#039;ve used the same version on all 4, but it&#039;s not that bad)
&lt;/ul&gt;
&lt;li&gt;the machine that Jenkins is running on is also based on that same development image. This helps fight issues with incompatible versions and build tools.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;The frontend nodes use a setup including varnish, nginx, PHP 5.3+APC, ZF 1.11, Dojo 1.6 and Doctrine 2.1.&lt;br/&gt;
The backend nodes use MySQL(Master+Slave), Apache Solr, RabbitMQ, memcached and ejabberd.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Back to ant.&lt;/h2&gt;

The task &lt;strong&gt;create-package&lt;/strong&gt; is building a .deb package that is to be deployed to all the staging hosts.&lt;/p&gt;
&lt;p&gt;It basically executes these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git pull
&lt;li&gt;ant &lt;strong&gt;phpunit&lt;/strong&gt; (unit tests, integration tests)
&lt;li&gt;ant &lt;strong&gt;clean&lt;/strong&gt; (remove build artifacts)
&lt;li&gt;ant &lt;strong&gt;compilejs&lt;/strong&gt; (using Google Closure Compiler)
&lt;li&gt;ant &lt;strong&gt;compilecss&lt;/strong&gt; (compiling SASS to CSS)
&lt;li&gt;dh_make (read the &lt;a href=&quot;http://www.debian.org/doc/manuals/maint-guide/&quot;&gt;Debian New Maintainers&#039; Guide&lt;/a&gt; for details)
&lt;/ul&gt;

&lt;p&gt;And that&#039;s it.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;The manually executed task is called &lt;strong&gt;deploy-to-staging&lt;/strong&gt; and consists of these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ant &lt;strong&gt;deb-sign&lt;/strong&gt; (sign the package with the development team&#039;s key, optional)
&lt;li&gt;ant &lt;strong&gt;db-staging-up&lt;/strong&gt; (we&#039;re using &lt;a href=&quot;http://liquibase.org&quot;&gt;Liquibase&lt;/a&gt;, so roll out the database changes)
&lt;li&gt;copy the .deb to all staging nodes via scp
&lt;/ul&gt;
&lt;p&gt;&lt;blockquote&gt;Here&#039;s one caveat: We&#039;ve set up our staging (and production) nodes to include a directory (like /opt/repository) in /etc/apt/sources.list and puppet periodically checks if there are new packages in this directory, and installs it. Of course you could just call dpkg -i through ssh as well.&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;So far, so good. After waiting 5mins we&#039;ve got our &quot;release 1.32c&quot; deployed to all 4 staging nodes and the testers can do their work. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Wasn&#039;t that easy?&lt;/h2&gt;

&lt;p&gt;We&#039;re not quite done yet though. The testers really liked release 1.32c and we want to deploy to live now!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;So this means:
&lt;ul&gt;
&lt;li&gt;developer clicks on &lt;strong&gt;deploy-to-live&lt;/strong&gt; (yes, you&#039;ve guessed it, an ant task)
&lt;li&gt;some 5mins later &quot;release 1.32c&quot; is live
&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;In greater detail:
&lt;ul&gt;
&lt;li&gt;fetch the latest &quot;known good&quot; debian package from a staging host
&lt;li&gt;ant &lt;strong&gt;db-production-up&lt;/strong&gt; (&lt;a href=&quot;http://liquibase.org&quot;&gt;Liquibase&lt;/a&gt; doing it&#039;s magic again)
&lt;li&gt;copy the .deb to all production nodes via scp
&lt;li&gt;there&#039;s no step 4
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;If everything went well, you just deployed a new release!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Of course it&#039;s not all perfect, there are some disadvantages and shortcomings.&lt;/h2&gt;

&lt;p&gt;The first thing we noticed is the build time. The build used to take 15 minutes because of massive disk I/O. Mostly all the analysis/metrics tools are to blame, if you have a few of those, every single one has to read and check all of your hundreds of files even if you exclude the external dependencies and libraries (which is a good idea, anyway). We put the files on a ram disk and brought the build from 15 minutes down to 4. Good enough.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;The setup is quite complex (as you&#039;ve seen if you&#039;re still reading). It takes a bit to get used to and there are some moving parts. But so far it&#039;s working nicely.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Jenkins is a single point of failure. If your build server goes the way of the dodo, it&#039;s very hard to get a release going. There&#039;s an easy fix, however: Have a second machine ready that&#039;s running an identical copy of your Jenkins setup. If your main build server is down you can still use that one then. As your developer VMs are using the same ant build.xml for daily work, even using that as a last resort is possible.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;There are also some goodies that aren&#039;t crucial, but nice:
&lt;ul&gt;
&lt;li&gt;everyone can deploy (even the product owner)&lt;/li&gt;
&lt;li&gt;30 minutes from bug report to live deploy is not uncommon with this setup and it&#039;s still following a fixed procedure&lt;/li&gt;
&lt;li&gt;this setup still allows us to do hotfixes (check out the tag deployed to production, do a fix, commit to a branch and HEAD, create .deb, deploy)&lt;/li&gt;
&lt;li&gt;Jenkins has some graphing functions, you can do commit stats or graph your Facebook fans&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Having talked with developers from other companies there seem to be quite a few similar setups including chef, rake, phing or even make - so you&#039;re surely not forced to use ant or a debian-based distribution. &lt;br /&gt;&lt;br /&gt;
Good luck simplifying your own deployment!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 06 Dec 2011 22:13:27 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/800-guid.html</guid>
    <category>ant</category>
<category>deployment</category>
<category>jenkins</category>
<category>php</category>

</item>
<item>
    <title>03.12. Setting up an own QA Environment for Javascript</title>
    <link>http://blog.mayflower.de/archives/788-03.12.-Setting-up-an-own-QA-Environment-for-Javascript.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/788-03.12.-Setting-up-an-own-QA-Environment-for-Javascript.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=788</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=788</wfw:commentRss>
    

    <author>nospam@example.com (Martin Ruprecht)</author>
    <content:encoded>
    Nearly every PHP project comes up with a great set of tools to assure the quality of source code;  unit tests are a no longer a nice to have feature, they are common components in new projects. While unit tests help you to provide solid interfaces and proof the functionality of a certain method, there is a long list of tools that check the quality of the source code itself with many different metrics. Each of these mentioned tools reports its results into a XML file, which can easily be interpreted  by a continuous integration server like Jenkins. The benefit is enormous: After every commit to your version control system your continuous integration server triggers the execution of the tests and the source code quality analysis and shows the result in meaningful diagrams. As a developer you get a direct feedback and you can make a prediction on the status of the entire project, because if even the smallest units work fine, there is a good chance that the whole system runs stable.
&lt;br /&gt;
&lt;br /&gt;
So far for developing with PHP, but what about JavaScript? Are there any tools for quality assurance? Yes! Is it really necessary to do JavaScript QA? Oh yes! Since JavaScript is becoming one of the hottest programming languages for web (and mobile) development, there is no doubt that that we need some way to check the functionality and measure the code quality. Before I will show you some really cool tools and some easy steps on how to set up your own quality assurance environment, let me say a few words on how the increasing popularity of Javascript is affecting the requirements we have  on QA for JavaScript and how it is different to QA for PHP. . A couple of years ago, JavaScript was only used for some (unneeded) animation, called DHTML, and for simple form validations. The AJAX hype gave JavaScript a second chance and from this point the lines of JavaScript code where spreading. In other words, most developers haven´t seen the necessity of writing down something similar to unit tests only for some small piece of JavaScript code, they use Firebug for debugging  and it works fine for the moment. Another reason why JavaScript QA is different from PHP QA lies in the nature of JavaScript. Whereas PHP is mostly executed on a (Apache) server JavaScript is executed on many different environments and devices that don´t follow common rules and standards. That´s why the requirements for any QA tools are really difficult, because you want to cover a huge amount of environments and devices- otherwise you can only guaranty that your source code runs correctly on a certain device and I´m sure that´s not your intention. In addition, don´t forget the dynamic of JavaScript. It´s easy to extend the range of functions of JavaScript (because of it´s prototypical inheritance) or think of all the functions that come up with the environment, for example the Firefox File API. All these dynamic is really really hard to cover for QA. And last but not least, JavaScript is an interpreted language not a compiled one, this means there is no static code analysis that check the syntax tree like it&#039;s done during compiling in other programming languages. So we have indicated two very simple requirements for JavaScript quality assurance: we need something to check our syntax and we need something that tests our code with many different environments/browser and devices. Ok, enough for the moment, let´s introduce our first tool: jsLint. 
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;jsLint&lt;/strong&gt;&lt;br /&gt;
This is not a completely new tool, invented by Douglas Crockford, jsLint is a JavaScript syntax parser written in JavaScript that does not need a browser for its syntax checks. You can use jsLint in many different ways, I prefer the Java wrapper for jsLint as a command line tool, see jslint4java [http://code.google.com/p/jslint4java/]. JsLint (and also jslint4java) comes up with a lot of possible optional parameters to define how strict your code should be checked. 
&lt;br /&gt;
&lt;em&gt;Here is an first example of jsLint (called from the commandline via jsLint4java):&lt;/em&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/jslint.jpg&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;
Not only syntax errors like the missing semicolon at the end of a line or a comma after the last entry of an array are considered, mixing spaces and tabs or a wrong indention will be checked as well. Using jsLint4java allows you to print the results into defined XML files. On the way to our own JavaScript QA environment we have entered our first milestone: We check our syntax tree with jsLint, in other words we do a static code analysis- cool!
&lt;br /&gt;
&lt;br /&gt;
From now on our source code quality will be checked by jsLint, but this doesn´t guaranty that our functions work well. This is the point where we should think about unit tests. There are a lots of great unit testing tools for JavaScript and nearly every frameworks comes up with its own implementation. To fit the requirement I have mentioned before, run the tests on many different environments (browsers) and devices, we need not only a standalone unit testing tool, we need something that runs the tests on these environments and devices. This is the point where our second tool enters the stage: please say hello to Googles jsTestDriver. 
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;JsTestDriver&lt;/strong&gt;
&lt;br /&gt;
JsTestDriver is pretty easys to use it consist of a single JAR file which contains everything you need to get started. Here is an overview of how JsTestDriver works at runtime:
This tool combines an independent test framework and a testrunner to execute the tests on many different environments and devices. 
&lt;br /&gt;
&lt;em&gt;This is the general architecture of jsTestDriver&lt;/em&gt;
&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/jsTestdriver.jpg&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;
Therefore the tool starts a simple HTTP server to connect  with your browser. From this point your browser is marked as a browser to test, this process is called capturing. There are only two steps left to run tests on the captured browsers. Step one is to write down some tests and step two is to trigger the execution of the tests from the command line of your system. Furthermore for jsTestDriver it doesn´t matter whether you are executing your tests from Windows, Mac or any Linux operation system you can capture a browser form any remote system or a mobile device. By the way, it´s not strictly needed to add a browser by visiting the capture page, it´s also possible to pass the path to the browser to an optional command line parameter (--browser). In this case jsTestDriver will open the browser, execute the tests and shut down the browser. For writing the tests jsTestDriver provides a huge amount of assertions  but it´s also possible to write the tests with nearly every test framework of your choice by using an adapter for it.  By starting the tests, all tests will be sent over HTTP to all captured browsers and executed, the results will be sent back to the server and will be displayed by default at the screen. An export of the results into a XML file is also possible. 
&lt;blockquote&gt;
&lt;em&gt;Here is a short example how a test for jsTestDriver could look like&lt;/em&gt;
&lt;br /&gt;
MathmaticsTest = TestCase(&quot;MathmaticsTest&quot;);
&lt;br /&gt;
MathmaticsTest.prototype.testAdd = function() {
&lt;br /&gt;
	var mathmatics = new school.Mathmatics();
&lt;br /&gt;
	assertEquals(3, mathmatics.add(1,2));
&lt;br /&gt;
}
&lt;br /&gt;
&lt;br /&gt;
MathmaticsTest.prototype.testSub = function() {
&lt;br /&gt;
	var mathmatics = new school.Mathmatics();
&lt;br /&gt;
	assertEquals(1, mathmatics.sub(4,3));
&lt;br /&gt;
}
&lt;br /&gt;
&lt;br /&gt;
MathmaticsTest.prototype.testDiv = function() {
&lt;br /&gt;
	var mathmatics = new school.Mathmatics();
&lt;br /&gt;
	assertEquals(4, mathmatics.div(8,2));
&lt;br /&gt;
}

&lt;br /&gt;
&lt;br /&gt;
MathmaticsTest.prototype.testMultiple = function() {
&lt;br /&gt;
	var mathmatics = new school.Mathmatics();
&lt;br /&gt;
	assertEquals(9, mathmatics.multiple(3,3));
&lt;br /&gt;
}&lt;/blockquote&gt;
&lt;br /&gt;
&lt;em&gt;Executing the tests ends in a result like this:&lt;/em&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/jsTestDriverCommandLineCall.png.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
After knowing these two very nice tools we already have two major components for or QA environment. What is still missing? Running a static code analysis and triggering unit tests for different devices from the command line is pretty cool already, but it would be even cooler if we were able to  integrate jsLint and jsTestDriver into a continuous integration environment to automate the process of checking and testing our source code. A couple of lines ago, I have mentioned Jenkins as one possible tool for continuous integration and do you remember that jsLint4java and also jsTestDriver have a XML output? Bingo! This is the great benefit of these two tools, they generate a XML file that could easily be read by Jenkins (or any other continuous integration tool). Imagine this workflow: You write some new JavaScript code including tests, you check in your changes into your projects version control system, Jenkins recognizes that there are some changes and triggers the static code analysis and starts the execution of the test and after performing these two tasks the results will be displayed in some nice graphs.Sounds promising, doesn&#039;t it? This is exactly what we will do with the next easy steps, because we only have to configure Jenkins- nothing more! Step one is to create an ANT task for each tool, this will be done in the projects build file (build.xml). 
A sample definition of an ANT task could be found at the homepage of jsLint4 [http://docs.jslint4java.googlecode.com/git/2.0.1/ant.html]. 
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/antjsLint.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
Important for this configuration is the node target with it´s attribute name, because this is the value you have to enter into the Jenkins  configuration. In addition, see the jslint node, where you can configure the strength or weakness of your analysis via the attribute options. Whereas the node formatter defines where the XML output should be saved, the fileset node defines the directory with the source code file that should be checked. That´s all for jsLint.
The task definition for jsTestDriver looks pretty similar:
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/antjsTestDriver.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
This ANT task executes the tests on the defined browsers. Also it writes the output into the defined directory. And that´s all for the moment, all other needed steps have to be done in Jenkins, and that´s also easy. 
&lt;br /&gt;
&lt;em&gt;Here the two needed steps:&lt;/em&gt;&lt;br /&gt;

&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/confJenk3.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/confJenk4.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;And these are the results:&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/uebersicht.jpg&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/jsVialoationJenkins.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/testerg2.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://blog.mayflower.de/uploads/testerg.png&quot; alt=&quot;&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;br /&gt;
For this blogpost I have introduced two (free available) tools and showed the steps to build your own basic JavaScript QA environment with Jenkins for continuous integration. In summary what you will get with this setup is  a solid environment for checking your source code quality and a way for automated unit test execution. Beside the presentation of the syntax violation results (jsLint) and unit tests (jsTestDriver) results I recommend a small subversion post commit hook that will send you an email with the results coming from jsLint. To conclude this blogpost, there is not only jsLint and jsTestDriver for measuring, checking and saving the quality of JavaScript code, for example it´s possible to use a plugin for jsTestDriver that checks the code coverage or define another ANT task that automatically generates a minified version of your source code.  
    </content:encoded>

    <pubDate>Sat, 03 Dec 2011 09:38:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/788-guid.html</guid>
    <category>automatisierung</category>
<category>best practises</category>
<category>debugging</category>
<category>deployment</category>
<category>development</category>
<category>javascript</category>
<category>php</category>
<category>test</category>
<category>unittests</category>
<category>web2.0</category>
<category>weihnachten</category>

</item>
<item>
    <title>01.12. CLOUD Transformation Model</title>
    <link>http://blog.mayflower.de/archives/783-01.12.-CLOUD-Transformation-Model.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/783-01.12.-CLOUD-Transformation-Model.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=783</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=783</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Hallmann)</author>
    <content:encoded>
    &lt;em&gt;What we want to do?&lt;/em&gt; &lt;br /&gt;&lt;br /&gt;
The blog post proposes &lt;strong&gt;procedures&lt;/strong&gt; to analyze architectures and applications that are based on clients, server and cloud technologies to &lt;strong&gt;find vulnerabilities with the goal to increase security&lt;/strong&gt;.
&lt;br /&gt;&lt;br /&gt; &lt;em&gt;Who are the unknowns?&lt;/em&gt; &lt;br /&gt;&lt;br /&gt; &lt;strong&gt;Web Desktop Systems&lt;/strong&gt; (WDS) are based on web technologies that distribute their parts over clients and servers with clients that provide simple versions of an operating system and installed browsers. The server part integrates cloud computing and cloud storage technologies.
&lt;br /&gt;&lt;br /&gt; &lt;em&gt;Cover our main idea.&lt;/em&gt; &lt;br /&gt;&lt;br /&gt;
The main idea is to &lt;strong&gt;transform&lt;/strong&gt; a &lt;strong&gt;common WDS&lt;/strong&gt; environment to a more &lt;strong&gt;secure environment&lt;/strong&gt; by using a way that is divided into single phases to split the whole process into small pieces that can be handled more easily. The approach visualizes strategies against security issues to increase security with the help of a &lt;strong&gt;predefined rule set&lt;/strong&gt;. Use that set to handle transform strategies and execute phases that can be processed separately similar transforming objects to executable pieces.
&lt;br /&gt;&lt;br /&gt; &lt;em&gt;Lets start with the phase model. Its very simple to use.&lt;/em&gt; &lt;br /&gt;&lt;br /&gt;
Formula 1 explains a mathematical abstraction of the proposed phase model. &lt;em&gt;I&lt;/em&gt;&lt;sub&gt;n&lt;/sub&gt; is the current security issue that has to be localized and handled. &lt;em&gt;R&lt;/em&gt;&lt;sub&gt;n&lt;/sub&gt; is a single element from the defined rule set. The optimal case is the elimination of the issue &lt;em&gt;I&lt;/em&gt;&lt;sub&gt;n&lt;/sub&gt; while applying the rule set element &lt;em&gt;R&lt;/em&gt;&lt;sub&gt;n&lt;/sub&gt;. &lt;em&gt;S&lt;/em&gt;&lt;sub&gt;ges&lt;/sub&gt;covers all issues and approximate the best security transformation of all issues that were handled and eliminated. Formula 2 shows the range of all security issues &lt;em&gt;n&lt;/em&gt;&lt;sub&gt;max&lt;/sub&gt; that exists and must be processed.
&lt;br /&gt;&lt;br /&gt; &lt;!-- s9ymdb:530 --&gt;&lt;center&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;181&quot; height=&quot;212&quot; src=&quot;http://blog.mayflower.de/uploads/danielhallmann/formula1.jpg&quot; /&gt;&lt;/center&gt; &lt;em&gt;Lets rock it!&lt;/em&gt; &lt;br /&gt;&lt;br /&gt;
&lt;p&gt;Step 1: &lt;strong&gt;Preparation Phase&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:531 --&gt;&lt;center&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;153&quot; height=&quot;296&quot; src=&quot;http://blog.mayflower.de/uploads/danielhallmann/preparation_phase.jpg&quot; /&gt;&lt;/center&gt;&lt;br/&gt;
The aim of this phase is the &lt;strong&gt;definition of the areas&lt;/strong&gt; in which we want to &lt;strong&gt;examine the architecture and functionality&lt;/strong&gt; of the application. &lt;strong&gt;Define a rule set&lt;/strong&gt; and transformation strategies, visualize how it would be accomplished and propose appropriated methods to finalize it.
&lt;br /&gt;&lt;br /&gt;
Include technical aspects and indicate appropriate search phrases to cover all important technical parts. Prepare metrics like LOC to get the amount of source code lines and cyclomatic complexity to &lt;strong&gt;cover complexity&lt;/strong&gt; and &lt;strong&gt;get details about the structure&lt;/strong&gt;. Figure out operational tools like TCP/IP Sniffer e.g. Wireshark&lt;sup&gt;®&lt;/sup&gt; which are helpful to localize insecure vulnerabilities.
&lt;br /&gt;&lt;br /&gt;
According to these findings &lt;strong&gt;define a rule set&lt;/strong&gt; for transformation of vulnerabilities to ensure security. A target that will be covered is transfer data to the cloud. Study encryption on the client and server side. Look for sections that are used to send data that are a potential risk to compromise data. The following part shows an example to store documents to Amazon S3&lt;sup&gt;®&lt;/sup&gt; to cover a real live scenario:
&lt;br /&gt;&lt;br /&gt; &lt;strong&gt;Preparation Phase&lt;/strong&gt; &lt;hr /&gt; &lt;strong&gt;Important vulnerable application part&lt;/strong&gt;:
Use as example the important application unit to transfer data to the cloud and the storage system. Think about the possibility to attack that part and how can an unauthorized person get access to sensitive data and entries? If data was stored in clear text form a hacker can access all data or a part of information without any protection. To prevent this kind of access store data encrypted with a proper algorithm. Now, the task is to find a mechanism to mitigate that risk and create a rule set entity that matches the current behavior and can be used for similar risks in the future. See Table 1which shows a possible entry.
&lt;br /&gt;&lt;br /&gt; &lt;strong&gt;Create rule set entity that matches the vulnerability&lt;/strong&gt;:
Amazon S3 provides a process that handles encrypted exchange of data between client and server. A request-header covers encrypted exchange of data that will be transferred between client and cloud service.
&lt;br /&gt;&lt;br /&gt; 
&lt;table style=&quot;width: 100%; &quot; border=&quot;1&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot;&gt; 
&lt;tbody&gt; 
&lt;tr&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt; &lt;strong&gt;&lt;em&gt;R&lt;/em&gt;&lt;sub&gt;n&lt;/sub&gt;&lt;/strong&gt;&lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;strong&gt;Entity&lt;/strong&gt;&lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt; 
&lt;/tr&gt; 
&lt;tr&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;em&gt;R&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt; &lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;...&lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;/td&gt; 
&lt;/tr&gt; 
&lt;tr&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;em&gt;R&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt; &lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;Specifying Server-Side Encryption using the AWS SDK for PHP&lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;Use request-header  x-amz-server-side-encryption that handles encrypted exchange of data between client and cloud service.&lt;/td&gt; 
&lt;/tr&gt; 
&lt;tr&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;em&gt;R&lt;/em&gt;&lt;sub&gt;3&lt;/sub&gt; &lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;...&lt;/td&gt; 
&lt;td style=&quot;width: 33%; &quot;&gt;&lt;/td&gt; 
&lt;/tr&gt; 
&lt;/tbody&gt; 
&lt;/table&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;Table 1 Rule set entity&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Step 2: &lt;strong&gt;Analysis Phase&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:532 --&gt;&lt;center&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;133&quot; height=&quot;291&quot; src=&quot;http://blog.mayflower.de/uploads/danielhallmann/analysis_phase.jpg&quot; /&gt;&lt;/center&gt;
&lt;br/&gt;
The aim of the analysis phase is to &lt;strong&gt;find security issues&lt;/strong&gt; depending on the code structure. After scanning the architecture order all findings in descending sequence to start with the important one.
&lt;br /&gt;&lt;br /&gt;
To get information &lt;strong&gt;cover technical environments&lt;/strong&gt; and determine all facts specified in the preparation phase. Find critical fragments with &lt;strong&gt;code reviews&lt;/strong&gt; that are interesting like the cloud service on the server side. These are parts that are not in the user space and managed by the provider.
&lt;br /&gt;&lt;br /&gt;
Recognize procedures that will be used to optimize the technical structure and &lt;strong&gt;prepare techniques for the action phase&lt;/strong&gt;. For instance, intercept all outgoing and incoming request headers that were exchanged between client instances and cloud components. Search for critical vulnerabilities and evaluate the way how data is processed during a request.
&lt;br /&gt;&lt;br /&gt; &lt;strong&gt;Analysis Phase&lt;/strong&gt; &lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Source code part&lt;/strong&gt;: StoreObjects.php&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:539 --&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;551&quot; height=&quot;123&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/vulnerable_source_code1.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Process all important areas that have been specified in the Preparation Phase. Listing 1 shows a source code part that stores entities in the cloud. The method create_object is called with a bucket name testbucket, the name of the file testfile.txt and some optional parameters like body, acl and contentType. All body data testdata will be stored in plain text and can be read by a hacker that gets unauthorized access. Now, step to the Action Phase that handles this vulnerable source part.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Step 3: &lt;strong&gt;Action Phase&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:534 --&gt;&lt;center&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;143&quot; height=&quot;291&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/action_phase.jpg&quot;  alt=&quot;&quot; /&gt;&lt;/center&gt;
&lt;br/&gt;
The objective of this phase is the &lt;strong&gt;transformation of vulnerabilities&lt;/strong&gt; which were found in the analysis phase. Therefore the action phase reduces security issues by a defined rule set from the preparation phase. At the end of the action phase all detected vulnerabilities will be covered.
Select critical parts and &lt;strong&gt;implement technical code fragments&lt;/strong&gt; to eliminate security vulnerabilities. An example could be the encryption of data to the server through a secure connection. Similar hackers in web development that get unauthorized access to resources in cloud storages data can be compromised too. A possible scenario is to steal server credentials and hack into to get server access.
&lt;br/&gt;&lt;br/&gt;
&lt;strong&gt;Action Phase&lt;/strong&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;strong&gt;Apply rule set Entity&lt;/strong&gt;: R2: Specifying Server-Side Encryption using the AWS SDK for PHP&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:540 --&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;551&quot; height=&quot;134&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/applying_rule_set_entity1.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;p&gt;To encrypt data add the parameter encryption (see Listing 2) with the value AES256 that set the x-amz-server-side-encryption request header to store the file secure. After that change, it is necessary to check if the modification does not bring the application in an instable status. Now, step to the Validation Phase to ensure the stability of the application.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Step 4: &lt;strong&gt;Validation Phase&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:536 --&gt;&lt;center&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;140&quot; height=&quot;291&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/validation_phase.jpg&quot;  alt=&quot;&quot; /&gt;&lt;/center&gt;
&lt;br/&gt;
The aim of this phase is ensure &lt;strong&gt;architecture&lt;/strong&gt; consistency during every transformation. Guarantee that every change works as expected and validate all enclosed components. Loose parts have to work separate and through their interfaces as integration. Run unit tests to ensure functionality of separate single code fragments and cover consistency of multiple components.
&lt;br/&gt;&lt;br/&gt;
Scenarios could be either &lt;strong&gt;exchange of data between applications&lt;/strong&gt; that run on the client and the transfer of data to server components. That includes cloud computing and storage with can be used to execute programs and store data.
&lt;br/&gt;&lt;br/&gt;
&lt;strong&gt;Validation Phase&lt;/strong&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Testing Tool&lt;/strong&gt;: PHPUnit&lt;/p&gt;
&lt;br/&gt;
&lt;!-- s9ymdb:538 --&gt;&lt;img class=&quot;serendipity_image_left&quot; width=&quot;556&quot; height=&quot;532&quot;  src=&quot;http://blog.mayflower.de/uploads/danielhallmann/phpunit_examples1.jpg&quot;  alt=&quot;&quot; /&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;To validate change use test cases and check if the modification runs as expected. The first test case testHeaders validates the request headers and check against the new x-amz-server-side-encryption header if it was set to AES256. The second test case testRetrieveObjects covers the data that was stored and validate the correct data type, format and value that was retrieved.&lt;/p&gt;
&lt;br/&gt;
Each phase of the transformation model &lt;strong&gt;concentrates on increasing security and eliminating vulnerabilities&lt;/strong&gt;. Collect suitable information about code artifacts before transforming it. Always &lt;strong&gt;ensure validation of functionality&lt;/strong&gt; while updating code fragments and cover revert strategies to get an opportunity for role back scenarios in case of incorrect transformation.
&lt;br/&gt;&lt;br/&gt;
&lt;em&gt;Make your life easier&lt;/em&gt;.
&lt;br/&gt;&lt;br/&gt;
Use that transformation model as a &lt;strong&gt;pattern structure to cover the complexity&lt;/strong&gt; of current web architectures that includes WDS like Google Chrome OS&lt;sup&gt;®&lt;/sup&gt; and cloud services like Amazon EC2&lt;sup&gt;®&lt;/sup&gt; and Eucalyptus Cloud&lt;sup&gt;®&lt;/sup&gt;. Integrate technologies like cloud computing and storages that manage more computing cycles and storage outside the traditional resources that locate in the basement of companies that manage their own hardware. Handle each part of the whole structure and the communication between each other. Fill every phase with proper single methods - e.g. rule set entities - that fit perfect the current architecture object and integrate that model as helping pattern for your daily work.

 
    </content:encoded>

    <pubDate>Thu, 01 Dec 2011 08:03:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/783-guid.html</guid>
    
</item>
<item>
    <title>06.12. Doctrine 2 - Zend Framework Integration</title>
    <link>http://blog.mayflower.de/archives/799-06.12.-Doctrine-2-Zend-Framework-Integration.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/799-06.12.-Doctrine-2-Zend-Framework-Integration.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=799</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=799</wfw:commentRss>
    

    <author>nospam@example.com (Paul Seiffert)</author>
    <content:encoded>
    &lt;style&gt;
    .serendipity_entry h1 {
        font-size: 20px;
        margin: 13px 0;
    }

    .serendipity_entry h2 {
        margin: 7px 0;
    }

    .serendipity_entry ul {
        padding-left: 3em;
    }

    .gist-data {
        max-height: 250px;
        overflow: auto;
    }
&lt;/style&gt;

&lt;p&gt;
    In &lt;a href=&quot;http://blog.mayflower.de/archives/792-05.12.-Doctrine-2.html&quot;&gt;yesterday&#039;s article&lt;/a&gt; of our advent calendar, we explained the
    concepts underlying &lt;i&gt;Doctrine 2&lt;/i&gt;. In today&#039;s article, we want to use that knowledge and create a simple &lt;i&gt;Zend Framework&lt;/i&gt; (&lt;i&gt;ZF&lt;/i&gt;)
    application that uses &lt;i&gt;Doctrine 2&lt;/i&gt; to persist its business objects.
&lt;/p&gt;

&lt;p&gt;
    While explaining how to integrate &lt;i&gt;Doctrine 2&lt;/i&gt; into &lt;i&gt;Zend Framework&lt;/i&gt;, we will create a generic sandbox that can be used for future 
    projects building up on these technologies.
&lt;/p&gt;

&lt;h1&gt;Setting up a ZF project with Doctrine 2&lt;/h1&gt;

&lt;p&gt;
    Since this article is not about how to setup a &lt;i&gt;ZF&lt;/i&gt; project, the following steps will require you to have a clean but working project with 
    the usual folder structure.&lt;br /&gt;
    To use &lt;i&gt;Doctrine 2&lt;/i&gt; you will have to get a copy of its source code first. You can get one either from the project&#039;s &lt;a href=&quot;http://www.doctrine-project.org/projects/orm/2.1/download/2.1.4&quot;&gt;website&lt;/a&gt; or by cloning the git repository. In my opinion, downloading the source package from the 
    website is a lot easier (you don&#039;t have to take care of all the project&#039;s git submodules etc.). So download and extract the archive into a 
    temporary directory. After that, move the folder &lt;code&gt;Doctrine&lt;/code&gt; from the archive&#039;s root into the &lt;code&gt;library&lt;/code&gt; of your new
    &lt;i&gt;ZF&lt;/i&gt; application. Now, your project structure should look like this:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436040.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    The first thing that will occur to you if you look at the &lt;i&gt;Doctrine 2&lt;/i&gt; source code is that 100% of the code is
    namespaced (for a (German) introduction to namespaces have a look at the article &quot;&lt;a href=&quot;http://blog.mayflower.de/archives/786-02.12.-PHP-5.3-Features-in-real-life.html&quot;&gt;PHP 5.3 Features in Real Life&lt;/a&gt;&quot; from a colleague of mine). This is pretty nice for people who are not scared of new 
    language constructs but for many people that are using &lt;i&gt;ZF&lt;/i&gt; it might look odd at first. I am sure that you will get familiar with the syntax
    differences really fast, but &lt;i&gt;ZF&lt;/i&gt; (1) does not - because it does support real namespacing yet (however this will change with version 2).&lt;br /&gt;
    Therefore we have to do some additional work that enables us to autoload classes that reside in namespaces. Luckily, &lt;i&gt;Doctrine 2&lt;/i&gt; comes with 
    a neat set of helper classes bundled in the project &lt;a href=&quot;http://www.doctrine-project.org/projects/common&quot;&gt;&lt;i&gt;Doctrine Common&lt;/i&gt;&lt;/a&gt; which 
    also includes a class loader that fulfills our needs. The class loader is called &lt;code&gt;Doctrine\Common\ClassLoader&lt;/code&gt; and is really easy to use:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436045.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    This code snippet creates and registers a new class loader that looks for classes in the namespace &lt;i&gt;Doctrine&lt;/i&gt;. These classes should 
    be placed in a folder called &lt;i&gt;Doctrine&lt;/i&gt; which is part of the current include path. Every namespace separator will be transformed into a
    directory separator when looking for the classes, so make sure to keep your class-, namespace-, file- and folder-names in sync! 
&lt;/p&gt;

&lt;p&gt;
    I recommend putting the initialization of the class loader into your application&#039;s bootstrap class because this way it can be used for cli 
    scripts, too. As you might have seen, there are several packages inside the &lt;i&gt;Doctrine&lt;/i&gt; folder that we placed in your &lt;i&gt;library&lt;/i&gt;. 
    The folders &lt;i&gt;ORM&lt;/i&gt;, &lt;i&gt;DBAL&lt;/i&gt; and &lt;i&gt;Common&lt;/i&gt; contain the &lt;i&gt;Doctrine 2&lt;/i&gt; classes required by the framework. The fourth folder 
    &lt;i&gt;Symfony&lt;/i&gt; contains some classes borrowed from the &lt;a href=&quot;http://symfony.com&quot;&gt;&lt;i&gt;Symfony2&lt;/i&gt;&lt;/a&gt; framework. To load all these classes,
    we have to initialize multiple class loaders:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436046.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    The initialization of the loaders responsible for &lt;i&gt;Symfony2&lt;/i&gt; and entity classes requires a second argument, that indicates the directory
    in which the classes of the namespaces can be found. If you do not provide this argument, the class loader just looks in the directories of your
    include path for folder names matching the given namespace.
&lt;/p&gt;
&lt;br /&gt;
&lt;h2&gt;Creating the Entity Manager&lt;/h2&gt;

&lt;p&gt;
    The next thing we will do is creating an entity manager. To do so, we have to initialize a configuration object (of the type
    &lt;code&gt;Doctrine\ORM\Configuration&lt;/code&gt;) and pass it to the entity manager. Since we want to create a project that can be configured easily, 
    we separate the configuration data from the initialization code. Let&#039;s begin with the initialization code and add the required configuration 
    directives to our &lt;code&gt;application.ini&lt;/code&gt; file later.&lt;br /&gt;&lt;br /&gt;

    Instead of describing each single option here, I add some detailed comments in the initialization code:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436051.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    From now on, you can access the entity manager by requesting it from the &lt;code&gt;Zend_Registry&lt;/code&gt;. This should probably be done via a 
    dependency injection system, but this article will not cover how to implement dependency injection or even a dependency injection container.&lt;br /&gt;
    To make this bootstrap code work, you will have to add the following directives to your &lt;code&gt;application.ini&lt;/code&gt;:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436056.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    Basically, this is all you have to do to integrate &lt;i&gt;Doctrine 2&lt;/i&gt; into your &lt;i&gt;ZF&lt;/i&gt; application. It is fully functional with this
    configuration, so let us take a snapshot of the project now and declare it as our sandbox for future &lt;i&gt;ZF-Doctrine 2&lt;/i&gt; projects.&lt;br /&gt;\
    Next, I want to show you how to create entity classes within your project and how to initialize a database scheme from these entities.
&lt;/p&gt;
&lt;br /&gt; 
&lt;h2&gt;Creating Entity Classes&lt;/h2&gt;

&lt;p&gt;
    If you have read my &lt;a href=&quot;http://blog.mayflower.de/archives/792-05.12.-Doctrine-2.html&quot;&gt;yesterday&#039;s article&lt;/a&gt;, the following part will not 
    look very new to you. I will create two entity classes: &lt;i&gt;User&lt;/i&gt; and &lt;i&gt;Group&lt;/i&gt; which have a n:m relationship called &lt;i&gt;membership&lt;/i&gt;.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436060.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;script src=&quot;https://gist.github.com/1436062.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    To write create tables in the database for these entities, we will use &lt;i&gt;Doctrine&lt;/i&gt;&#039;s console tools which are really handy. Create a new 
    script named &lt;code&gt;doctrine.php&lt;/code&gt; in your application&#039;s &lt;code&gt;bin&lt;/code&gt; directory and copy the following code snippet into it.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436064.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    This script sets up a &lt;code&gt;Zend_Application&lt;/code&gt; first, bootstraps it and creates a normal &lt;i&gt;Doctrine 2&lt;/i&gt; console. You might want to have a 
    look at the original console script which is included in the &lt;i&gt;Doctrine 2&lt;/i&gt; archive we downloaded before. I added the &lt;i&gt;ZF&lt;/i&gt; initialization
    to be able to use the application&#039;s configuration here.&lt;br /&gt;&lt;br /&gt;

    When you run the script now, the output should look like this:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436069.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    All actions related to your database&#039;s schema have the prefix &lt;code&gt;orm:schema-tool&lt;/code&gt;. Create your schema now by executing &lt;br /&gt;&lt;br /&gt;

    &lt;code&gt;$ php bin/doctrine.php orm:schema-tool:create&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;

    If you have no errors in your configuration, your database should have three new tables now: &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;group&lt;/code&gt; and &lt;code&gt;group_user&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
    Now you are ready to implement your application&#039;s logic. You can write code that queries, modifies and creates user and group objects and have 
    all data persisted by &lt;i&gt;Doctrine 2&lt;/i&gt;. To end this article, I just want to give you a feeling for how you might interact with
    &lt;i&gt;Doctrine 2&lt;/i&gt; in your business logic.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1436074.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    I hope this article helps you setting up the infrastructure for your next project and covers everything you have to know to begin using
    &lt;i&gt;Doctrine 2&lt;/i&gt;. The sandbox we set up can be downloaded &lt;a href=&quot;http://blog.mayflower.de/uploads/PaulBlog/sandbox.tgz&quot;&gt;here&lt;/a&gt;. Make sure to include the current versions of &lt;i&gt;ZF&lt;/i&gt; and
    &lt;i&gt;Doctrine 2&lt;/i&gt; after downloading it.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 06 Dec 2011 08:00:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/799-guid.html</guid>
    <category>annotations</category>
<category>blog</category>
<category>code</category>
<category>development</category>
<category>doctrine</category>
<category>doctrine 2</category>
<category>framework</category>
<category>namespaces</category>
<category>object orientation</category>
<category>open-source</category>
<category>opensource</category>
<category>php</category>
<category>php5</category>
<category>weihnachten</category>
<category>xmas</category>
<category>zend framework</category>

</item>
<item>
    <title>05.12. Doctrine 2</title>
    <link>http://blog.mayflower.de/archives/792-05.12.-Doctrine-2.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/792-05.12.-Doctrine-2.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=792</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=792</wfw:commentRss>
    

    <author>nospam@example.com (Paul Seiffert)</author>
    <content:encoded>
    &lt;style&gt;
    .serendipity_entry h1 {
        font-size: 20px;
        margin: 13px 0;
    }

    .serendipity_entry h2 {
        margin: 7px 0;
    }

    .serendipity_entry ul {
        padding-left: 3em;
    }

    .gist-data {
        max-height: 250px;
        overflow: auto;
    }
&lt;/style&gt;


&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;
    &lt;i&gt;Object-relational mapping&lt;/i&gt; (ORM) frameworks have been around for several years now and for some people, ORM is
    already outdated by now. As we have seen with other technologies and concepts before, PHP is not exactly what we call
    an early adopter among the programming languages. Thus it took some time for ORM to grow up in the PHP context.
&lt;/p&gt;

&lt;p&gt;
    There have been some frameworks before &lt;i&gt;Doctrine 2&lt;/i&gt; that implement ORM (remember e.g. &lt;a href=&quot;http://propelorm.org&quot; title=&quot;Propel&quot;&gt;Propel&lt;/a&gt;) specific tasks but most
    of them lack the required maturity to be used in large projects. With &lt;i&gt;Doctrine 2&lt;/i&gt;, PHP takes a huge step into the right
    direction  &lt;i&gt;Doctrine 2&lt;/i&gt; is fast, extensible and easy to use.
&lt;/p&gt;

&lt;p&gt;
    This article will take you on a tour through the main concepts of &lt;i&gt;Doctrine 2&lt;/i&gt; in the first part and then explain how
    to use it in a real world application in the second part. Since at the time of writing &lt;i&gt;Zend Framework&lt;/i&gt; 1.11.xx (&lt;i&gt;ZF&lt;/i&gt;) is
    very popular, we will integrate &lt;i&gt;Doctrine 2&lt;/i&gt; into a &lt;i&gt;ZF&lt;/i&gt; project.
&lt;/p&gt;
&lt;br /&gt;
        
&lt;h1&gt;Basic Concepts&lt;/h1&gt;
&lt;p&gt;
    To understand &lt;i&gt;Doctrine 2&lt;/i&gt;, we have to take a look at some relevant terms (or in this case objects), study their behavior
    and practice their usage. We start with some introductory phrases on ORM systems and then go on to the concepts underlying
    &lt;i&gt;Doctrine 2&lt;/i&gt;: &lt;i&gt;Entity Objects&lt;/i&gt;, the &lt;i&gt;Entity Manager&lt;/i&gt;, &lt;i&gt;Repositories&lt;/i&gt; and &lt;i&gt;Proxies&lt;/i&gt;.
&lt;/p&gt;
&lt;br /&gt;
&lt;h2&gt;Object-relational Mapping&lt;/h2&gt;
&lt;p&gt;
    Since the beginning of Object-Orientation, people had to manage the persistence of their application&#039;s state resp.
    their objects. In the context of Web Application Development, this usually involves a Database server which is being
    consulted using a Query Language. One example for this pattern is a PHP application that uses some kind of SQL server
    by sending SQL queries to it. Another one is an application using a CouchDB server by querying it via its REST API. &lt;br /&gt;
    Due to the author&#039;s laziness, we will talk in terms of relational databases from now on. Keep in mind, that you can
    accomplish almost everything mentioned here with NoSQL databases, too.
&lt;/p&gt;
&lt;p&gt;
    ORM relates value objects that exist in an application&#039;s business logic to database records.
    Thus every object that should be persistent is saved in one row of a database table. The most common approach is to
    map classes to tables and the classes&#039; objects to rows in the these tables.&lt;br /&gt;
    Besides writing objects to a database, ORM systems are also intended to ease the process of finding data stored in the
    database. When talking in terms of ORM, finding data always means making the framework fetch one or many objects
    that meet a certain criteria.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Entity Objects&lt;/h2&gt;
&lt;p&gt;
    The objects that are being managed by an ORM system are called &lt;i&gt;Entity Objects&lt;/i&gt;. Every entity object relates to one
    entry in a table. In &lt;i&gt;Doctrine 2&lt;/i&gt;, the classes that represent entities do not have to fulfill special requirements
    like inheriting from a certain super class (as you might have seen in other database abstraction frameworks like
    &lt;i&gt;Zend_Db&lt;/i&gt;). When creating a new entity class with &lt;i&gt;Doctrine 2&lt;/i&gt;, all you have to do is to write down a regular PHP class
    with properties. Besides this, you have to provide some hints on how these attributes should be persisted.
    The information how entity attributes relate to columns in the DB is called Metadata. Metadata can be described in
    different ways: By default there are metadata drivers for descriptions in XML, YAML and PHP. The fourth
    and most popular driver is based on DocBlock annotations (since in PHP, annotations aren&#039;t a language feature as in
    Java (see &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_annotation&quot;&gt;Wikipedia&lt;/a&gt;), they are contained by the classes&#039; and attributes&#039; DocBlocks).
    We will use annotations to describe our entities metadata. To get an impression on how easy this is,
    take a look at the following example.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430553.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    This example contains all it needs to tell &lt;i&gt;Doctrine 2&lt;/i&gt; about the new entity &lt;code&gt;User&lt;/code&gt;. With this class, you can create,
    find, delete and modify user objects and persist their state to the underlying database. But keep in mind: as long
    as you don&#039;t need any persistence features, you can use your user objects just like any other objects!
&lt;/p&gt;
&lt;p&gt;
    The next two objects resp. object types we will describe are responsible for doing the ORM functionality:
    persisting and finding.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;The Entity Manager&lt;/h2&gt;
&lt;p&gt;
    To use ORM functionality, the &lt;i&gt;Entity Manager&lt;/i&gt; (&lt;code&gt;Doctrine\ORM\EntityManager&lt;/code&gt;) is the main access point to &lt;i&gt;Doctrine 2&lt;/i&gt;. The entity manager is
    responsible  as you might have guessed  for managing entities and for building a facade for the whole framework.
    To accomplish its tasks, the entity manager uses some helpers. The &lt;i&gt;Unit of Work&lt;/i&gt; object for example collects entities
    that should be written back to the database and is capable of doing this in batches. This way, database operation
    can be executed with almost no overhead and therefore are really fast.
&lt;/p&gt;
&lt;p&gt;
    Another dependency of the entity manager is the &lt;i&gt;Event Manager&lt;/i&gt;. To be as extensible as possible, &lt;i&gt;Doctrine 2&lt;/i&gt; comes
    with an event system that publishes all important state changes to the outside as events. You can register for such
    events and extend the life cycle of your entity objects at one single point.
&lt;/p&gt;
&lt;p&gt;
    The entity manager&#039;s &lt;a href=&quot;http://www.doctrine-project.org/api/orm/2.0/doctrine/orm/entitymanager.html&quot;&gt;API&lt;/a&gt; combines methods for managing entities (&lt;code&gt;find&lt;/code&gt;, &lt;code&gt;persist&lt;/code&gt;, &lt;code&gt;contains&lt;/code&gt;, &lt;code&gt;copy&lt;/code&gt;, &lt;code&gt;detatch&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;,
    &lt;code&gt;remove&lt;/code&gt; and &lt;code&gt;refresh&lt;/code&gt;), methods that control the use of transations (&lt;code&gt;beginTransaction&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, &lt;code&gt;flush&lt;/code&gt;, &lt;code&gt;rollback&lt;/code&gt; and
    &lt;code&gt;transactional&lt;/code&gt;) and some helper methods for creating custom queries and accessing some of the entity manager&#039;s dependencies.
&lt;/p&gt;
&lt;p&gt;
    The following example shows how to query an object from the entity manager, modify it and write the changes back into
    the database.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430549.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    Creating a new persistent object is almost as easy as modifying it:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430548.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;br /&gt;
&lt;h2&gt;Repositories&lt;/h2&gt;
&lt;p&gt;
    For finding entities, &lt;i&gt;Repositories&lt;/i&gt; are used. Every entity class has its own repository which is responsible for
    finding entities of that type. By default, repositories have some handy methods for fetching entities that match certain criteria:
    &lt;ul&gt;
        &lt;li&gt;&lt;code&gt;find&lt;/code&gt;: Finds an entity by its primary key / identifier&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;findAll&lt;/code&gt;: Finds all entities of the repository&#039;s entity type&lt;/li&gt;
        &lt;li&gt;
            &lt;code&gt;findBy&lt;/code&gt; / &lt;code&gt;findOneBy&lt;/code&gt;: Finds all resp. one entity that matches the passed criteria:&lt;br /&gt;
            &lt;script src=&quot;https://gist.github.com/1430546.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
        &lt;/li&gt;
        &lt;li&gt;
            &lt;code&gt;findBy&amp;lt;attribute&amp;gt;&lt;/code&gt; / &lt;code&gt;findOneBy&amp;lt;attribute&amp;gt;&lt;/code&gt;: Magic methods that ease the filtering by a single attribute:&lt;br /&gt;
            &lt;script src=&quot;https://gist.github.com/1430544.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
        &lt;/li&gt;
    &lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
    To access a repository, all you have to do is ask the entity manager for one. If you have implemented your own
    repository, it will be returned by &lt;code&gt;Doctrine\ORM\EntityManager::getRepository()&lt;/code&gt;. Otherwise, &lt;i&gt;Doctrine 2&lt;/i&gt; will provide
    a generic repository. The main reason to implement custom repository classes is to group custom queries for an entity
    type to make them reusable. For custom query logic, there are several mechanisms you can use: You can either use
    Doctrine&#039;s query builder that implements an API similar to &lt;i&gt;Zend_Db_Select&lt;/i&gt; or queries written in the &lt;i&gt;Doctrine Query
    Language&lt;/i&gt; (&lt;i&gt;DQL&lt;/i&gt;) or you can even execute plain SQL queries. With these options, it is also possible to migrate old
    applications which use complex queries by just wrapping these queries into the methods of custom repositories.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Proxies&lt;/h2&gt;
&lt;p&gt;
    When traversing a graph of entity objects (which is required when entities are having relations to other entities),
    it would be very expensive (in the sense of requiring many database queries) to fetch every depending entity with
    an additional query. Therefore &lt;i&gt;Doctrine 2&lt;/i&gt; uses the concept of &lt;i&gt;Proxy&lt;/i&gt; objects that represent regular entity objects
    which have not been populated with data from the database. Take a look at the following example where the entity
    &lt;code&gt;Group&lt;/code&gt; aggregates a list of &lt;code&gt;User&lt;/code&gt; objects in its member property. When accessing the members list, &lt;i&gt;Doctrine 2&lt;/i&gt; provides a
    collection of proxy objects instead of complete &lt;code&gt;User&lt;/code&gt; objects. When an object of this collection is being asked for
    one of its properties, Doctrine loads the object&#039;s data from the database. This way, the users&#039; data is not loaded
    until it is really needed.
&lt;/p&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430542.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;h1&gt;Advanced Mapping Concepts&lt;/h1&gt;
&lt;p&gt;
    This section describes some advanced concepts that are required when mapping entity classes that have relationships to
    other entity classes. Possible relationship types are association and inheritance. Inheritance is the mechanism used for
    representing subtypes in object-oriented programming languages. An example would be a class &lt;code&gt;User&lt;/code&gt; that implements
    methods every user of a software should have and a class &lt;code&gt;Administrator&lt;/code&gt; inheriting from &lt;code&gt;User&lt;/code&gt; that adds methods for
    determining the administrator&#039;s access rights.
&lt;/p&gt;
&lt;p&gt;
    Association is a weaker relation type. It means that an entity object can be related to other entity objects of other
    types. In terms of relational databases, there are three types of association which differ in the number of entities
    an object is related to: 1:1, 1:n and n:m relationships. n and m are placeholders and mean multiple.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Association&lt;/h2&gt;
&lt;p&gt;
    To put objects of an entity type into relation, you just have to mention this relation in the entity class&#039; mapping
    information. The simplest case is a unidirectional 1:1 relationship. In the following example we describe a &lt;code&gt;User&lt;/code&gt; entity
    which has its access information (user credentials) encapsulated into another entity class called &lt;code&gt;UserCredential&lt;/code&gt;. Since
    every user has at most one credential object and every credential object may only be associated to one user object,
    this is a 1:1 relationship.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430540.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    If the relationship should be bidirectional, include the &lt;code&gt;OneToOne&lt;/code&gt; attribute in the other class, too, and add an
    attribute which denotes the attribute of the other entity that mapps the related object:
&lt;/p&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430535.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;p&gt;
    This way, you can access the user object from the credentials object, too.&lt;br \ /&gt;
    Most of the times, developers have to deal with relationships which include many objects on at least one side.
    These relationships are called 1:n or n:m relationships. This means that either one or multiple entities are standing
    in relationship with an arbitrary number of entities of another type. To accomplish this, you have to use the mapping
    keywords &lt;code&gt;OneToMany&lt;/code&gt; or &lt;code&gt;ManyToMany&lt;/code&gt; when describing your entities. Besides that, the mapping works the exact same way as
    with 1:1 relationships.
&lt;/p&gt;
&lt;p&gt;
    There are however some tricks you should know when dealing with collections of associated entity objects. Consider
    the following relationship between the entity classes &lt;code&gt;User&lt;/code&gt; and &lt;code&gt;Group&lt;/code&gt;:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430534.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    When a group has at least one member, the group object will have a collection of the type
    &lt;code&gt;Doctrine\Common\Collections\ArrayCollection&lt;/code&gt; set as its members property. This collection contains
    all user objects (or proxy objects as we have seen before) and can be modified intuitively with the methods &lt;code&gt;add&lt;/code&gt; and
    &lt;code&gt;removeElement&lt;/code&gt;. To honor object-orientation, you might want to introduce custom methods for these tasks. If you do so,
    you get into trouble when the group object does not have any users associated. In this case, the collection will simply be
    set to null. To avoid checks whether the collection has already be initialized, you should to this by yourself
    in the entity class&#039; constructor:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430532.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    It is also important to notice that one entity has to update the other entity&#039;s state as well when a relationship
    between to objects is created or removed. Take care to do this only in one class to avoid endless recursion loops!
    This class is called the &lt;i&gt;Owning Side&lt;/i&gt; of the relationship. When implementing a bidirectional relationship, the other
    class is called the &lt;i&gt;Inverse Side&lt;/i&gt;. It is important to determine owning and inverse side and implement the the classes
    accordingly to avoid greater trouble during debugging.
&lt;/p&gt;
&lt;p&gt;
    There are some more features implemented by &lt;i&gt;Doctrine 2&lt;/i&gt; enabling developers to specify their entities&#039; relationships
    including sorting, pre-fetching and indexing. These topics are not covered in this article but are explained very
    understandable in the &lt;a href=&quot;http://www.doctrine-project.org/docs/orm/2.1/en/reference/association-mapping.html&quot;&gt;&lt;i&gt;Doctrine 2&lt;/i&gt; documentation&lt;/a&gt;.
&lt;/p&gt;

&lt;br /&gt;
&lt;h2&gt;Inheritance&lt;/h2&gt;
&lt;p&gt;
    Subtyping can be implemented in different ways using &lt;i&gt;Doctrine 2&lt;/i&gt;. The main difference between these implementations
    is how the inheritance is mapped to the database. The options are to have one table for every class (&lt;i&gt;Class Table Inheritance&lt;/i&gt;),
    to have one table for all classes in a hierarchy (&lt;i&gt;Single Table Inheritance&lt;/i&gt;) and to have a table for every specialized
    sub-class of a given super-class (&lt;i&gt;Mapped Super Class&lt;/i&gt;).We will give a short overview on all three alternatives, you have
    to pick the right one yourself. This decision should be made based on how many common attributes there are in your sub-classes.
&lt;/p&gt;

&lt;h3&gt;Mapped Superclasses&lt;/h3&gt;
&lt;p&gt;
    Introducing a mapped superclass is probably the easiest way for specifying inheritance but might lead to
    many duplicate columns in your database schema. The superclass of your entities is not being declared as an entity
    itself (and might also be declared abstract) but provides attributes and optionally methods that will be available
    in all subclasses. When creating the database schema, &lt;i&gt;Doctrine 2&lt;/i&gt; merges all attributes and relationships of the
    superclass into the definitions of the subclasses and processes them as regular entities.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430528.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    After creating the database from this mapping information, your tables will look like this: &lt;br /&gt;
&lt;/p&gt;

&lt;img src=&quot;http://blog.mayflower.de/uploads/PaulBlog/User-AdministratorusingaMappedSuperclass.png&quot; /&gt;

&lt;h3&gt;Single Table Inheritance&lt;/h3&gt;
&lt;p&gt;
    When having entities that are very similar besides some few attributes, you might want to store them together in one
    database table. This approach is called &lt;i&gt;Single Table Inheritance&lt;/i&gt;. To distinguish between the different types, there is
    always a column marked as discriminator column and a discriminator map that tells &lt;i&gt;Doctrine 2&lt;/i&gt; which values in the
    discriminator indicate what entity types.
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430523.js?file=gistfile1.txt&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    These definitions cause the existing of one single table called User with all the attributes declared inside the
    classes User and Administrator plus a column type  the discriminator column. When working with entities of these
    types, Doctrine will manage the type flag automatically for you.
&lt;/p&gt;
&lt;p&gt;
    The resulting database schema looks as illustrated by the following diagram:&lt;br /&gt;
&lt;/p&gt;

&lt;img src=&quot;http://blog.mayflower.de/uploads/PaulBlog/User-AdministratorusingSingleTableInheritance.png&quot; /&gt;

&lt;h3&gt;Class Table Inheritance&lt;/h3&gt;
&lt;p&gt;
    Having each entity type stored in its own table is always good for keeping your schema extensible. When you have to
    create a new subtype, &lt;i&gt;Doctrine 2&lt;/i&gt; will just create a new table for this type and it can inherit the logic and common
    attributes of a superclass. The only overhead you have with this approach is that all tables that correspond to subtypes
    have to maintain a relationship to their supertype&#039;s table. Using class table inheritance, the example with the entities
    User and Administrator looks like this:
&lt;/p&gt;

&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1430465.js?file=gistfile1.aw&quot;&gt;&lt;/script&gt;
&lt;br /&gt;

&lt;p&gt;
    Besides the inheritance type, there is no difference to the example using single table inheritance. The outcome on
    the resulting database scheme is huge. Now you have to separate tables which store users and administrators. Every
    record in the table Administrator has a corresponding record in the User table.
&lt;/p&gt;

&lt;img src=&quot;http://blog.mayflower.de/uploads/PaulBlog/User-Administratorusingclasstableinheritance.png&quot; /&gt;

&lt;hr /&gt;

&lt;p&gt;
    This was the first part of this article. Stay tuned for part II which will be published tomorrow (on 6th of December 2011)! In the second part, we will integrate &lt;i&gt;Doctrine 2&lt;/i&gt; into a &lt;i&gt;Zend Framework&lt;/i&gt; application and include a generic sandbox (ZF-)project with &lt;i&gt;Doctrine 2&lt;/i&gt;!
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 05 Dec 2011 01:00:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/792-guid.html</guid>
    <category>design patterns</category>
<category>development</category>
<category>fun</category>
<category>mysql</category>
<category>namespaces</category>
<category>object orientation</category>
<category>open-source</category>
<category>opensource</category>
<category>php</category>
<category>php5</category>
<category>weihnachten</category>
<category>xmas</category>

</item>
<item>
    <title>To Protect and Surf</title>
    <link>http://blog.mayflower.de/archives/796-To-Protect-and-Surf.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/796-To-Protect-and-Surf.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=796</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=796</wfw:commentRss>
    

    <author>nospam@example.com (Martin Brotzeller)</author>
    <content:encoded>
    &lt;a href=&quot;http://it.slashdot.org/story/11/12/04/2231234/browser-history-sniffing-is-back&quot;&gt;Slashdot&lt;/a&gt; reports, that CSS History Sniffing is back - this time utilizing the latency that your browser shows when you have visited a site already. The time a browser takes to respond differs when the resource that is linked in a page is already in the browser cache. Of course that only works when you actually fetch the resources. As i described &lt;a href=&quot;http://blog.mayflower.de/archives/730-Tracking-Menaces-for-Your-Privacy.html&quot;&gt;earlier&lt;/a&gt;,  there is a Firefox extension that protects you: &lt;a href=&quot;https://www.requestpolicy.com/&quot;&gt;Request Policy&lt;/a&gt;. This extension lets you choose which sites may refer to which other sites. It&#039;s a bit tedious to get started, but it protects you not only from the ever-watching eye of social networks that load &quot;like&quot; buttons everywhere, but also from this renewed threat. 
    </content:encoded>

    <pubDate>Mon, 05 Dec 2011 01:15:11 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/796-guid.html</guid>
    <category>datenschutz</category>
<category>firefox</category>
<category>privacy</category>
<category>security</category>
<category>tracking</category>

</item>
<item>
    <title>04.12. PDF nicht nur mit PHP</title>
    <link>http://blog.mayflower.de/archives/791-04.12.-PDF-nicht-nur-mit-PHP.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/791-04.12.-PDF-nicht-nur-mit-PHP.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=791</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=791</wfw:commentRss>
    

    <author>nospam@example.com (Christian Albrecht)</author>
    <content:encoded>
    Eine Suche nach php pdf bei der Suchmaschine meiner Wahl ergibt eine Vielzahl an Tutorials, Blog-Einträgen und natürlich auch Klassen und Bibliotheken. In diesem Blog-Artikel möchte ich einen knappen Überblick über einige der gebräuchlichsten PHP-Tools zur PDF-Generierung geben und Alternativen zeigen die keine Programmierung erfordern.

&lt;h3&gt;PHP: PDF  Manual&lt;/h3&gt;

Das erste Suchergebnis führt uns auf die PHP Manual Seite. Das braucht Ihr Euch nicht anzuschauen weil es einfach nur verwirrend und unvollständig ist. Dahinter steht eine PECL Erweiterung, welche PHP einen Wrapper zur kommerziellen &lt;a href=&quot;http://www.pdflib.com/&quot;&gt;PDFlib&lt;/a&gt; bietet.

&lt;h3&gt;PDFlib&lt;/h3&gt;

Ist in Version 8 verfügbar und unterstützt laut Hersteller verschiedene Features aus Acrobat 9, der PDF-Spezifikation 1.7 extension level 3. Etwas ausführlicher betrachtet bedeutet das:
&lt;br/&gt;
&lt;br/&gt;
&lt;ul&gt; 
&lt;li&gt;Es kann über Verweise auf Ressourcen in externen PDF-Dokumenten zugegriffen werden.&lt;/li&gt; 
&lt;li&gt;Der Inhalt kann in durch den Benutzer auswählbare Ebenen aufgeteilt sein welche sich gruppieren&lt;br /&gt;lassen um zum Beispiel in Sprachspezifischen Ebenen ein und dieselbe Bildebene zu zeigen.&lt;/li&gt; 
&lt;li&gt;Bilder, Seiten und Teile von Seiten können mit Georeferenzen ausgestattet werden.&lt;/li&gt; 
&lt;li&gt;AES-256 Verschlüsselung und Unicode Passwörter werden unterstützt.&lt;/li&gt; 
&lt;/ul&gt;
&lt;br/&gt;
Im Gegensatz zum PHP:PDF  Manual bietet sich auf der Herstellerseite ein Haufen an Dokumentation. Dort findet Ihr neben einem &lt;a href=&quot;http://www.pdflib.com/en/developer/technical-documentation/pdflib-in-php-howto/&quot;&gt;Installations- und Konfigurations-Howto für PHP&lt;/a&gt;, eine 256-seitige &lt;a href=&quot;http://www.pdflib.com/developer/technical-documentation/manuals/&quot;&gt;PDFlib API Dokumentation&lt;/a&gt; und ein 312-seitiges &lt;a href=&quot;http://www.pdflib.com/developer/technical-documentation/manuals/&quot;&gt;PDFlib Tutorial&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;
Schon alleine die Länge der API Dokumentation lässt darauf schließen das die PDFlib umfangreiche Funktionen zum gestalten von PDF Dokumenten mit sich bringt. Auszugsweise, wie auch unter &lt;a href=&quot;http://www.pdflib.com/products/pdflib-family/whats-new-in-pdflib-8/&quot;&gt;What&#039;s new in PDFlib 8?&lt;/a&gt; nachzulesen:
&lt;br/&gt;
&lt;br/&gt; 
&lt;ul&gt; 
&lt;li&gt;Bidirektionale Schriftformatierung für internationale Sprachen und Fallback Fonts.&lt;/li&gt; 
&lt;li&gt;Unterstützung OpenType spezifischer Font-Features&lt;/li&gt; 
&lt;li&gt;Textumbruch um Bilder, in Pfaden sowie Text an Pfaden entlang&lt;/li&gt; 
&lt;li&gt;Transparenz in TIFF und PNG Bildern&lt;/li&gt; 
&lt;li&gt;Interaktive Formulare&lt;/li&gt; 
&lt;li&gt;Druckvorlagen Farbmanagement PDF/X-4 und PDF/X-5&lt;/li&gt; 
&lt;/ul&gt;
&lt;br/&gt;
PDFlib ist ein renommiertes Produkt und auch in PHP können damit professionelle PDF Dokumente erstellt werden.

&lt;h3&gt;Zend Framework PDF&lt;/h3&gt;

Wer etwas weniger komplexe Ansprüche an die PDF-Generierung stellt ist auch mit dem &lt;a href=&quot;http://framework.zend.com/manual/de/zend.pdf.html&quot;&gt;Zend_PDF&lt;/a&gt; Modul des unter OpenSource Lizenz veröffentlichten Zend Frameworks gut beraten.
&lt;br/&gt;
&lt;br/&gt;
&lt;ul&gt; 
&lt;li&gt;Laden von PDF Dokumenten (Acrobat 5, Spezifikation 1.4)&lt;/li&gt; 
&lt;li&gt;Versionsverwaltung: Laden von Versionen, Rollback nach Änderung&lt;/li&gt; 
&lt;li&gt;Schreiben oder Ausgeben und diese Vorgänge auf die geänderten Stellen beschränken&lt;/li&gt; 
&lt;li&gt;Seiten als Vorlagen verwenden, Seiten zu einem Dokument hinzufügen oder entfernen&lt;/li&gt; 
&lt;li&gt;Einfache Vektorgrafikelemente&lt;/li&gt; 
&lt;li&gt;Seitentransformationen (Drehen, Zoomen)&lt;/li&gt; 
&lt;li&gt;14 gebrauchsfertige PDF-Fonts, Unterstützung von TrueType Fonts&lt;/li&gt; 
&lt;li&gt;Unterstützung von Sprungzielen, Lesezeichen-Menüs, Anhängen und Aktionen&lt;/li&gt; 
&lt;li&gt;Unterstützung von Dokument Information und Metadaten&lt;/li&gt; 
&lt;/ul&gt;
&lt;br/&gt; 
Das erstellen und Laden von PDF Dokumenten geht dank der durchdachten API sehr einfach von statten. Einzig den automatisierten Textumbruch mag man vermissen. Zwar kann man sich anhand der API die Weiten der einzelnen Zeichen berechnen lassen, das erscheint dann aber doch etwas aufwendig zu sein für jedes Zeichen eines Textes.
&lt;br /&gt; &lt;br /&gt;
Verschiedene Typen von &lt;a href=&quot;http://framework.zend.com/manual/de/zend.pdf.interactive-features.html&quot;&gt;Anhängen und Aktionen&lt;/a&gt;, sofern noch nicht in Zend_PDF enthalten, lassen sich nach Lektüre der gesuchten Funktionalität in der 980-seitigen &lt;a href=&quot;http://www.adobe.com/devnet/pdf/pdf_reference_archive.html&quot;&gt;Adobe PDF Reference&lt;/a&gt; relativ einfach und schnell integrieren.




&lt;h3&gt;FPDF&lt;/h3&gt;

Verspricht High-Level Funktionen und steht auch unter OpenSource Lizenz zum Download bereit. Ebenso wie bei Zend_PDF werden PDF-Dokumente mit &lt;a href=&quot;http://www.fpdf.org/&quot;&gt;FPDF&lt;/a&gt; nur durch Einsatz von PHP generiert und es ist keine weitere Bibliothek notwendig.
&lt;br/&gt;
&lt;br/&gt;
&lt;ul&gt; 
&lt;li&gt;Auswahl der Maßeinheit, Seitenformat und -ränder&lt;/li&gt; 
&lt;li&gt;Seitenkopf- und Fußzeilen Verwaltung&lt;/li&gt; 
&lt;li&gt;Automatisierter Seitenumbruch, Zeilenumbruch und Textausrichtung&lt;/li&gt; 
&lt;/ul&gt;
&lt;br/&gt;
bietet FPDF unter anderem und füllt damit die Lücke in Bezug auf Automation der Textgestaltung. Es gibt &lt;a href=&quot;http://www.fpdf.org/en/tutorial/index.php&quot;&gt;FPDF Tutorials&lt;/a&gt; für verschiedene Anwendungsfälle und eine überschaubare &lt;a href=&quot;http://www.fpdf.org/en/doc/index.php&quot;&gt;FPDF API Dokumentation&lt;/a&gt;.&lt;br /&gt;
Anhand einer Extension &lt;a href=&quot;http://www.setasign.de/products/pdf-php-solutions/fpdi/&quot;&gt;FPDI&lt;/a&gt; ist es möglich Seiten aus anderen PDF-Dokumenten auszulesen und in das zu erstellende Dokument zu importieren.
&lt;br /&gt;
Dazu gibt es auch noch eine Menge an &lt;a href=&quot;http://www.fpdf.org/en/script/index.php&quot;&gt;FPDF Scripts&lt;/a&gt; die die Funktionalität um viele interessante Features wie Barcodes, SVG Templates bis hin zu Formularausfüllung erweitern.




&lt;h3&gt;Prince XML&lt;/h3&gt;

ist eine kommerzielle aber im Privatgebrauch kostenfreie Lösung zum erstellen von PDF-Dokumenten aus XML oder HTML Quellen mithilfe gängiger CSS 2, 2.1 und 3 Eigenschaften und Selektoren sowie eigenen CSS Erweiterungen. &lt;a href=&quot;http://www.princexml.com/&quot;&gt;Prince&lt;/a&gt; misst sich mit den gängigen Browsern im bewältigen des &lt;a href=&quot;http://www.princexml.com/samples/acid2/&quot;&gt;Acid2 Tests&lt;/a&gt; und bewirbt:
&lt;br/&gt;
&lt;br/&gt; 
&lt;ul&gt; 
&lt;li&gt;(X)(HT)ML, SVG, CSS, JPEG, PNG, TIFF, JavaScript / ECMAScript&lt;/li&gt; 
&lt;li&gt;Seitenkopf- und Fußzeilen, Seitennummerierung sowie Duplex drucken.&lt;/li&gt; 
&lt;li&gt;Mehrspalten Layouts, fließende und positionierte Blöcke&lt;/li&gt; 
&lt;li&gt;Verweise, Sprungziele, PDF-Metadaten und Anhänge&lt;/li&gt; 
&lt;li&gt;Verschlüsselung und Dokumenten Zugriffschutz&lt;/li&gt; 
&lt;/ul&gt;
&lt;br/&gt;
Neben dem Kommandozeilenprogramm gibt es auch für PHP eine Wrapperklasse und unter Windows gibt es sogar eine GUI zum bedienen des Programms. Die &lt;a href=&quot;http://www.princexml.com/doc/8.0/&quot;&gt;Dokumentation&lt;/a&gt; ist ausführlich und übersichtlich aufgebaut.&lt;br /&gt; &lt;br /&gt;
Eine schöne Lösung zum erstellen von PDF-Dokumenten wenn man sich nicht direkt mit der programmatischen Erstellung von PDF-Dokumenten beschäftigen möchte.

&lt;h3&gt;Online Service&lt;/h3&gt;

Des weiteren gibt es unzählige von kostenpflichtigen und kostenfreien Online-Services wie zum Beispiel &lt;a href=&quot;http://pdfcrowd.com/&quot;&gt;pdfcrowd&lt;/a&gt; das in der Lage ist HTML-Seiten von einer angegebenen Url oder auch mit einem WYSIWYG Editor erstelltes HTML-Dokument als PDF auszugeben. In einer kostenpflichtigen Version lassen sich dann auch noch verschiedene Optionen zur Konvertierung angeben.
&lt;br /&gt; &lt;br /&gt;
Mit &lt;a href=&quot;http://www.cometdocs.com/&quot;&gt;cometdocs&lt;/a&gt; lassen sich über 50 Dateiformate in andere Formate konvertieren. Unter anderen mit dabei Word nach PDF, HTML nach PDF und sogar Excel nach PDF. 
    </content:encoded>

    <pubDate>Sun, 04 Dec 2011 10:19:24 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/791-guid.html</guid>
    
</item>
<item>
    <title>Introducing Gigger, a Realtime Javascript Monitoring Framework</title>
    <link>http://blog.mayflower.de/archives/747-Introducing-Gigger,-a-Realtime-Javascript-Monitoring-Framework.html</link>
            <category>Development</category>
            <category>Open Source</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/747-Introducing-Gigger,-a-Realtime-Javascript-Monitoring-Framework.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=747</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=747</wfw:commentRss>
    

    <author>nospam@example.com (Felix Kaser)</author>
    <content:encoded>
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://gigger.mayflower.de/monitor.html&quot;&gt;Go to Live Demo &amp;gt;&amp;gt;&amp;gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;p&gt;Monitoring your web application is essential for professional maintenance and development. Especially if you have a high load on your website and you want to keep the current users on your site, you definitely should stay alert for problems
and be able to react fast in case of problems. Monitoring is also crucial for A/B tests, since you have to evaluate somehow which version
of your website performs better. Many big players also measure constantly how much revenue the website produces. For them it is important to monitor if a new
feature increases or decreases the revenue and take decisions based on that information.&lt;/p&gt; &lt;br /&gt;

&lt;p&gt;Mayflower is currently developing a javascript framework which provides a smart tool for realtime monitoring and measuring. Read the full article for more information.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/747-Introducing-Gigger,-a-Realtime-Javascript-Monitoring-Framework.html#extended&quot;&gt;Continue reading &quot;Introducing Gigger, a Realtime Javascript Monitoring Framework&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 22 Sep 2011 17:17:00 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/747-guid.html</guid>
    <category>ajax</category>
<category>code</category>
<category>comet</category>
<category>development</category>
<category>framework</category>
<category>javascript</category>
<category>open-source</category>
<category>opensource</category>
<category>tracking</category>

</item>
<item>
    <title>Tracking Menaces for Your Privacy</title>
    <link>http://blog.mayflower.de/archives/730-Tracking-Menaces-for-Your-Privacy.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/730-Tracking-Menaces-for-Your-Privacy.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=730</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=730</wfw:commentRss>
    

    <author>nospam@example.com (Martin Brotzeller)</author>
    <content:encoded>
    &lt;p&gt;
A &lt;a href=&quot;http://yro.slashdot.org/story/11/07/30/1458235/Researchers-Expose-Tracking-Service-That-Cant-Be-Dodged&quot;&gt;lot of&lt;/a&gt; &lt;a href=&quot;http://www.heise.de/newsticker/meldung/Websites-hebeln-Anti-Cookie-Massnahmen-aus-1288914.html&quot;&gt;people&lt;/a&gt; are &lt;a href=&quot;http://boingboing.net/2011/07/31/perma-cookie-wars-continue-kissmetrics-sneaks-cookies-back-onto-your-computer-even-if-you-turn-off-every-cookie-vector.html&quot;&gt;talking&lt;/a&gt; about a &lt;a href=&quot;http://papers.ssrn.com/sol3/papers.cfm?abstract_id=1898390&quot;&gt;particular research paper&lt;/a&gt; featured by &lt;a href=&quot;http://www.wired.com/epicenter/2011/07/undeletable-cookie/&quot;&gt;Wired&lt;/a&gt; of late. That paper describes, how users can be, and are, tracked against their express wish. Even deleting cookies does not solve the tracking problem. A lot of folks talk about how unethical, probably unlawful and unfair it is. 
&lt;/p&gt;
&lt;p&gt;
So far, although, I have not seen a site that gives more than hints how to prevent being tracked. Firefox users have a couple of tools at hand that can easily circumvent most, if not all, attack vectors. Using these measures comes at the cost of comfort, though. 
&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/730-Tracking-Menaces-for-Your-Privacy.html#extended&quot;&gt;Continue reading &quot;Tracking Menaces for Your Privacy&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Tue, 02 Aug 2011 00:19:42 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/730-guid.html</guid>
    <category>cookies</category>
<category>datenschutz</category>
<category>firefox</category>
<category>javascript</category>
<category>security</category>
<category>security2.0</category>
<category>tracking</category>

</item>
<item>
    <title>Decoupling URLs from Rewrite Rules</title>
    <link>http://blog.mayflower.de/archives/718-Decoupling-URLs-from-Rewrite-Rules.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/718-Decoupling-URLs-from-Rewrite-Rules.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=718</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=718</wfw:commentRss>
    

    <author>nospam@example.com (Martin Brotzeller)</author>
    <content:encoded>
    Apache&#039;s mod_rewrite is a really powerful tool, but with great power comes great responsibility. You wouldn&#039;t like your customer to have to edit your rewriting rules. &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/718-Decoupling-URLs-from-Rewrite-Rules.html#extended&quot;&gt;Continue reading &quot;Decoupling URLs from Rewrite Rules&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 25 Jul 2011 13:18:00 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/718-guid.html</guid>
    
</item>
<item>
    <title>About planetary-sized posters</title>
    <link>http://blog.mayflower.de/archives/411-About-planetary-sized-posters.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/411-About-planetary-sized-posters.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=411</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=411</wfw:commentRss>
    

    <author>nospam@example.com (Björn Schotte)</author>
    <content:encoded>
    &lt;p&gt;
Geez, what a week! On Friday, we&#039;ll party on &lt;a href=&quot;http://blog.thinkphp.de/archives/408-PHP-5.3-BBQ-Release-Party-in-Munich.html&quot;&gt;celebrating the PHP 5.3 release&lt;/a&gt; in Munich/Germany. For those of you who can&#039;t be there, I&#039;m sure there will be enough photos on Flickr, Facebook and the like. But, as you may remember, we&#039;ve produced some very cool Zend Framework posters. I just got an e-mail from Rob Zienert about planetary-sized posters :-)
&lt;/p&gt;
&lt;p&gt;&amp;#160;&lt;/p&gt;
&lt;p&gt;
If you want to experience the true size of our Zend Framework poster, &lt;a href=&quot;mailto:bjoern.schotte@mayflower.de&quot;&gt;just drop me an e-mail&lt;/a&gt; and tell me your company address and if you want to have the poster in English (as long as it&#039;s available) or German. Oh, and btw, we&#039;re currently finishing a PHP Web Security poster (at the same size) by Stefan Esser from &lt;a href=&quot;http://www.sektioneins.de/&quot;&gt;SektionEins&lt;/a&gt;. Don&#039;t miss it!
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 13 Jul 2009 23:17:01 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/411-guid.html</guid>
    
</item>
<item>
    <title>Redis - Vortrag@Mayflower-Würzburg</title>
    <link>http://blog.mayflower.de/archives/705-Redis-VortragMayflower-Wuerzburg.html</link>
            <category>Events</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/705-Redis-VortragMayflower-Wuerzburg.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=705</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=705</wfw:commentRss>
    

    <author>nospam@example.com (Andreas Ganje)</author>
    <content:encoded>
    Am kommenden &lt;b&gt;Donnerstag, den 16.06.2011&lt;/b&gt; findet ein weiterer öffentlicher Vortrag im Mayflower-Büro in Würzburg statt (Pleichertorstrasse 2, 97070 Würzburg, Straßenbahn und die Haltestelle Congress Centrum). &lt;br /&gt;Beginn ist um 18:00 Uhr, Thema des Vortrags ist &quot;&lt;b&gt;Redis&lt;/b&gt;&quot;.

&lt;br /&gt;&lt;br /&gt;
In dem Vortrag von &lt;b&gt;Peter Voringer&lt;/b&gt; geht es um die Funktionalität und den Einsatzbereich/-möglichkeiten von Redis, sowie die PHP Client Library Rediska.

&lt;br /&gt;&lt;br /&gt;

Die Donnerstags-Vorträge werden sowohl in Würzburg als auch in München gehalten. Bei Interesse einfach das Blog beobachten, um auf dem Laufenden zu bleiben!

&lt;br /&gt;

Wir freuen uns auf viele Teilnehmer!

&lt;br /&gt;&lt;br /&gt;

&lt;a href=&quot;http://maps.google.de/maps?f=q&amp;source=s_q&amp;hl=de&amp;geocode=&amp;q=97070+Pleichertorstrasse+2&amp;sll=51.151786,10.415039&amp;sspn=9.8995,28.256836&amp;ie=UTF8&amp;hq=&amp;hnear=Pleichertorstra%C3%9Fe+2,+W%C3%BCrzburg+97070+W%C3%BCrzburg,+Bayern&amp;ll=49.799938,9.926319&amp;spn=0.009944,0.027595&amp;z=15&amp;iwloc=A&quot;&gt;Anfahrt zum Mayflowerbüro Würzburg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;Zur Anmeldung einfach einen Kommentar im Beitrag hinterlassen.&lt;/b&gt; 
    </content:encoded>

    <pubDate>Mon, 13 Jun 2011 23:20:58 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/705-guid.html</guid>
    
</item>
<item>
    <title>Creating coding standards for PHP_CodeSniffer</title>
    <link>http://blog.mayflower.de/archives/631-Creating-coding-standards-for-PHP_CodeSniffer.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/631-Creating-coding-standards-for-PHP_CodeSniffer.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=631</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=631</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Schlichtholz)</author>
    <content:encoded>
    &lt;div style=&quot;text-align: justify&quot;&gt;When our project is supervised by a continous integration platform, we are (hopefully) using static code analysis tools. One of the best for analysing PHP code
is PHP_CodeSniffer which integrates fine into systems like PhpUnderControl, Hudson or Bamboo. But in some cases the pre-installed coding standards like PEAR or Zend might not be sufficient for our
current project or we want to deviate. This is the moment when we want to be able to create a custom one that fits our special needs. In this article I want to share my first experiences
with you about how to create a custom coding standard for PHP_CodeSniffer.&lt;/div&gt;
 &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/631-Creating-coding-standards-for-PHP_CodeSniffer.html#extended&quot;&gt;Continue reading &quot;Creating coding standards for PHP_CodeSniffer&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 24 Feb 2011 17:21:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/631-guid.html</guid>
    
</item>
<item>
    <title>Cinder now available at Mayflower Open Source Labs</title>
    <link>http://blog.mayflower.de/archives/627-Cinder-now-available-at-Mayflower-Open-Source-Labs.html</link>
            <category>Open Source</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/627-Cinder-now-available-at-Mayflower-Open-Source-Labs.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=627</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=627</wfw:commentRss>
    

    <author>nospam@example.com (Florian Anderiasch)</author>
    <content:encoded>
    &lt;p&gt;&lt;a href=&quot;http://confluence.opensource.mayflower.de/display/CINDER/Home&quot;&gt;Cinder&lt;/a&gt; is a plug-in for your eclipse-based IDE (eclipse, Zend Studio, etc.) to display results of your Continuous Integration environment right inside your IDE.&lt;/p&gt; 
&lt;p&gt;&lt;br /&gt;We just released version 0.1.6, which you can install via the Eclipse Update Manager and the URL &lt;a href=&quot;http://opensource.mayflower.de/cinder&quot;&gt;http://opensource.mayflower.de/cinder&lt;/a&gt;, then activating it via &amp;quot;Window -&amp;gt; Show View -&amp;gt; Other -&amp;gt; Cinder&amp;quot;.&lt;/p&gt; 
&lt;p&gt;&lt;br /&gt;If you haven&#039;t heard of Cinder yet, here&#039;s a short summary:&lt;/p&gt; 
&lt;p&gt;&lt;br /&gt;You open the XML file containing the errors and warnings of your build (for us that&#039;s typically the PHP_CodeBrowser XML generated by a Hudson build) and get an overview of reports. Now you can sort them, categorize them and work on them in any order. Cinder can grab these files periodically if you make them available via http or on a filesystem.&lt;/p&gt; 
&lt;p&gt;&lt;br /&gt;A few screenshots:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; 
&lt;div style=&quot;width: 600px;&quot; class=&quot;serendipity_imageComment_center&quot;&gt; 
&lt;div class=&quot;serendipity_imageComment_img&quot;&gt;&lt;!-- s9ymdb:477 --&gt;&lt;img width=&quot;600&quot; src=&quot;http://blog.mayflower.de/uploads/opensource/cinder01.png&quot; class=&quot;serendipity_image_center&quot; /&gt;&lt;/div&gt; 
&lt;div class=&quot;serendipity_imageComment_txt&quot;&gt;The Cinder View after reading an XML file.&lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;br /&gt;&lt;/p&gt; 
&lt;div style=&quot;width: 645px;&quot; class=&quot;serendipity_imageComment_center&quot;&gt; 
&lt;div class=&quot;serendipity_imageComment_img&quot;&gt;&lt;!-- s9ymdb:478 --&gt;&lt;img height=&quot;520&quot; width=&quot;645&quot; src=&quot;http://blog.mayflower.de/uploads/opensource/cinder02.png&quot; class=&quot;serendipity_image_center&quot; /&gt;&lt;/div&gt; 
&lt;div class=&quot;serendipity_imageComment_txt&quot;&gt;After selecting a warning the file is opened at the matching line.&lt;/div&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;br /&gt;Bug reports, ideas and feedback are welcome, please visit &lt;a href=&quot;http://github.com/winks/cinder&quot;&gt;the github page&lt;/a&gt;to tell us about your ideas.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 23 Dec 2010 13:56:35 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/627-guid.html</guid>
    <category>cinder</category>
<category>continuous-integration</category>
<category>cruisecontrol</category>
<category>eclipse</category>
<category>hudson</category>
<category>opensource</category>
<category>zendstudio</category>

</item>
<item>
    <title>PHP_CodeBrowser goes stable</title>
    <link>http://blog.mayflower.de/archives/626-PHP_CodeBrowser-goes-stable.html</link>
            <category>Open Source</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/626-PHP_CodeBrowser-goes-stable.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=626</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=626</wfw:commentRss>
    

    <author>nospam@example.com (Simon Kohlmeyer)</author>
    <content:encoded>
    &lt;p&gt;We already &lt;a title=&quot;http://github.com/mayflowergmbh/PHP_CodeBrowser&quot; href=&quot;http://github.com/mayflowergmbh/PHP_CodeBrowser&quot;&gt;wrote about CodeBrowser 0.9 in August&lt;/a&gt; and after fixing a few minor bugs the &lt;a target=&quot;_blank&quot; href=&quot;http://opensource.mayflower.de&quot;&gt;Mayflower Open Source Labs Team&lt;/a&gt; is very happy to present PHP_CodeBrowser 1.0.0.&lt;/p&gt; 
&lt;p&gt;The new version is already available on pear.phpunit.de. To check it out, just run&lt;/p&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;blockquote&gt;&lt;code&gt;
&amp;#160; pear channel-discover pear.phpunit.de&lt;br /&gt;
&amp;#160; pear install phpunit/PHP_CodeBrowser
&lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;p&gt;or, if you have already installed PHP_CodeBrowser, you can upgrade with&lt;/p&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;blockquote&gt;&lt;code&gt;
&amp;#160; pear upgrade phpunit/PHP_CodeBrowser
&lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;p&gt;If you would like to see any features in the next releases , please visit &lt;a title=&quot;http://github.com/mayflowergmbh/PHP_CodeBrowser&quot; href=&quot;http://github.com/mayflowergmbh/PHP_CodeBrowser&quot;&gt;the github page&lt;/a&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt; &lt;/span&gt;and tell us about your ideas.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 14 Dec 2010 18:52:05 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/626-guid.html</guid>
    
</item>
<item>
    <title>OpenSocial</title>
    <link>http://blog.mayflower.de/archives/618-OpenSocial.html</link>
            <category>Development</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/618-OpenSocial.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=618</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=618</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Prokscha)</author>
    <content:encoded>
    Three years ago, on the 1st of November 2007, Google released 
OpenSocial. A lot of time and development work has passed since then. It
 is a perfect time to deal with it, so in this blog we get to learn where 
OpenSocial is today and how it actually works (&lt;a href=&quot;http://blog.mayflower.de/archives/617-OpenSocial.html&quot; target=&quot;_self&quot;&gt;read german version&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/618-OpenSocial.html#extended&quot;&gt;Continue reading &quot;OpenSocial&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 22 Nov 2010 09:19:21 +0100</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/618-guid.html</guid>
    
</item>
<item>
    <title>(Pseudo)dynamic data generation in JMeter</title>
    <link>http://blog.mayflower.de/archives/566-Pseudodynamic-data-generation-in-JMeter.html</link>
            <category>Development</category>
            <category>Misc</category>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/566-Pseudodynamic-data-generation-in-JMeter.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=566</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=566</wfw:commentRss>
    

    <author>nospam@example.com (Anatoliy Belsky)</author>
    <content:encoded>
    What if you have to do extensive performance tests for a complicated webapp with login, search forms,  etc.? If the tool you would use for this must be very powerful, opensource and have graphic interface  there is no way you can pass by JMeter. At this time I&#039;ll tell about how to get dynamical data to be used inside JMeter tests. I&#039;ll presume you&#039;ve already worked with JMeter before and have at least knowhow about a standard test plan structure.
&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/566-Pseudodynamic-data-generation-in-JMeter.html#extended&quot;&gt;Continue reading &quot;(Pseudo)dynamic data generation in JMeter&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Tue, 07 Sep 2010 13:55:00 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/566-guid.html</guid>
    
</item>
<item>
    <title>Contributing to ZendFramework</title>
    <link>http://blog.mayflower.de/archives/587-Contributing-to-ZendFramework.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/587-Contributing-to-ZendFramework.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=587</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=587</wfw:commentRss>
    

    <author>nospam@example.com (Stefan Staudenmeyer)</author>
    <content:encoded>
    &lt;h3&gt;... on contribution&lt;/h3&gt; 
&lt;p&gt;Who hasn&#039;t ever started writing his own Framework/CMS? It is considered best practice for learning purposes, but going through all the security stuff can be stressful and boring at the same time. That&#039;s where most devs start to contribute to big Open Source-projects like Typo3 or the Zend Framework, because they are already experienced working with it and yet evolving another system on the market or even getting people to contribute seems like an unachievable task. Instead of wasting his time on yet another ACL implementation, the developer is taking part in making a software become even better, no matter if he delivers new features, reports / fixes bugs or works on documentation (another, yet an often underestimated part of contribution). It is also worth noting that every single Blog-entry and every HowTo thats put on the web also is a great deal of contribution that helps the software spreading. Beginners articles are important to put on the web since every one of us had it&#039;s beginnings and these are the sort of articles where many people decide to either use the software for a certain project or not.&lt;/p&gt; 
&lt;p&gt;As you might see, this article is not only a guide on contributing bugfixes, but also I want to motivate you to just give it a try.&lt;/p&gt; 
&lt;h3&gt;... on Zend Framework&lt;/h3&gt; 
&lt;p&gt;Having spent almost a year at the IRC support channel, I can tell they&#039;re really fun guys to hang around with. Of course, the Framework itself developed into a great piece of software. I do not want to discuss the up or downsides of a use-at-will framework, neither I want to recommend it over {put your favourite software here}. But what I can talk about is a little summary of the support channel&#039;s chatlogs. The widely annouced channel (which is #zftalk on Freenode) includes all kinds of concerns. One kind of people finds bugs, the other do have really clever ideas on improvements, but when you ask them to contribute its all the same: they either think it takes years to get into it, the others think they might be &amp;quot;not good enough for this&amp;quot;. We sure won&#039;t force or threaten people to contribute, but what I can do is taking the fear out of it and demystify the thing, so later you might see that its actually just a few minutes to spend. Let me just loose a few words to the latter ones before we get into it: You can&#039;t destroy anything, and every idea of yours can also lead to a great improvement either realted to your concern or in a completely different area. We&#039;re glad that you take your time, even if you are completely new to ZF. Some beginners concerns already caused developers to write guides and articles that are still around and are linked at times in #zftalk...&lt;/p&gt; 
&lt;h3&gt;... on contributing to Zend Framework&lt;/h3&gt; 
&lt;p&gt;Contributing any code to ZF requires signing the CLA, which is an agreement that both you have the right to share any code you supply, and that you will not patent that code. This is to ensure that the frameworks codebase remains business friendly, and free to use for everyone. In fact you have to actually sign a paper, having done this you can just scan and mail or fax it. This is an important step, and none of your code will be used in any official package unless you did this.&lt;/p&gt; 
&lt;p&gt;The next step will be reading the coding &amp;amp; subversion standards. If you already had a look at actual ZF components code you should be familiar with the standards. Once you took a short insight (you probably wont be able to just remember all of this at once), you can check out the official SVN repository. Notice, that you, even having signed the CLA and being confirmed, do not have commit rights. So you might now ask yourself how to contribute then? All magic is taking place in the bugtracker, ZF&#039;s official Jira. All bug tickets, additions and improvements are filed as tickets here. So if you find a bug, report it here, and soon there will be a discussion in the comments section of a ticket.&lt;/p&gt; 
&lt;p&gt;Mostly all of these people, being listed by their reallife names, are also to be found on different names in the support channel, so feel free to ask them any ticket-related stuff.&lt;/p&gt; 
&lt;p&gt;The code itself will be submitted as a patch file (svn diff &amp;gt; patchFile), and uploaded in the Jira-Ticket. This might also be done by people who do have commit rights, but one might not be sure how to fix a problem, or any question might be left. This method of code management then leaves it to the original package developer to decide whether a change should be made or it should be thought over again (might have side effects on other packages and so on).&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://blog.mayflower.de/uploads/sstaudenmeyer/2010-09-01-ZF_SvnPatch.jpg&quot;&gt;&lt;img src=&quot;http://blog.mayflower.de/uploads/sstaudenmeyer/2010-09-01-ZF_SvnPatch_prev.jpg&quot; style=&quot;margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; &quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;The last yet very important point is unit tests. ZF makes heavy use of them and so should you. The best you can do is report bugs as failing tests with a short description, fix them with the code diff and then deliver them with working tests.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://blog.mayflower.de/uploads/sstaudenmeyer/2010-09-01-ZF_SvnDiff.jpg&quot;&gt;&lt;img src=&quot;http://blog.mayflower.de/uploads/sstaudenmeyer/2010-09-01-ZF_SvnDiff_prev.jpg&quot; style=&quot;margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; &quot; /&gt;&lt;/a&gt; &lt;/p&gt; 
&lt;h3&gt;... in closing&lt;/h3&gt; 
&lt;p&gt;As you might now see, once the problems and the contaminated areas are visible, you can pull out your armory and kill the bugs within minutes. The contribution of new packages for the ZF are made in the Wiki, filed as proposals that later get discussed by the community review team, but I might do another article about that one as its a not so trivial workflow. Whenever you fix a bug or deliver an improvement you will be listed on the official Jira´s Overview page of top contributors. Can you make it to the top? ZF´s bug hunting days are the place for many contributors to join the battle on a shirt, but you might also see that being an active contributor on an open source project might be a good point of interest on your CV.&lt;/p&gt; 
&lt;p&gt;Having run out of things to say, I want to call all the devs out there to give it a try. A short quote of Ben Scholzen (ZF Core developer): &amp;quot;I code whenever I feel like it&amp;quot;: In closing, remember that neither having an account on JIRA nor Signing the CLA ties you in to any minimum commitment, and you can do as much or as little as you are comfortable with. Just pick the level which feels right for you.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://blog.mayflower.de/uploads/sstaudenmeyer/2010-09-01-ZF_JiraGraph.jpg&quot;&gt;&lt;img src=&quot;http://blog.mayflower.de/uploads/sstaudenmeyer/2010-09-01-ZF_JiraGraph_prev.jpg&quot; style=&quot;margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; &quot; /&gt;&lt;/a&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 01 Sep 2010 10:13:48 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/587-guid.html</guid>
    <category>contribution</category>
<category>framework</category>
<category>php</category>
<category>zend framework</category>
<category>zf</category>

</item>
<item>
    <title>MySQLnd Plugins: Writing a MySQL Query Logger in PHP</title>
    <link>http://blog.mayflower.de/archives/578-MySQLnd-Plugins-Writing-a-MySQL-Query-Logger-in-PHP.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/578-MySQLnd-Plugins-Writing-a-MySQL-Query-Logger-in-PHP.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=578</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=578</wfw:commentRss>
    

    <author>nospam@example.com (David Soria Parra)</author>
    <content:encoded>
    &lt;p&gt;
During the development of an application, not all time is spent 
on writing code. A lot of time is spent on reading debug output, 
crawling through log files and firing up the debugger to figure 
out what the application does. While the debugger helps us to 
inspect details of a running application on a testing 
environment, logfiles are often the only indication of the origin 
of an error on a production system. In this blogpost I want to 
describe how to log SQL statements on an existing application
without touching any existing line of code at all. We will use a new
MySQLnd Extension developed at the &lt;a href=&quot;http://opensource.mayflower.de&quot;&gt;Mayflower OpenSource Labs&lt;/a&gt; for
that purpose.
&lt;/p&gt;&lt;p&gt;
As an example, I will use &lt;a href=&quot;http://phprojekt.com&quot;&gt;PHProjekt 6&lt;/a&gt;. The project is 
particularly suitable for demonstration purposes as it has a 
logging infrastructure for function calls, but does not log SQL 
statements.
&lt;/p&gt;
 &lt;br /&gt;&lt;a href=&quot;http://blog.mayflower.de/archives/578-MySQLnd-Plugins-Writing-a-MySQL-Query-Logger-in-PHP.html#extended&quot;&gt;Continue reading &quot;MySQLnd Plugins: Writing a MySQL Query Logger in PHP&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 16 Aug 2010 14:50:00 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/578-guid.html</guid>
    <category>mysql</category>
<category>opensource</category>
<category>opensource labs</category>
<category>pecl</category>
<category>php5</category>

</item>
<item>
    <title>PHP_CodeBrowser 0.9.0 is out</title>
    <link>http://blog.mayflower.de/archives/575-PHP_CodeBrowser-0.9.0-is-out.html</link>
            <category>PHP</category>
    
    <comments>http://blog.mayflower.de/archives/575-PHP_CodeBrowser-0.9.0-is-out.html#comments</comments>
    <wfw:comment>http://blog.mayflower.de/wfwcomment.php?cid=575</wfw:comment>

    <slash:comments>7</slash:comments>
    <wfw:commentRss>http://blog.mayflower.de/rss.php?version=2.0&amp;type=comments&amp;cid=575</wfw:commentRss>
    

    <author>nospam@example.com (Simon Kohlmeyer)</author>
    <content:encoded>
    &lt;p&gt;
PHP_CodeBrowser is a tool that creates good looking web pages from your code and annotates them with problems found by checkstyle, pmd and others.&lt;br /&gt;&lt;br /&gt;

We have covered the release of PHP_CodeBroser version 0.1.0-alpha some months ago, see &lt;a href=&quot;http://blog.mayflower.de/archives/464-PHP_CodeBrowser-Release-version-0.1.0.html&quot; title=&quot;PHP_CodeBrowser Release version 0.1.0&quot;&gt;this post&lt;/a&gt;. Now, we&#039;re proud to announce version 0.9.0-beta.&lt;/p&gt; 
&lt;p&gt;It features a neat interface that let you find errors even quicker, a clear commandline interface and much better performance, it&#039;s almost seven times faster than the 0.1.x release.&lt;/p&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;p&gt;You can get it via pear, just do&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt; &lt;em&gt;pear channel-discover pear.phpunit.de&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;pear config-set preferred_state beta&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;em&gt;pear install phpunit/PHP_CodeBrowser&lt;/em&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;or you can check out the from github, just visit &lt;a href=&quot;http://github.com/mayflowergmbh/PHP_CodeBrowser&quot; title=&quot;github page&quot;&gt;http://github.com/mayflowergmbh/PHP_CodeBrowser&lt;/a&gt; or just try&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt;&lt;em&gt;git clone git://github.com/mayflowergmbh/PHP_CodeBrowser.git&lt;/em&gt; &lt;br /&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&amp;#160;Here are some pictures to give you an impression of what it looks like&lt;/p&gt; 
&lt;p&gt;This is the overview page&lt;/p&gt; 
&lt;p&gt; &lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:453 --&gt;&lt;img style=&quot;width: 704px; height: 500px;&quot; src=&quot;http://blog.mayflower.de/uploads/opensource/PHPCodeBrowser-Screenshot-Overview.png&quot; class=&quot;serendipity_image_center&quot; /&gt; &lt;/p&gt; 
&lt;p&gt;And this is how the real code browser looks like.&lt;/p&gt; 
&lt;p&gt;&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:454 --&gt;&lt;!-- s9ymdb:455 --&gt;&lt;img style=&quot;width: 708px; height: 500px;&quot; src=&quot;http://blog.mayflower.de/uploads/opensource/PHPCodeBrowser-Screenshot-Reviewkleiner.png&quot; class=&quot;serendipity_image_center&quot; /&gt;&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 12 Aug 2010 16:12:02 +0200</pubDate>
    <guid isPermaLink="false">http://blog.mayflower.de/archives/575-guid.html</guid>
    <category>php phpunit motivation php5</category>

</item>

</channel>
</rss>
