<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Akra's DevNotes</title>
	<atom:link href="http://akrabat.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://akrabat.com</link>
	<description>Developing PHP and XUL Software in the Real World</description>
	<pubDate>Fri, 16 May 2008 21:00:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Simple Zend_Form File Upload Example Revisited</title>
		<link>http://akrabat.com/2008/05/16/simple-zend_form-file-upload-example-revisited/</link>
		<comments>http://akrabat.com/2008/05/16/simple-zend_form-file-upload-example-revisited/#comments</comments>
		<pubDate>Fri, 16 May 2008 21:00:29 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<category><![CDATA[zend_form]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=248</guid>
		<description><![CDATA[I've been thinking about the Simple Zend_Form File Upload Example that I discussed last month.
To recap, if you haven't read the comments, if the form fails to validate for some reason then you get a nasty error:
Warning: htmlspecialchars() expects parameter 1 to be string, object given in /Users/rob/Sites/akrabat/Zend_Form_FileUpload_Example/lib/Zend/View/Abstract.php on line 786
Essentially, what is happening is [...]]]></description>
			<content:encoded><![CDATA[<p>I've been thinking about the <a href="/2008/04/07/simple-zend_form-file-upload-example/">Simple Zend_Form File Upload Example</a> that I discussed last month.</p>
<p>To recap, if you haven't read the comments, if the form fails to validate for some reason then you get a nasty error:</p>
<p><strong>Warning: htmlspecialchars() expects parameter 1 to be string, object given in /Users/rob/Sites/akrabat/Zend_Form_FileUpload_Example/lib/Zend/View/Abstract.php on line 786</strong></p>
<p>Essentially, what is happening is that the <tt>App_Form_Element_File</tt> class that we wrote assigns the <tt>$_FILES</tt> array to the <tt>$value</tt> parameter for the form element. On redisplay of the form, the <tt>formFile</tt> view helper then calls the <tt>escape()</tt> view helper passing in the <tt>$value</tt> when rendering the <tt>&lt;input&gt;</tt> element. The <tt>escape()</tt> view helper calls <tt>htmlspecialchars()</tt> which throws the warning about <tt>$value</tt> not being a string. </p>
<p><b>*whew!*</b></p>
<p>What we need is something that's an array when the data is valid, but can also look like a string to <tt>htmlspecialchars()</tt>. This got me thinking about the SPL and creating an object for the data from the <tt>$_FILES</tt> array.</p>
<p>Let's call this object <tt>App_Form_Element_FileValue</tt> and store it in <tt>lib/App/Form/Element/FileValue.php</tt>:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php

</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">App_Form_Element_FileValue&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">ArrayObject
</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #0000BB">__toString</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$result&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$result&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">$result</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</span>
</span></code></pre>
<p>The <tt>ArrayObject</tt> class is part of the SPL and handily provides a set of functions that enables the object to work with most functions that we like to use with an array including the ability to access the data using array notation. We implement the PHP5 magic function <tt>__toString()</tt> so that <tt>htmlspecialchars()</tt> will get a string from the object when it asks for one which nicely knocks that problem on the head.</p>
<p>To integrate it into the code, we need to modify <tt>App_Form_Element_File::isValid()</tt> from:</p>
<pre class="phpcode"><span style="color: #0000BB">
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$context&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;for&nbsp;a&nbsp;file&nbsp;upload,&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;POST&nbsp;array,&nbsp;it's&nbsp;in&nbsp;$_FILES
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getName</span><span style="color: #007700">();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">null&nbsp;</span><span style="color: #007700">===&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isset(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #0000BB">$key</span><span style="color: #007700">]))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$value&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #0000BB">$key</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;continues&#8230;
</span>
</span></code></pre>
<p>to</p>
<pre class="phpcode"><span style="color: #0000BB">
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$context&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;for&nbsp;a&nbsp;file&nbsp;upload,&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;POST&nbsp;array,&nbsp;it's&nbsp;in&nbsp;$_FILES
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getName</span><span style="color: #007700">();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">null&nbsp;</span><span style="color: #007700">===&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isset(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #0000BB">$key</span><span style="color: #007700">]))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$value&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">App_Form_Element_FileValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #0000BB">$key</span><span style="color: #007700">]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;continues&#8230;
</span>
</span></code></pre>
<p>We also need to modify the validator <tt>App_Validate_ValidFile::isValid()</tt> function as it's rather too rigourous in its checking. We currently check that <tt>$value</tt> is an array using <tt>is_array()</tt>:</p>
<pre class="phpcode"><span style="color: #0000BB">
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;default&nbsp;value&nbsp;and&nbsp;error&nbsp;is&nbsp;"no&nbsp;file&nbsp;uploaded"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$valueString&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$error&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_NO_FILE</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">is_array</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;&amp;&amp;&nbsp;</span><span style="color: #0000BB">array_key_exists</span><span style="color: #007700">(</span><span style="color: #DD0000">'error'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;set&nbsp;the&nbsp;error&nbsp;to&nbsp;the&nbsp;correct&nbsp;value
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$error&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">[</span><span style="color: #DD0000">'error'</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;set&nbsp;the&nbsp;%value%&nbsp;placeholder&nbsp;to&nbsp;the&nbsp;uplaoded&nbsp;filename
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$valueString&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;continues&#8230;
</span>
</span></code></pre>
<p>As <tt>$value</tt> is now an object of type <tt>App_Form_Element_FileValue</tt>, we need to change the test in the <tt>if</tt> statement to:</p>
<pre class="phpcode"><span style="color: #0000BB">
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;default&nbsp;value&nbsp;and&nbsp;error&nbsp;is&nbsp;"no&nbsp;file&nbsp;uploaded"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$valueString&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$error&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_NO_FILE</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((</span><span style="color: #0000BB">is_array</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;||&nbsp;</span><span style="color: #0000BB">$value&nbsp;</span><span style="color: #007700">instanceof&nbsp;</span><span style="color: #0000BB">ArrayObject</span><span style="color: #007700">)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;</span><span style="color: #0000BB">array_key_exists</span><span style="color: #007700">(</span><span style="color: #DD0000">'error'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;set&nbsp;the&nbsp;error&nbsp;to&nbsp;the&nbsp;correct&nbsp;value
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$error&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">[</span><span style="color: #DD0000">'error'</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;set&nbsp;the&nbsp;%value%&nbsp;placeholder&nbsp;to&nbsp;the&nbsp;uplaoded&nbsp;filename
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$valueString&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;continues&#8230;
</span>
</span></code></pre>
<p>Note that we test for an instance of <tt>ArrayObject</tt> as that is where the functionality of array behaviour is implemented and is more generic in case we need to reuse this code with another object that behaves like an array.</p>
<p>Those are the only changes needed to elegantly remove the error message. </p>
<p>Here's a zip file of this project with the above changes: <a href="/wp-content/uploads/Zend_Form_FileUpload_Example_Revisited.zip">Zend_Form_FileUpload_Example_Revisited.zip</a> (It includes Zend Framework 1.5.2 which is why it's 3.9MB big).</p>
<p>Test it out and see if it works for you as well as it works for me !</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/05/16/simple-zend_form-file-upload-example-revisited/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A review of &#8220;Learning PHP Data Objects&#8221;</title>
		<link>http://akrabat.com/2008/05/04/a-review-of-learning-php-data-objects/</link>
		<comments>http://akrabat.com/2008/05/04/a-review-of-learning-php-data-objects/#comments</comments>
		<pubDate>Sun, 04 May 2008 09:52:17 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=245</guid>
		<description><![CDATA[
Packt Publishing recently sent me a couple of books to review. This post is about the second one I received, Learning PHP Data Objects by Dennis Popel. I was excited to receive this book as PDO underlies a lot of the Zend_Db_Adapter objects that I use in my day to day programming. It seemed like [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://akrabat.com/wp-content/uploads/packt-learning-pdo.png" alt="packt_learning_pdo.png" border="0" width="97" height="123" class="left" /></p>
<p><a href="http://www.packtpub.com/">Packt Publishing</a> recently sent me a couple of books to review. This post is about the second one I received, <a href="http://www.packtpub.com/oop-php-5/book">Learning PHP Data Objects</a> by Dennis Popel. I was excited to receive this book as PDO underlies a lot of the Zend_Db_Adapter objects that I use in my day to day programming. It seemed like a good idea that I should know more about it. </p>
<h3>Overview of the book</h3>
<p>This book starts out introducing PDO and then takes us on a tour through all its features including error handling and prepared statements along with more advanced features like scrollable cursors. </p>
<p>The first chapter introduces PDO and shows the basics of how to use it to connect to a database, issue a query and retrieve the resultant data. The author also makes the distinction about how the code he is showing is example code and provides pointers to what's missing (such as proper error messages) if you were to use the code in production. I liked this very much as it's important as authors that we realise that inexperienced readers have a tendency to copy/paste examples and use as-is. The introductory chapter closes with a look at prepared statements and so covers all the high points of PDO.</p>
<p>Having introduced the subject, chapter 2 looks in detail at using PDO to connect to a database. This chapter is more tutorial-ish and the code is presented to be typed in. A worked example of a book database is used from here on throughout the rest of the book. The author appears to expect the user to learn what the code does by reading the comments within the code body, as there is little explanation of what the code does in the prose. One thing that's tricky is that when there is explanation after a code block, it's hard to work out which bit of the block the author is referring to. On the whole though, the tutorial nature provides step-by-step progress for people who learn best that way.</p>
<p>Chapter 3 covers error handling. I was pleased to see this important topic given an entire chapter and so early in the book. Error handling is not an after thought here. This chapter provides a good discussion of the types of errors that you will encounter and then provides instructions on how to handle them. Again, the tutorial aspect of the book is emphasised with lots of code to type in. Some of it is in bold, but I'm not sure why as no reference is made to it in the prose. This chapter also starts a dangerous trend where four pages of code is presented (without line numbers) and then the following page or so dissects the code with reference to line numbers that do not exist! This makes the explanation of the code really hard to follow, especially when the you get to the section about lines 189 to 191&#8230;  This chapter also continues the tutorial by building more pages and showing you how to check for errors along the way.</p>
<p>Chapter 4 studies prepared statements and shows how to use them. Positional and named placeholders are looked at, along with how to insert blobs using bound parameters. In this chapter, the bold sections in the code make more sense as they are referenced in the prose. Again, we have pages of code with no line numbers and then are asked to study lines 60 to 73. The information in this chapter is nevertheless very good and I learnt stuff :)</p>
<p>Having looked at getting data into the application, chapter 5 looks at retrieval and rowsets. This chapter covers counting the number of rows returned and limiting rowsets. It's much shorter as it covers less topics and I'm glad the author didn't pad the chapter just to get the page count up! Chapter 6 is also relatively short, but this time covers a lot of ground. These are advanced topics and include connection attributes, buffered queries, dsn files for connections and transactions. The transactions section gets the most space and is covered quite less, though with rather less prose for the volume of code than I would have liked.</p>
<p>The last chapter in the book is a bit of an odd ball as it looks as designing a model within an MVC application. To me this didn't fit with the specialist PDO nature of the book, and I'd have rather have had more space devoted to transactions or database specific issues.</p>
<h3>In summary</h3>
<p>This book is an good, detailed tutorial for understanding PDO. It is not a reference book and so relatively hard to dip into to look up a specific thing. If you learn by starting from scratch and working your way through, then this is a very good book. The biggest distraction for me was the long code listings. It would have been better to have either put in line numbers or interspersed the code with the textual explanations. </p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/05/04/a-review-of-learning-php-data-objects/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A review of &#8220;Object-Oriented Programming with PHP5&#8243;</title>
		<link>http://akrabat.com/2008/05/04/a-review-of-object-oriented-programming-with-php5/</link>
		<comments>http://akrabat.com/2008/05/04/a-review-of-object-oriented-programming-with-php5/#comments</comments>
		<pubDate>Sun, 04 May 2008 09:00:20 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=244</guid>
		<description><![CDATA[
Packt Publishing recently sent me a couple of books to review, so let's start with Object-Oriented Programming with PHP5 by Hasin Hayder. According to the introduction, the book is intended for beginners to intermediate PHP5 programmers and the first chapter has a good introduction to what object oriented programming is and why you would want [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://akrabat.com/wp-content/uploads/packt-oop-with-php5.png" alt="packt_oop_with_php5.png" border="0" width="97" height="123" class="left" /><br />
<a href="http://www.packtpub.com/">Packt Publishing</a> recently sent me a couple of books to review, so let's start with <a href="http://www.packtpub.com/oop-php-5/book">Object-Oriented Programming with PHP5</a> by Hasin Hayder. According to the introduction, the book is intended for beginners to intermediate PHP5 programmers and the first chapter has a good introduction to what object oriented programming is and why you would want to use it.</p>
<h3>Overview of the book</h3>
<p>Chapters two and three of the book are an excellent discussion of how objects work in PHP and cover everything from the use of <tt>$this</tt> through to object cloning and fluent interfaces. Chapter 4 gives a basic introduction to design patterns, however I feel that it covers too many patterns in not enough detail. It does provide the terminology required though for communicating with other developers about design patterns which will also help when searching the web for more information. </p>
<p>Chapter 5 then introduces reflection and unit testing. This is an odd couple to put together and the entire chapter feels like the author was padding. There are long pages of code with very little explanation of what the code does and no example of real-world usage of the Reflection classes. The unit testing half provides a good introduction to unit testing and shows how to use it. Rather oddly, there's a 10 page table listing all the PHPUnit assert functions which would have been better left to the PHPUnit documentation as the table provides no added value.</p>
<p>Chapter 6 introduces the <a href="http://php.net/spl">SPL</a>. Like the design patterns chapter, it covers a lot of objects in relatively shallow depth. Good code examples are provided to show how to use the SPL objects, but again, there's not really enough textual explanation of the code or discussion of real-world usage. Similarly, chapter 7 covers object oriented database access with MySQLi, PDO, ADOdb and MDB2. It finishes up with a couple of pages ADOdb's ActiveRecord object. It's all a bit rushed.</p>
<p>XML is introduced in chapter 8 with SimpleXML and DOM are looked at. Again, a very basic introduction is provided. For example XPath is covered in 3 pages and I still have no idea how to actually use it in a project. The final chapter in the book covers the MVC design pattern as implemented in the author's home-grown framework. As with the rest of the book, a lot of code is presented with little explanation of why the code has been written. For example, the view class presented provides __get(), but not __set(). There is no explanation as to why __get() would be required in a view class, but not __set().</p>
<h3>In summary</h3>
<p>This book is a whistle-stop tour through object oriented concepts with PHP5 and I'm left with mixed feelings about it. The best parts are chapters 2 and 3 which provide a solid introduction to objects and classes. The rest of the book covers too many disparate topics in very little depth to be useable on its own for those topics.</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/05/04/a-review-of-object-oriented-programming-with-php5/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Flickr Uploadr</title>
		<link>http://akrabat.com/2008/04/17/flickr-uploadr/</link>
		<comments>http://akrabat.com/2008/04/17/flickr-uploadr/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 18:29:26 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[Xul]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=243</guid>
		<description><![CDATA[The new Flickr Uploadr was written using Xul. Richard Crowley has put up a post at the Flickr blog with links to various articles that he's written about devloping with XUlrunner.
Fascinating stuff and a must read for anyone who writes Xulrunner apps. Even better, the full source to Uploadr is available!
]]></description>
			<content:encoded><![CDATA[<p>The new Flickr Uploadr was written using Xul. Richard Crowley has put up a <a href="http://code.flickr.com/blog/2008/04/16/flickr-uploadr-start-to-finish-now/">post at the Flickr blog</a> with links to various articles that he's written about devloping with XUlrunner.</p>
<p>Fascinating stuff and a must read for anyone who writes Xulrunner apps. Even better, the <a href="http://code.flickr.com/trac/browser/trunk/uploadr/">full source to Uploadr</a> is available!</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/04/17/flickr-uploadr/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simple Zend_Form File Upload Example</title>
		<link>http://akrabat.com/2008/04/07/simple-zend_form-file-upload-example/</link>
		<comments>http://akrabat.com/2008/04/07/simple-zend_form-file-upload-example/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 07:04:19 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<category><![CDATA[example]]></category>

		<category><![CDATA[zendframework]]></category>

		<category><![CDATA[zend_form]]></category>

		<guid isPermaLink="false">http://akrabat.com/?p=242</guid>
		<description><![CDATA[Zend Framework 1.5's Zend_Form component is missing support for the file input element as it is waiting on a file upload component to build upon. We're busy people, so we'll fake it&#8230;
This is a super simple example showing how to do file uploads with Zend_Form in Zend Framework 1.5.
I'm building on the Simple Zend_Form Example, [...]]]></description>
			<content:encoded><![CDATA[<p>Zend Framework 1.5's Zend_Form component is missing support for the <tt>file</tt> input element as it is waiting on a file upload component to build upon. We're busy people, so we'll fake it&#8230;</p>
<p>This is a super simple example showing how to do file uploads with Zend_Form in Zend Framework 1.5.</p>
<p>I'm building on the <a href="/2008/02/21/simple-zend_form-example/">Simple Zend_Form Example</a>, so make sure you have read that and that it works before you start this one.</p>
<p>This is what the form looks like:</p>
<p><img src="http://akrabat.com/wp-content/uploads/simplefileuploadscreenshot.jpg" alt="SimpleFileUploadScreenshot.jpg" border="0" width="580" height="369" /></p>
<p>(Unstyled, as usual!)</p>
<p>This is what we need to do:</p>
<h3>The form</h3>
<p>The form is an extension of <tt>Zend_Form</tt> and is stored <tt>in app/forms/UploadForm.php</tt> and so the class name is <tt>forms_UploadForm</tt>:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php

</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">forms_UploadForm&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Zend_Form&nbsp;
</span><span style="color: #007700">{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">$options&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">addElementPrefixPath</span><span style="color: #007700">(</span><span style="color: #DD0000">'App'</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'App/'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">$options</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setName</span><span style="color: #007700">(</span><span style="color: #DD0000">'upload'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setAttrib</span><span style="color: #007700">(</span><span style="color: #DD0000">'enctype'</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'multipart/form-data'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$description&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Zend_Form_Element_Text</span><span style="color: #007700">(</span><span style="color: #DD0000">'description'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$description</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setLabel</span><span style="color: #007700">(</span><span style="color: #DD0000">'Description'</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;</span><span style="color: #0000BB">setRequired</span><span style="color: #007700">(</span><span style="color: #0000BB">true</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;</span><span style="color: #0000BB">addValidator</span><span style="color: #007700">(</span><span style="color: #DD0000">'NotEmpty'</span><span style="color: #007700">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$file&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">App_Form_Element_File</span><span style="color: #007700">(</span><span style="color: #DD0000">'file'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$file</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setLabel</span><span style="color: #007700">(</span><span style="color: #DD0000">'File'</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;</span><span style="color: #0000BB">setRequired</span><span style="color: #007700">(</span><span style="color: #0000BB">true</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;</span><span style="color: #0000BB">addValidator</span><span style="color: #007700">(</span><span style="color: #DD0000">'NotEmpty'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$submit&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Zend_Form_Element_Submit</span><span style="color: #007700">(</span><span style="color: #DD0000">'submit'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$submit</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setLabel</span><span style="color: #007700">(</span><span style="color: #DD0000">'Upload'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">addElements</span><span style="color: #007700">(array(</span><span style="color: #0000BB">$description</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$file</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$submit</span><span style="color: #007700">));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
}&nbsp;
</span>
</span></code></pre>
<p>We are going to create our own validator class within our own library namespace (lib/App) and so we need to tell the form about this using <tt>addElementPath()</tt>. We then set the name and enctype attribute of the form to allow for files to be uploaded.</p>
<p>The form has two fields: a text field called 'description' and the file upload field called 'file', along with a submit button. As Zend Framework doesn't have it's own file element, we will create our own called <tt>App_Form_Element_File</tt>.</p>
<h3>The file form element</h3>
<p>The file element, <tt>App_Form_Element_File</tt>, is stored in <tt>lib/App/Form/Element/File.php</tt> and looks like this:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php
</span><span style="color: #007700">require_once&nbsp;</span><span style="color: #DD0000">'Zend/Form/Element/Xhtml.php'</span><span style="color: #007700">;

class&nbsp;</span><span style="color: #0000BB">App_Form_Element_File&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Zend_Form_Element_Xhtml
</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Flag&nbsp;indicating&nbsp;whether&nbsp;or&nbsp;not&nbsp;to&nbsp;insert&nbsp;ValidFile&nbsp;validator&nbsp;when&nbsp;element&nbsp;is&nbsp;required
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;bool
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">protected&nbsp;</span><span style="color: #0000BB">$_autoInsertValidFileValidator&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">;

&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Default&nbsp;view&nbsp;helper&nbsp;to&nbsp;use
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;string
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">$helper&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'formFile'</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Set&nbsp;flag&nbsp;indicating&nbsp;whether&nbsp;a&nbsp;ValidFile&nbsp;validator&nbsp;should&nbsp;be&nbsp;inserted&nbsp;when&nbsp;element&nbsp;is&nbsp;required
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;bool&nbsp;$flag&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;Zend_Form_Element
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">setAutoInsertValidFileValidator</span><span style="color: #007700">(</span><span style="color: #0000BB">$flag</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_autoInsertValidFileValidator&nbsp;</span><span style="color: #007700">=&nbsp;(bool)&nbsp;</span><span style="color: #0000BB">$flag</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Get&nbsp;flag&nbsp;indicating&nbsp;whether&nbsp;a&nbsp;ValidFile&nbsp;validator&nbsp;should&nbsp;be&nbsp;inserted&nbsp;when&nbsp;element&nbsp;is&nbsp;required
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;bool
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">autoInsertValidFileValidator</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_autoInsertValidFileValidator</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$context&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;for&nbsp;a&nbsp;file&nbsp;upload,&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;POST&nbsp;array,&nbsp;it's&nbsp;in&nbsp;$_FILES
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getName</span><span style="color: #007700">();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">null&nbsp;</span><span style="color: #007700">===&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isset(</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #0000BB">$key</span><span style="color: #007700">]))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$value&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$_FILES</span><span style="color: #007700">[</span><span style="color: #0000BB">$key</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;auto&nbsp;insert&nbsp;ValidFile&nbsp;validator
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">isRequired</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">autoInsertValidFileValidator</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;!</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getValidator</span><span style="color: #007700">(</span><span style="color: #DD0000">'ValidFile'</span><span style="color: #007700">))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$validators&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getValidators</span><span style="color: #007700">();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$validFile&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">=&nbsp;array(</span><span style="color: #DD0000">'validator'&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">'ValidFile'</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'breakChainOnFailure'&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">array_unshift</span><span style="color: #007700">(</span><span style="color: #0000BB">$validators</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$validFile</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setValidators</span><span style="color: #007700">(</span><span style="color: #0000BB">$validators</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;do&nbsp;not&nbsp;use&nbsp;the&nbsp;automatic&nbsp;NotEmpty&nbsp;Validator&nbsp;as&nbsp;ValidFile&nbsp;replaces&nbsp;it&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setAutoInsertNotEmptyValidator</span><span style="color: #007700">(</span><span style="color: #0000BB">false</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$context</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;}

}
</span>
</span></code></pre>
<p>Zend Framework already provides a view helper for displaying a file element, <tt>formFile</tt>, so we set the <tt>$helper</tt> member variable to 'formFile' so that the correct element is rendered when the form is displayed. We then need to ensure that validation is handled correctly. For all other form elements the value of the field is returned in the POST array. For a file, this is not true as the data is with the <tt>$_FILES</tt> global array. We could handle this in the controller, but by putting it in the element class, we never have to think about it again.  The <tt>isValid()</tt> member function is used to set the value for an element and also run the validator chain to determine if the value is valid or not. </p>
<p>We override <tt>isValid()</tt> for the file element to provide two functionalities:</p>
<p>* Set the value to the contents of correct sub-array of the $_FILES array .<br />
* Automatically turn on a custom validator called ValidFile which will check if the upload succeeded.</p>
<p>The file element also has some helper functions (<tt>setAutoInsertValidFileValidator</tt> and <tt>getAutoInsertValidFileValidator</tt>) to control the auto-insertion of the <tt>ValidFile</tt> validator. Note that if we do automatically insert the <tt>ValidFile</tt> validator, then we turn off <tt>Zend_Form_Element</tt>'s automatic <tt>NotEmpty</tt> validator as it is redundant. </p>
<p>Once we have set the <tt>$value</tt> variable correctly and inserted our validator, we call up to the parent's <tt>isValid()</tt> function which will run the validation chain for us.</p>
<h3>The <tt>ValidFile</tt> validator</h3>
<p>The <tt>ValidFile</tt> validator's full class name is <tt>App_Validate_ValidFile</tt> and so it's filename is lib/App/Validate/ValidFile.php. This class handles validating the 'error' field within the $value array (which as you'll recall came from $_FILES). This is the code:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php

</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">App_Validate_ValidFile&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Zend_Validate_Abstract
</span><span style="color: #007700">{

&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;</span><span style="color: #0000BB">INI_SIZE&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'iniSize'</span><span style="color: #007700">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;1;&nbsp;The&nbsp;uploaded&nbsp;file&nbsp;exceeds&nbsp;the&nbsp;upload_max_filesize&nbsp;directive&nbsp;in&nbsp;php.ini
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">FORM_SIZE&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'formSize'</span><span style="color: #007700">;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;2;&nbsp;The&nbsp;uploaded&nbsp;file&nbsp;exceeds&nbsp;the&nbsp;MAX_FILE_SIZE&nbsp;directive&nbsp;that&nbsp;was&nbsp;specified&nbsp;in&nbsp;the&nbsp;HTML&nbsp;form.&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">PARTIAL&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'partial'</span><span style="color: #007700">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;3;&nbsp;The&nbsp;uploaded&nbsp;file&nbsp;was&nbsp;only&nbsp;partially&nbsp;uploaded.&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">NO_FILE&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'noFile'</span><span style="color: #007700">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;4;&nbsp;No&nbsp;file&nbsp;was&nbsp;uploaded.&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">NO_TMP_DIR&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'noTmpDir'</span><span style="color: #007700">;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;6;&nbsp;Missing&nbsp;a&nbsp;temporary&nbsp;folder.
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">CANT_WRITE&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'cantWrite'</span><span style="color: #007700">;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;7;&nbsp;Failed&nbsp;to&nbsp;write&nbsp;file&nbsp;to&nbsp;disk.
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">EXTENSION&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'extension'</span><span style="color: #007700">;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Value:&nbsp;8;&nbsp;File&nbsp;upload&nbsp;stopped&nbsp;by&nbsp;extension.&nbsp;Introduced&nbsp;in&nbsp;PHP&nbsp;5.2.0.&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">ERROR&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'error'</span><span style="color: #007700">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;General&nbsp;error&nbsp;for&nbsp;future&nbsp;proofing&nbsp;against&nbsp;new&nbsp;PHP&nbsp;versions

&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@var&nbsp;array
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">protected&nbsp;</span><span style="color: #0000BB">$_messageTemplates&nbsp;</span><span style="color: #007700">=&nbsp;array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">INI_SIZE&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"The&nbsp;uploaded&nbsp;file&nbsp;exceeds&nbsp;the&nbsp;upload_max_filesize&nbsp;directive&nbsp;in&nbsp;php.ini"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">FORM_SIZE&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"The&nbsp;uploaded&nbsp;file&nbsp;exceeds&nbsp;the&nbsp;MAX_FILE_SIZE&nbsp;directive&nbsp;that&nbsp;was&nbsp;specified&nbsp;in&nbsp;the&nbsp;HTML&nbsp;form"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">PARTIAL&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"The&nbsp;uploaded&nbsp;file&nbsp;was&nbsp;only&nbsp;partially&nbsp;uploaded"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">NO_FILE&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"No&nbsp;file&nbsp;was&nbsp;uploaded"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">NO_TMP_DIR&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"Missing&nbsp;a&nbsp;temporary&nbsp;folder"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">CANT_WRITE&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"Failed&nbsp;to&nbsp;write&nbsp;file&nbsp;to&nbsp;disk"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">EXTENSION&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"File&nbsp;upload&nbsp;stopped&nbsp;by&nbsp;extension"</span><span style="color: #007700">,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">ERROR&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #DD0000">"Unknown&nbsp;upload&nbsp;error"
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">);

&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Defined&nbsp;by&nbsp;Zend_Validate_Interface
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;true&nbsp;if&nbsp;and&nbsp;only&nbsp;if&nbsp;$value[error]&nbsp;is&nbsp;equal&nbsp;to&nbsp;UPLOAD_ERR_OK.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@note:&nbsp;This&nbsp;validator&nbsp;expects&nbsp;$value&nbsp;to&nbsp;be&nbsp;the&nbsp;array&nbsp;from&nbsp;$_FILES
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;array&nbsp;$value
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;function&nbsp;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;default&nbsp;value&nbsp;and&nbsp;error&nbsp;is&nbsp;"no&nbsp;file&nbsp;uploaded"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$valueString&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"</span><span style="color: #007700">;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$error&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_NO_FILE</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">is_array</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;&amp;&amp;&nbsp;</span><span style="color: #0000BB">array_key_exists</span><span style="color: #007700">(</span><span style="color: #DD0000">'error'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;set&nbsp;the&nbsp;error&nbsp;to&nbsp;the&nbsp;correct&nbsp;value
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$error&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">[</span><span style="color: #DD0000">'error'</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;set&nbsp;the&nbsp;%value%&nbsp;placeholder&nbsp;to&nbsp;the&nbsp;uplaoded&nbsp;filename
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$valueString&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_setValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$valueString</span><span style="color: #007700">);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$result&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">false</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(</span><span style="color: #0000BB">$error</span><span style="color: #007700">)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_OK</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$result&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_INI_SIZE</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">INI_SIZE</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_FORM_SIZE</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">FORM_SIZE</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_PARTIAL</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">PARTIAL</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_NO_FILE</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">NO_FILE</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_NO_TMP_DIR</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">NO_TMP_DIR</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">UPLOAD_ERR_CANT_WRITE</span><span style="color: #007700">:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">CANT_WRITE</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">8</span><span style="color: #007700">:&nbsp;</span><span style="color: #FF8000">//&nbsp;UPLOAD_ERR_EXTENSION&nbsp;isn't&nbsp;defined&nbsp;in&nbsp;PHP&nbsp;5.1.4,&nbsp;so&nbsp;use&nbsp;the&nbsp;value
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">EXTENSION</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_error</span><span style="color: #007700">(</span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">ERROR</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">$result</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;}

}
</span>
</span></code></pre>
<p>Although this class is quite long, not much happens! All the work happens in <tt>isValid()</tt> where we set $error to the 'error' value originally from the $_FILES array and then set our error message based on which error PHP has reported to us. If PHP reported no error (UPLOAD_ERR_OK), then we return true, otherwise we return false after having set the error value.</p>
<h3>The controller</h3>
<p>Lastly, the controller is essentially identical to what we did in the <a href="/2008/02/21/simple-zend_form-example/">Simple Zend_Form Example</a>:</p>
<pre class="phpcode">
<span style="color: #0000BB">&lt;?php

</span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">IndexController&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">Zend_Controller_Action
</span><span style="color: #007700">{
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">indexAction</span><span style="color: #007700">()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">pageTitle&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"Zend_Form&nbsp;File&nbsp;Upload&nbsp;Example"</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bodyCopy&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"&lt;p&gt;Please&nbsp;fill&nbsp;out&nbsp;this&nbsp;form.&lt;/p&gt;"</span><span style="color: #007700">;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$form&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">forms_UploadForm</span><span style="color: #007700">();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_request</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">isPost</span><span style="color: #007700">())&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$formData&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_request</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getPost</span><span style="color: #007700">();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">$form</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">isValid</span><span style="color: #007700">(</span><span style="color: #0000BB">$formData</span><span style="color: #007700">))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;success&nbsp;-&nbsp;do&nbsp;something&nbsp;with&nbsp;the&nbsp;uploaded&nbsp;file
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$uploadedData&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$form</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getValues</span><span style="color: #007700">();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Zend_Debug</span><span style="color: #007700">::</span><span style="color: #0000BB">dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$uploadedData</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'$uploadedData'</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$form</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">populate</span><span style="color: #007700">(</span><span style="color: #0000BB">$formData</span><span style="color: #007700">);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">view</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">form&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$form</span><span style="color: #007700">;
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</span>
</span></code></pre>
<p>If it all validates correctly, then you need to process the uploaded data. For this example we just display it using <tt>Zend_Debug::dump()</tt>, so you can see what it looks like:</p>
<p><img src="http://akrabat.com/wp-content/uploads/simplefileuploadscreenshot21.jpg" alt="SimpleFileUploadScreenshot2.jpg" border="0" width="594" height="411" /></p>
<h3>Conclusion</h3>
<p>As you can see, although Zend Framework 1.5 doesn't have file upload element built in, adding one is not especially hard. In fact, we have more code used to validate that and provide an error message on failure than we do for the upload itself!</p>
<p>As usual, here's a zip file of this project: <a href="http://akrabat.com/wp-content/uploads/Zend_Form_FileUpload_Example.zip">Zend_Form_FileUpload_Example.zip</a> (It includes Zend Framework 1.5.1 which is why it's 3.9MB big).</p>
<p>Test it out and maybe use it as the basis of your file uploading needs with Zend_Form.</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/04/07/simple-zend_form-file-upload-example/feed/</wfw:commentRss>
		</item>
		<item>
		<title>On Mail.app</title>
		<link>http://akrabat.com/2008/03/22/on-mailapp/</link>
		<comments>http://akrabat.com/2008/03/22/on-mailapp/#comments</comments>
		<pubDate>Sat, 22 Mar 2008 19:58:22 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[Computing]]></category>

		<guid isPermaLink="false">http://akrabat.com/2008/03/22/on-mailapp/</guid>
		<description><![CDATA[As I mentioned a while ago, I'm now using a MacBook Pro. All is going well, and I like Mail.app's search and data detectors very much. There are some niggles though that I miss from Thunderbird. My top 3 are:
* GPG integration (Thunderbird's Enigmail)
* Mail.app's insistence on attached PDFs and images inline
* Filing mails to [...]]]></description>
			<content:encoded><![CDATA[<p>As I <a href="http://akrabat.com/2007/11/09/the-move-to-mac/">mentioned</a> a while ago, I'm now using a MacBook Pro. All is going well, and I like Mail.app's search and data detectors very much. There are some niggles though that I miss from Thunderbird. My top 3 are:</p>
<p>* GPG integration (Thunderbird's <a href="https://addons.mozilla.org/en-US/thunderbird/addon/71">Enigmail</a>)<br />
* Mail.app's insistence on attached PDFs and images inline<br />
* Filing mails to arbitrary folders using the keyboard (Thunderbird's <a href="https://addons.mozilla.org/en-US/thunderbird/addon/2487">nostalgy</a>)</p>
<p>It turns out that there are solutions to all three issues for OS X's Mail.app:</p>
<p>* <a href="http://www.sente.ch/software/GPGMail/">GPGMail</a> from Sente. (Not for Leopard, yet though)<br />
* <a href="http://lokiware.info/Mail-Attachments-Iconizer">Mail Attachments Iconizer</a> from Lokiware<br />
* <a href="http://www.tow.com/msgfiler/">MsgFiler</a> from tow.</p>
<p>I had found GPGMail a while ago and I"m looking forward to the Leopard release. In the meantime, I am getting by using the Services->GPG menu. I only learnt about the other two by accident.</p>
<p>Lokiware is sponsoring the <a href="http://daringfireball.net/">Daring Firebal</a>l RSS feed this week and John Gruber's write up about this event, pointed at <a href="http://www.macworld.com/article/132112/2008/02/msgfilermai.html">Dan Frakes’s Macworld article</a> which not only persuaded me to download Mail Attachments Iconizer also mentioned MsgFiler too.</p>
<p>I've bought both! Clearly sponsoring DF's RSS feed is worthwhile :)</p>
<p>Now, I'm trying to decide if I should buy Yojimbo&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/03/22/on-mailapp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Updated Tutorial for Zend Framework 1.5</title>
		<link>http://akrabat.com/2008/03/17/updated-tutorial-for-zend-framework-15/</link>
		<comments>http://akrabat.com/2008/03/17/updated-tutorial-for-zend-framework-15/#comments</comments>
		<pubDate>Mon, 17 Mar 2008 13:50:25 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<category><![CDATA[zendframework]]></category>

		<guid isPermaLink="false">http://akrabat.com/2008/03/17/updated-tutorial-for-zend-framework-15/</guid>
		<description><![CDATA[Zend Framework 1.5 has now been released to mark the occasion I have significantly updated my Zend Framework Tutorial! The tutorial was first released on 16th August 2006 and was written against version 0.1 of Zend Framework and had one major revision to bring in support for the ViewRenderer component. 

The new tutorial produces exactly [...]]]></description>
			<content:encoded><![CDATA[<p>Zend Framework 1.5 has now been released to mark the occasion I have significantly updated my <a href="/zend-framework-tutorial">Zend Framework Tutorial</a>! The tutorial was first released on <a href="http://akrabat.com/2006/08/16/my-take-on-a-zend-framework-tutorial/">16th August 2006</a> and was written against version 0.1 of Zend Framework and had one major revision to bring in support for the ViewRenderer component. </p>
<p><img src="http://akrabat.com/wp-content/uploads/tutorial-screenshot.jpg" alt="Tutorial-Screenshot" /></p>
<p>The new tutorial produces exactly the same application as before, but now uses the new 1.5 goodies of Zend_Form and Zend_Layout, so you can see how these key components fit into a Zend Framework MVC application.</p>
<p>As always, when you find bugs and typos, please let me know and I'll fix them!</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/03/17/updated-tutorial-for-zend-framework-15/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PHPWM March Meeting: Symfony</title>
		<link>http://akrabat.com/2008/03/13/phpwm-march-meeting-symfony/</link>
		<comments>http://akrabat.com/2008/03/13/phpwm-march-meeting-symfony/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 20:07:56 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[phpwm]]></category>

		<guid isPermaLink="false">http://akrabat.com/2008/03/13/phpwm-march-meeting-symfony/</guid>
		<description><![CDATA[On Tuesday, PHPWM had a meeting at PSL Connect's offices where Darren Beale talked about Symfony.

I took a few pictures and have stuck them up on Flickr. I should have taken my other lens though as the 50mm isn't wide enough for taking pictures in room!
It was a very good talk that covered the basics [...]]]></description>
			<content:encoded><![CDATA[<p>On Tuesday, <a href="http://www.phpwm.org/">PHPWM</a> had a meeting at <a href="http://www.pslconnect.com/">PSL Connect</a>'s offices where <a href="http://bealers.com/">Darren Beale</a> talked about Symfony.</p>
<p><a href="http://www.flickr.com/photos/86569608@N00/2330990881" title="View 'Darren, about to start presenting' on Flickr.com"><img src="http://farm3.static.flickr.com/2012/2330990881_996ee820c2_m.jpg" alt="Darren, about to start presenting" border="0" width="161" height="240" /></a></p>
<p>I took a few pictures and have stuck them up on <a href="http://www.flickr.com/photos/akrabat/tags/phpwm0803/">Flickr</a>. I should have taken my other lens though as the 50mm isn't wide enough for taking pictures in room!</p>
<p>It was a very good talk that covered the basics of Symfony and what it can do. At the start, Darren asked us which frameworks we use and pretty much everyone used a different one! He then went though how Symfony worked and we got to see some code in action too. It was a nice step up from <a href="http://pookey.co.uk/blog/">Ian</a>'s talk at the PHP UK Conference.</p>
<p>Afterwards we had a drink down the pub which was good :)</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/03/13/phpwm-march-meeting-symfony/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Site Stats</title>
		<link>http://akrabat.com/2008/03/09/site-stats/</link>
		<comments>http://akrabat.com/2008/03/09/site-stats/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 08:39:03 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://akrabat.com/2008/03/09/site-stats/</guid>
		<description><![CDATA[One thing I get asked a lot about at work is site stats. Usually, the client wants to know how many visitors they get on any other day along with other data such as where the visitors came from and which search terms they may have used.
So far, I've used Google Analytics and PHPMyVisites JS [...]]]></description>
			<content:encoded><![CDATA[<p>One thing I get asked a lot about at work is site stats. Usually, the client wants to know how many visitors they get on any other day along with other data such as where the visitors came from and which search terms they may have used.</p>
<p>So far, I've used <a href="https://www.google.com/analytics">Google Analytics</a> and <a href="">PHPMyVisites</a> JS based logging along with <a href="http://www.analog.cx/">Analog</a> on the logs themselves. I've also experimented with <a href="http://haveamint.com/">Mint</a> on one site. </p>
<p>Generally, I've found that Analytics requires lots of drilling down to find anything, PHPMyVisites can be a little simplistic (though it is getting more features with each release) and Mint doesn't provide enough history.</p>
<p>Are there better solutions out that that are cost-effective for relatively small clients?</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/03/09/site-stats/feed/</wfw:commentRss>
		</item>
		<item>
		<title>IE8 will work like IE8 by default!</title>
		<link>http://akrabat.com/2008/03/04/ie8-will-work-like-ie8-by-default/</link>
		<comments>http://akrabat.com/2008/03/04/ie8-will-work-like-ie8-by-default/#comments</comments>
		<pubDate>Tue, 04 Mar 2008 12:24:00 +0000</pubDate>
		<dc:creator>Rob...</dc:creator>
		
		<category><![CDATA[Around the web]]></category>

		<guid isPermaLink="false">http://akrabat.com/2008/03/04/ie8-will-work-like-ie8-by-default/</guid>
		<description><![CDATA[We’ve decided that IE8 will, by default, interpret web content in the most standards compliant way it can. This decision is a change from what we’ve posted previously.
From Microsoft's Interoperability Principles and IE8.
This is good news all round. It's nice to see that Microsoft have listened to the comments surrounding their original intention to make [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>We’ve decided that IE8 will, by default, interpret web content in the most standards compliant way it can. This decision is a change from what we’ve posted previously.</p></blockquote>
<p>From <a href="http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx">Microsoft's Interoperability Principles and IE8</a>.</p>
<p>This is good news all round. It's nice to see that Microsoft have listened to the comments surrounding their original intention to make IE8 render like IE7 by default. Well done!</p>
]]></content:encoded>
			<wfw:commentRss>http://akrabat.com/2008/03/04/ie8-will-work-like-ie8-by-default/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
