<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tudor Barbu&#039;s professional blog &#187; php</title>
	<atom:link href="http://blog.motane.lu/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.motane.lu</link>
	<description>Ramblings about software development</description>
	<lastBuildDate>Thu, 02 Feb 2012 17:38:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Multiple inheritance in PHP</title>
		<link>http://blog.motane.lu/2012/01/21/multiple-inheritance-in-php/</link>
		<comments>http://blog.motane.lu/2012/01/21/multiple-inheritance-in-php/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 12:32:06 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[extreme php]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1878</guid>
		<description><![CDATA[I wrote yesterday an article introducing Cosmin&#8217;s blog. His most recent article is on multiple inheritance and how easy it would be to implement that into weakly typed like PHP. Just have a look at the article. Having learned OOP in Java, I am generally against multiple inheritance. I believe that if the answer is [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote yesterday an article introducing Cosmin&#8217;s blog. His <a href="http://cosmi.nu/multiple-inheritance-suddenly-more-easy-in-php-than-in-c/45" title="Multiple inheritance suddleny more easy in PHP than in C" class="outgoing">most recent article</a> is on multiple inheritance and how easy it would be to implement that into weakly typed like PHP. Just have a look at the article.</p>
<p>Having learned OOP in Java, I am generally against multiple inheritance. I believe that if the answer is multiple inheritance, you&#8217;re asking the wrong question. But, for &#8220;academic&#8221; reasons, I tried to implement multiple inheritance in PHP. And I came up with the following abomination.</p>
<p>First, create a parent class from which all classes in need of multiple inheritance extend. The parent classes will be placed in the $_parents array as strings. When the main object is instantiated, the constructor creates objects from all the parent classes. And by using __call() I&#8217;m just going to redirect method calls on the main object to the first suitable parent object. I know it sounds complicated, so long story short, just read the code! I&#8217;m a developer, not a writer!</p>
<pre class="brush: php; title: ; notranslate">
/**
 * Abomination class implementing multiple inheritance via
 * __call magic method
 */
abstract class MultipleInheritance
{
    /**
     * List of parent classes
     *
     * @var array
     * @access protected
     */
    protected $_parents = array();    

    /**
     * List of parent objects - generated automatically
     *
     * @var array
     * @access private
     */
    private $_parentObjects = array();

    /**
     * Constructor (thank you captain Obvious)
     *
     * - init the parent objects
     *
     * @access public
     */
    public function __construct()
    {
        foreach ($this-&gt;_parents as $parentClass) {
            $this-&gt;_parentObjects []= new $parentClass();
        }
    }

    /**
     * __call magic method
     *
     * @param string $name
     * @param array $arguments
     * @access public
     * @return mixed
     */
    public function __call($name, array $arguments)
    {
        foreach ($this-&gt;_parentObjects as $object) {
            if (method_exists($object, $name)) {
                return call_user_func_array(array($object, $name), $arguments);
            }
        }

        throw new Exception('No such method: ' . $name);
    }
}
</pre>
<p>Now, some very sexist implementations of Mom and Dad classes:</p>
<pre class="brush: php; title: ; notranslate">
class Dad
{
    /**
     * Can parallel park
     *
     * @access public
     * @return void
     */
    public function park()
    {
        echo 'Look, I can parallel park' . PHP_EOL;
    }    

    /**
     * Can ground the kids
     *
     * @access public
     * @return void
     */
    public function ground()
    {
        echo 'Grounded by DAD' . PHP_EOL;
    }
}

class Mom
{
    protected $_parents = array('GrandMa');

    /**
     * Makes sandwiches
     *
     * @access public
     * @return void
     */
    public function makeSandwich()
    {
        echo 'Just making a sandwich' . PHP_EOL;
    }    

    /**
     * Can grounds the kids
     *
     * @access public
     * @return void
     */
    public function ground()
    {
        echo 'Grounded by MOM' . PHP_EOL;
    }
}
</pre>
<p>&#8230;and finally the child class:</p>
<pre class="brush: php; title: ; notranslate">
class Child extends MultipleInheritance
{
    protected $_parents = array('Dad', 'Mom');
}
</pre>
<p>Let&#8217;s try it out:</p>
<pre class="brush: php; title: ; notranslate">
$child = new Child();
$child-&gt;park();
$child-&gt;makeSandwich();
$child-&gt;ground();
</pre>
<p>And it works. And when two parent classes have the same method &#8211; ground() in this case &#8211; the method belonging to the first encountered class is executed. And voila, multiple inheritance in PHP. Well, sort of.</p>
<p>Now there&#8217;s a small problem with the <strong>instanceof</strong> operator. And by small problem I mean it doesn&#8217;t work and there&#8217;s no way to fix it. The following code</p>
<pre class="brush: php; title: ; notranslate">
if ($child instanceof Mom) {
    echo get_class($child) . ' class inherits from Mom' . PHP_EOL;
} else {
    echo get_class($child) . ' class does not inherit from Mom' . PHP_EOL;
}
</pre>
<p>will always go on the &#8220;else&#8221; branch, although in my application&#8217;s logic, the Child class extends from the Mom class. And since PHP doesn&#8217;t allow overloading the operators, there&#8217;s no clean way to do this. Of course, there&#8217;s a hacky way around it, by adding an isInstanceOf() method to the MultipleInheritance class:</p>
<pre class="brush: php; title: ; notranslate">
abstract class MultipleInheritance
{
    // ...

    /**
     * Check inheritance
     *
     * @param string $class
     * @access public
     * @return bool
     */
    public function isInstanceOf($class)
    {
        if (in_array($this-&gt;_parents, $class)) {
            return true;
        }

        foreach ($this-&gt;_parentObjects as $parent) {
            if ($parent instanceof MultipleInheritance) {
                if ($parent-&gt;isInstanceOf($class)) {
                    return true;
                }
            }
        }

        return false;
    }
}
</pre>
<p>&#8230;and using it to check inheritance:</p>
<pre class="brush: php; title: ; notranslate">
if ($child-&gt;isInstanceOf('Mom')) {
    echo get_class($child) . ' class inherits from Mom' . PHP_EOL;
} else {
    echo get_class($child) . ' class does not inherit from Mom' . PHP_EOL;
}
</pre>
<p>But the abomination is not completed yet. Because I used <a href="http://php.net/manual/en/function.method-exists.php" title="method_exists() in the PHP manual" class="outgoing">method_exists()</a> instead of <a href="http://php.net/manual/en/function.is-callable.php" title="is_callable() in the PHP manual" class="outgoing">is_callable()</a>, magic methods in the parent class will not be detected. To fix this, just change the code from:</p>
<pre class="brush: php; title: ; notranslate">
if (method_exists($object, $name)) {
    return call_user_func_array(array($object, $name), $arguments);
}
</pre>
<p>&#8230;to&#8230;</p>
<pre class="brush: php; title: ; notranslate">
if (is_callable($object, $name)) {
    return call_user_func_array(array($object, $name), $arguments);
}
</pre>
<p>&#8230;and it will work. At last, the abomination is ready. Doctor Frankenstein would be proud! Here is a gist with the entire example: <a href="https://gist.github.com/1652646" title="Go to https://gist.github.com/1652646" class="outgoing">https://gist.github.com/1652646</a>.</p>
<p>PS: DO NOT USE MULTIPLE INHERITANCE IN REAL LIFE APPLICATIONS!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2012/01/21/multiple-inheritance-in-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>New kid on the block</title>
		<link>http://blog.motane.lu/2012/01/20/new-kid-on-the-block/</link>
		<comments>http://blog.motane.lu/2012/01/20/new-kid-on-the-block/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 18:24:25 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[other]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1873</guid>
		<description><![CDATA[Meet Cosmin. He&#8217;s my dev partner at StoreBeez. He&#8217;s a software developer who recently turned to the light side of the Force by making the switch from .NET and other M$ technologies to PHP and open source. While he still uses Windows &#8211; which bears testimony of his former allegiance with the evil empire &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Meet <a href="http://cosmi.nu/" title="Cosmin's blog" class="outgoing">Cosmin</a>. He&#8217;s my dev partner at <a href="http://www.storebeez.com" title="Virtual mall selling jewellery, handmade, vintage and fashion items" class="outgoing">StoreBeez</a>. He&#8217;s a software developer who recently turned to the light side of the Force by making the switch from .NET and other M$ technologies to PHP and open source. </p>
<p>While he still uses Windows &#8211; which bears testimony of his former allegiance with the evil empire &#8211; he&#8217;s moving up the ladder and started a blog on PHP and other FLOSS technologies. <a href="http://cosmi.nu/" title="Cosmin's blog" class="outgoing">Check him out</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2012/01/20/new-kid-on-the-block/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Paginating randomly ordered SQL results with Zend_Paginate</title>
		<link>http://blog.motane.lu/2012/01/10/paginating-randomly-ordered-sql-results-with-zend_paginate/</link>
		<comments>http://blog.motane.lu/2012/01/10/paginating-randomly-ordered-sql-results-with-zend_paginate/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 19:32:28 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mysq]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1837</guid>
		<description><![CDATA[As some of you might already know, I&#8217;m working on my latest project, StoreBeez, which is a virtual mall where independent businesses and artisans can open an online store fast and easy, without having to pay any upfront costs. The products are also displayed on our frontpage. And since I don&#8217;t want to promote a [...]]]></description>
			<content:encoded><![CDATA[<p>As some of you might already know, I&#8217;m working on my latest project, <a href="http://www.storebeez.com" title="E-commerce platform helping independent businesses and artisans go online by providing them with a free online store and free marketing" class="outgoing">StoreBeez</a>, which is a virtual mall where independent businesses and artisans can open an online store fast and easy, without having to pay any upfront costs. </p>
<p>The products are also displayed on our frontpage. And since I don&#8217;t want to promote a given store &#8211; all out stores are equal &#8211; displaying the products in random order seemed like a good idea. Retrieving random results is simple, just use MySQL&#8217;s <a href="http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand" title="MySQL's manual entry for rand()" class="outgoing">rand()</a> function and make the queries look like:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT * FROM `table` ORDER BY RAND();
</pre>
<p>Which works. Every time the user reloads the page, different results are shown. The problem arises when I&#8217;m trying to paginate. Every request means a new random order and sometimes rows get displayed multiple times &#8211; on different pages &#8211; or simply get &#8220;lost&#8221;.</p>
<p>The solution is to keep the same order between two consecutive requests. To do this, just pass a seed to the random number generator:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT * FROM `table` ORDER BY RAND({seed});
</pre>
<p>&#8230;where {seed} is a number kept in session. This way, the order is kept between requests. Given that I use Zend Framework as my &#8220;weapon of choice&#8221;, I will post a ZF solution below:</p>
<p>In the controller:</p>
<pre class="brush: php; title: ; notranslate">
$page = intval($this-&gt;_getParam('page'));
$page = $page ?: 1;

if ($page == 1) {
    $namespace = new Zend_Session_Namespace('random_key');
    $namespace-&gt;key = time();
}

$productsTable = new My_Table_Products();
$products = $productsTable-&gt;fetchPaginator();
$products-&gt;setItemCountPerPage(10)
         -&gt;setCurrentPageNumber($page);
</pre>
<p>And in the table:</p>
<pre class="brush: php; title: ; notranslate">
class My_Table_Products
{
    // ...

    public function fetchPaginator()
    {
        $namespace = new Zend_Session_Namespace('random_key');
        $select = $this-&gt;select()
                       -&gt;order('RAND(' . $namespace-&gt;random_key . ')');

        $paginator = Zend_Paginator::factory($select);

        return $paginator;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2012/01/10/paginating-randomly-ordered-sql-results-with-zend_paginate/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Zend Framework 2.0</title>
		<link>http://blog.motane.lu/2011/11/10/zend-framework-2-0/</link>
		<comments>http://blog.motane.lu/2011/11/10/zend-framework-2-0/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 15:46:40 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1623</guid>
		<description><![CDATA[Looks promising]]></description>
			<content:encoded><![CDATA[<p>Looks promising</p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/T0LMaODppcc" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2011/11/10/zend-framework-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uploadify on Zend Framework and the 302 error</title>
		<link>http://blog.motane.lu/2011/10/20/uploadify-on-zend-framework-and-the-302-error/</link>
		<comments>http://blog.motane.lu/2011/10/20/uploadify-on-zend-framework-and-the-302-error/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 23:46:30 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1602</guid>
		<description><![CDATA[Uploadify is an awesome script and it works like a charm. But &#8211; there&#8217;s always a but &#8211; sometimes it throws a mysterious 302 error. This happened to me all day long and it drove me crazy. Well, not really, I was already crazy So, what to do when the HTTP 302 error pops? A [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.uploadify.com/" title="Uploadify" class="outgoing">Uploadify</a> is an awesome script and it works like a charm. But &#8211; there&#8217;s always a but &#8211; sometimes it throws a mysterious 302 error. This happened to me all day long and it drove me crazy. Well, not really, I was already crazy <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So, what to do when the HTTP 302 error pops? A quick look over HTTP statuses should point the me in the right direction:</p>
<blockquote><p>
The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.</p>
<p>The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).</p>
<p>If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
</p></blockquote>
<p>from <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3" title="RFC 2626" class="outgoing">here</a>. In simple English, that means a redirect. So what happens!? For security reasons, I turned on the <a href="http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly" title="PHP Settings - Cookie HttpOnly" class="outgoing">cookie-httponly</a> setting and the client-side script was unable to access the cookies and pass the session id back to the server-side script, which in term would see this connection as coming from an non-authenticated user and issue a redirect to the login page. Thus the mysterious 302 status.</p>
<p>The problem can be solved really easy, by turning the cookie-httponly setting off for the entire application. If that&#8217;s not desirable, there&#8217;s a more complicated solution. First, Uploadify must send the session id to the server together with the file:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#fileUpload').uploadify({
    'uploader'   : '/uploadify/uploadify.swf',
    'script'     : '/images/upload/',
    'cancelImg'  : '/uploadify/cancel.png',
    'auto'       : true,
    'fileExt'    : '*.jpg;*.gif;*.png',
    'fileDesc'   : 'Image Files',
    'sizeLimit'  : 2097152,
    'scriptData' : {'sid' : '&lt;?=Zend_Session::getId();?&gt;'},
    onComplete   : function(event, id, fileObj, response, data) {
        // bla bla bla
    }
}
</pre>
<p>&#8230;then, turn off the auto-start in the application.ini file:</p>
<pre class="brush: plain; title: ; notranslate">
phpSettings.session.strict	= &quot;On&quot;
</pre>
<p>&#8230;and in the Bootstrap.php file:</p>
<pre class="brush: php; title: ; notranslate">
protected function _initSession()
{
	if (isset($_POST['sid'])) {
		Zend_Session::setId($_POST['sid']);
	}

	Zend_Session::start();
}
</pre>
<p>Of course, there are some security issues with both approaches, but nothing serious. Took me about 2 hours to figure it out <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2011/10/20/uploadify-on-zend-framework-and-the-302-error/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ZF module for IndexTank</title>
		<link>http://blog.motane.lu/2011/04/18/zf-module-for-indextank/</link>
		<comments>http://blog.motane.lu/2011/04/18/zf-module-for-indextank/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 08:11:44 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[index tank]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1550</guid>
		<description><![CDATA[I like the way open source works. For example, my former colleague and manager started his own company that produces customer support and ticketing software called Helpdesk and one of the challenges he had to solve was building a reliable search system that will allow his users to search through thousands of tickets. And since [...]]]></description>
			<content:encoded><![CDATA[<p>I like the way open source works. For example, my former colleague and manager started his own company that <a href="http://www.helpdeskhq.com" class="outgoing" title="Helpdesk - Free Customer Support and Ticketing System">produces customer support and ticketing software called Helpdesk</a> and one of the challenges he had to solve was building a reliable search system that will allow his users to search through thousands of tickets. </p>
<p>And since we all know that providing a reliable search system is not an easy job, a decision was made to outsource the searching features to <a href="http://www.indextank.com/" title="Index tank" class="outgoing">IndexTank</a>, a company that provides scaled real-time search. Here&#8217;s where the open source part comes in: since there wasn&#8217;t any suitable Zend Framework component for integration with IndexTank, Alex decided to write his own and open-source it on <a href="https://github.com/helpdesk/indextank-php-zend-framework" title="' class="outgoing">Github</a>. It&#8217;s really cool and well documented. Deutschland uber alles <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>Also check out the post on <a href="http://blog.indextank.com/602/zend-framework-client-for-indextank-courtesy-of-helpdesk/" title="" class="outgoing">IndexTank&#8217;s blog</a> and <a href="http://www.helpdeskhq.com" title="Helpdesk - Free Customer Support and Ticketing System">Helpdesk</a>&#8216;s website.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2011/04/18/zf-module-for-indextank/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Forward POST data</title>
		<link>http://blog.motane.lu/2011/01/25/forward-post-data/</link>
		<comments>http://blog.motane.lu/2011/01/25/forward-post-data/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 16:49:31 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1509</guid>
		<description><![CDATA[I was looking today for a way to gracefully forward a POST request from one page to another in PHP. By &#8220;forwarding the request&#8221; I mean redirecting the user to another page on a different domain with all the POST data intact. I want to stress on the definition, because most people understand &#8220;use cURL [...]]]></description>
			<content:encoded><![CDATA[<p>I was looking today for a way to gracefully forward a POST request from one page to another in PHP. By &#8220;forwarding the request&#8221; I mean redirecting the user to another page <em>on a different domain</em> with all the POST data intact. I want to stress on the definition, because most people understand &#8220;use cURL to create a POST request from PHP&#8221;. Being on a different domain, it kind of rules out cookies and sessions.</p>
<p>The proper way to do it is by issuing a <em><strong>HTTP 307 &#8211; Temporary redirect</strong></em> header &#8211; which will instruct the browser to resend the data to the new URI, indicated by the <em><strong>Location</strong></em> field of the response.</p>
<pre class="brush: php; title: ; notranslate">
header('HTTP/1.1 307 Temporary Redirect');
header('Location: new-location.php');
</pre>
<p>Just for the record, in pre-HTTP 1.1 browsers the POST data gets converted to GET, but if your users don&#8217;t use computers from the 90s, this won&#8217;t be a problem. And it works like a charm. In Chrome and Internet Explorer.  </p>
<p>In Firefox and Opera, the browser will pop-up a dialog, informing the user that the data is being redirected to another page and asking the user&#8217;s permission to continue. Which is an extremely stupid standard behavior. Yes, it&#8217;s in the standard! </p>
<blockquote><p>
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
</p></blockquote>
<p>&#8230;straight from the HTTP&#8217;s status codes bible, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" title="RCF 2616" class="outgoing">RFC 2616</a>. Why do I say it&#8217;s a stupid specification? Because it is! It makes no sense to pop-up a dialog that might confuse the user when the data was already sent. For example, if I&#8217;m a malevolent webmaster, I already have the user&#8217;s data, so at this point displaying the dialog box is useless. I can save the data in my database and have a cronjob connect to the new page or do whatever I please with the POSTed information. However, if the redirect is legitimate, displaying the message box might confuse the user and have him cancel the request, which might break the application&#8217;s logic.</p>
<p>Great work guys, I&#8217;m moments away from converting the POST data into GET and send it in the URL&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2011/01/25/forward-post-data/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Single error message for Zend_Validate_EmailAddress</title>
		<link>http://blog.motane.lu/2011/01/07/single-error-message-for-zend_validate_emailaddress/</link>
		<comments>http://blog.motane.lu/2011/01/07/single-error-message-for-zend_validate_emailaddress/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 16:51:25 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1488</guid>
		<description><![CDATA[One of the strong assets of Zend Framework is its rich built in package of validators. It has validators for just about anything, from simple email addresses and digits to credit card numbers and database rows. Yet, sometimes things go wrong and they need to be hacked back on track. Today&#8217;s problem was with the [...]]]></description>
			<content:encoded><![CDATA[<p>One of the strong assets of Zend Framework is its rich built in package of validators. It has validators for just about anything, from simple email addresses and digits to credit card numbers and database rows. Yet, sometimes things go wrong and they need to be hacked back on track. Today&#8217;s problem was with the email address validator that sometimes generates some very user-unfriendly error messages. Like such:</p>
<blockquote><p>
&#8216;bad.email&#8217; is no valid hostname for email address &#8216;testing@bad.email&#8217;<br />
&#8216;bad.email&#8217; does not match the expected structure for a DNS hostname<br />
&#8216;bad.email&#8217; appears to be a local network name but local network names are not allowed
</p></blockquote>
<p>For the average user, these messages can be very confusing and sometimes is much better to just show an easy to understand &#8220;<em>Please enter a correct email</em>&#8221; message. How hard can that be with Zend Framework!?! Well&#8230;let&#8217;s say it&#8217;s not as simple as it looks.</p>
<p>The obvious thing to do is to add custom error messages (basically adding the same message over and over again). Like such: </p>
<pre class="brush: php; title: ; notranslate">
$email-&gt;setOptions(
    array(
        'label'      =&gt; 'Email',
        'required'   =&gt; true,
        'filters'    =&gt; array(
            'StringTrim',
            'StripTags',
        ),
        'validators' =&gt; array(
            array(
                'EmailAddress',
                true,
                array(
                    'allow' =&gt; Zend_Validate_Hostname::ALLOW_DNS,
                    'domain' =&gt; true,
                    'mx' =&gt; true,
                    'deep' =&gt; true,
                    'messages' =&gt; array(
                        Zend_Validate_EmailAddress::INVALID =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_FORMAT =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_HOSTNAME =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_MX_RECORD =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_SEGMENT =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::DOT_ATOM =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::QUOTED_STRING =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_LOCAL_PART =&gt; 'Please enter a correct email'
                    ),
                ),
            ),
        ),
    )
);
</pre>
<p>But it won&#8217;t work. That&#8217;s because <em>Zend_Validate_EmailAddress</em> calls <em>Zend_Validate_Hostname</em> internally, so custom error messages should be added also for the <em>Zend_Validate_Hostname</em> validator.</p>
<pre class="brush: php; title: ; notranslate">
$email-&gt;setOptions(
    array(
        'label'      =&gt; 'Email',
        'required'   =&gt; true,
        'filters'    =&gt; array(
            'StringTrim',
            'StripTags',
        ),
        'validators' =&gt; array(
            array(
                'EmailAddress',
                true,
                array(
                    'allow' =&gt; Zend_Validate_Hostname::ALLOW_DNS,
                    'domain' =&gt; true,
                    'mx' =&gt; true,
                    'deep' =&gt; true,
                    'messages' =&gt; array(
                        Zend_Validate_EmailAddress::INVALID =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_FORMAT =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_HOSTNAME =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_MX_RECORD =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_SEGMENT =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::DOT_ATOM =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::QUOTED_STRING =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::INVALID_LOCAL_PART =&gt; 'Please enter a correct email',
                        Zend_Validate_EmailAddress::LENGTH_EXCEEDED =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::CANNOT_DECODE_PUNYCODE =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::INVALID =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::INVALID_DASH =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::INVALID_HOSTNAME =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::INVALID_HOSTNAME_SCHEMA =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::INVALID_LOCAL_NAME =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::INVALID_URI =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::IP_ADDRESS_NOT_ALLOWED =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::LOCAL_NAME_NOT_ALLOWED =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::UNDECIPHERABLE_TLD =&gt; 'Please enter a correct email',
                        Zend_Validate_Hostname::UNKNOWN_TLD =&gt; 'Please enter a correct email',
                    ),
                ),
            ),
        ),
    )
);
</pre>
<p>Pretty long. Yet still not working. But it is somewhat better &#8211; as no creepy error messages are being displayed &#8211; instead the same message appears multiple times. This is not a validator chain, so the programmer can&#8217;t force the breaking of the chain after the first failed test <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>In the end, after few hours of digging through the code and the docs, I came up with my own solution, which still harnesses the power of the original <a href="http://framework.zend.com/apidoc/core/Zend_Validate/Zend_Validate_EmailAddress.html" class="outgoing" title="Zend_Validate_EmailAddress in ZF API" >Zend_Validate_EmailAddress</a> validator while providing a way to add a simple &#8220;<em>Please enter a correct email</em>&#8221; message. One time <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . It uses the <a href="http://framework.zend.com/apidoc/core/Zend_Validate/Zend_Validate_Callback.html" class="outgoing" title="Zend_Validate_Callback in ZF API">Zend_Validate_Callback</a> class and PHP 5.3 anonymus functions:</p>
<pre class="brush: php; title: ; notranslate">
$email-&gt;setOptions(
    array(
        'label' =&gt; 'Email',
        'required' =&gt; TRUE,
        'filters' =&gt; array(
            'StringTrim',
            'StripTags',
        ),
        'validators' =&gt; array(
            array(
                'Callback',
                true,
                array(
                    'callback' =&gt; function($value) {
                        $validator = new Zend_Validate_EmailAddress(
                            array(
                                'allow' =&gt; Zend_Validate_Hostname::ALLOW_DNS,
                                'domain' =&gt; true,
                                'mx' =&gt; true,
                                'deep' =&gt; true,
                            )
                        );

                        return $validator-&gt;isValid($value);
                    },
                    'messages' =&gt; array(
                        Zend_Validate_Callback::INVALID_VALUE =&gt; 'Please enter a correct email',
                    ),
                ),
            ),
        ),
    )
);
</pre>
<p>It might seem a little far fetched, but it works <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2011/01/07/single-error-message-for-zend_validate_emailaddress/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Zend Framework Certified Engineer</title>
		<link>http://blog.motane.lu/2010/12/16/zend-framework-certified-engineer/</link>
		<comments>http://blog.motane.lu/2010/12/16/zend-framework-certified-engineer/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 12:07:46 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[certifications]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1429</guid>
		<description><![CDATA[This is a post I&#8217;ve been wanting to write for a while but I didn&#8217;t quite get the time to do it. It&#8217;s about me finally taking the ZF certification exam. I wanted to take this certification for over an year and a half, but first I postponed it because I was learning python and [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.motane.lu/wp-content/uploads/2009/05/zend_framework_logo.png" alt="" title="Zend Framework" width="259" height="136" class="alignleft size-full wp-image-689" />This is a post I&#8217;ve been wanting to write for a while but I didn&#8217;t quite get the time to do it. It&#8217;s about me finally taking the ZF certification exam. I wanted to take this certification for over an year and a half, but first I postponed it because I was learning python and working with Django and I didn&#8217;t have the time to actually look over Zend Framework&#8217;s manual and read it. Then I moved to Spain, got caught up with other problems and so on, and so on&#8230;</p>
<p>Thing is that I bought a voucher for this exam about an year ago, and, as most Zend issued vouchers, it only lasts one year. So, few weeks ago I found myself with an already paid non-refundable voucher bound to expire. Since I had nothing to lose, I decided to take my chances and take the exam. And I did <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <a href="http://www.zend.com/en/store/education/certification/yellow-pages.php#show-ClientCandidateID=ZEND009807" title="View my Zend profile" class="outgoing">Hooray for me</a>!</p>
<h2><span>About the exam</span></h2>
<p>The Zend Framework is much more &#8220;to the point&#8221; than the PHP 5 and it&#8217;s a piece of cake for the seasoned Zend Framework developer. No more &#8220;which comes first: the needle or the haystack?&#8221; questions. Everything is focused on asserting the fact that the candidate has the knowledge required to be productive using ZF. The topics cover a large part of the ZF manual, with focus on commonly used features. This doesn&#8217;t mean that you shouldn&#8217;t pay attention to more &#8220;exotic&#8221; topics like Zend_Memory, Zend_TimeSync or Zend_Wildfire.  Although the test refers to version 1.5 of Zend Framework &#8211; the current version is 1.11 &#8211; there&#8217;s nothing specific to that version and the questions refer to those features that are common throughout all the versions (MVC, coding standards, plugins, validator chains, etc).</p>
<p>PS: don&#8217;t email me asking for the questions to the test! Go study&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2010/12/16/zend-framework-certified-engineer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP switch</title>
		<link>http://blog.motane.lu/2010/08/31/php-switch/</link>
		<comments>http://blog.motane.lu/2010/08/31/php-switch/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 09:10:24 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[strange stuff]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1424</guid>
		<description><![CDATA[Over the years, I&#8217;ve encountered a lot of strange things in PHP, but this one is off the scale: What do you think that the code above will print? Well&#8230;I&#8217;ll spare you the hassle and give you the answer: This weird behavior originates in the fact that PHP uses the equality operator (==) instead of [...]]]></description>
			<content:encoded><![CDATA[<p>Over the years, I&#8217;ve encountered a lot of strange things in PHP, but this one is off the scale:</p>
<pre class="brush: php; title: ; notranslate">
$value = 'zero';

switch ($value) {
    case 0:
        echo 'value is zero';
        break;
    default:
        echo 'value is not zero';
        break;
}
echo PHP_EOL;
</pre>
<p>What do you think that the code above will print? Well&#8230;I&#8217;ll spare you the hassle and give you the answer:</p>
<pre class="brush: bash; title: ; notranslate">
% php test.php
value is zero
</pre>
<p>This weird behavior originates in the fact that PHP uses the equality operator (==) instead of the identity (===) one when evaluating expressions inside a switch statement. It&#8217;s basically the same as:</p>
<pre class="brush: php; title: ; notranslate">
if ('foo' == 0) {
    echo 'bar';
}
</pre>
<p>&#8230;which also yields unexpected results. I hate this type of casting!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2010/08/31/php-switch/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

