<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>PHP Magazine</title>
	
	<link>http://www.phpmag.ru</link>
	<description>Suum cuique</description>
	<lastBuildDate>Fri, 15 Jan 2010 11:33:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/php-addicted" /><feedburner:info uri="php-addicted" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://creativecommons.org/licenses/by/3.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><feedburner:emailServiceId>php-addicted</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/php-addicted" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fphp-addicted" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><item>
		<title>Zend_Uri and spaces/unwise chars in URLs</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/2xg25exLpWE/</link>
		<comments>http://www.phpmag.ru/2010/01/13/zend_uri-and-unwise-chars-in-urls/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 09:15:06 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Uri]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=928</guid>
		<description><![CDATA[Usage of Zend_Http_Client is pretty straight-forward:

$client = new Zend_Http_Client($uri);
$client->request(Zend_Http_Client::HEAD); // HTTP HEAD request

However, today, on my Ubuntu box I had real problems as HTTP client constantly ended in segmentation fault (SIGTERM in apache logs). When debugging, I noticed that it does so only if $uri contains so called &#171;unwise&#187; characters, such as spaces, &#171;{&#171;, &#171;}&#187;, [...]]]></description>
			<content:encoded><![CDATA[<p>Usage of Zend_Http_Client is pretty straight-forward:</p>
<pre name="code" class="php">
$client = new Zend_Http_Client($uri);
$client->request(Zend_Http_Client::HEAD); // HTTP HEAD request
</pre>
<p>However, today, on my Ubuntu box I had real problems as HTTP client constantly ended in segmentation fault (SIGTERM in apache logs). When debugging, I noticed that it does so only if $uri contains so called &laquo;unwise&raquo; characters, such as spaces, &laquo;{&laquo;, &laquo;}&raquo;, &laquo;^&raquo; etc.</p>
<p>Going deeper, I reviewed the source code of Zend_Http_Client::setUri($uri) method, only to discover that it relies on Zend_Uri::factory($uri), to initialize the URLs. From there it was pretty simple. Zend_Uri is aware of &laquo;unwise&raquo; chars problem and disallows them by default (why exception thrown by Zend_Uri ended in SIGTERM is yet to discover, however). In order to allow such a characters:</p>
<pre name="code" class="php">
Zend_Uri::setConfig(array('allow_unwise' => true));
$client = new Zend_Http_Client($uri); // $uri may contain unwise chars now
</pre>
<p>After issuing above instruction Zend_Uri accepts those unwisely formed URIs. Plus, you have to URL-encode white-spaces (i.e. make sure that white-spaces in query string, or actually in URI part after the host name are replaced with &laquo;%20&#8243; char) to make them acceptable.</p>
<p>Further info available in <a href="http://framework.zend.com/manual/en/zend.uri.html#zend.uri.validation.allowunwise">offical documentation</a>.</p>
<p>Please note, that I still think that having unreliable chars in URI is really bad practice. If you work with some system that already gone far on this path, it&#8217;s nice to have a method to actually consume such a wildly formed URIs. Kudos to Zend_Uri maintainers!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=2xg25exLpWE:lehwpYSphyQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=2xg25exLpWE:lehwpYSphyQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=2xg25exLpWE:lehwpYSphyQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=2xg25exLpWE:lehwpYSphyQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=2xg25exLpWE:lehwpYSphyQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=2xg25exLpWE:lehwpYSphyQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=2xg25exLpWE:lehwpYSphyQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=2xg25exLpWE:lehwpYSphyQ:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/2xg25exLpWE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2010/01/13/zend_uri-and-unwise-chars-in-urls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2010/01/13/zend_uri-and-unwise-chars-in-urls/</feedburner:origLink></item>
		<item>
		<title>Zend Framework via svn:externals</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/_DaHWalUduM/</link>
		<comments>http://www.phpmag.ru/2009/12/30/zend-framework-via-svnexternals/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 21:41:52 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=921</guid>
		<description><![CDATA[I have used ZF in several projects, and think is is quite safe to use svn:externals to attach Zend and ZendX as external dependency. It might not be the good idea for other projects, but when it comes to ZF &#8211; what is in trunk is pretty stable.
So, go into folder which stores ZF, and [...]]]></description>
			<content:encoded><![CDATA[<p>I have used ZF in several projects, and think is is quite safe to use svn:externals to attach Zend and ZendX as external dependency. It might not be the good idea for other projects, but when it comes to ZF &#8211; what is in trunk is pretty stable.</p>
<p>So, go into folder which stores ZF, and safely remove the library. Then just add ZF as external dependency (which would be updated every time you update the working copy):</p>
<pre name="code" class="bash">
svn pe svn:externals .
</pre>
<p>in and editor opened, enter the dependencies:</p>
<pre name="code" class="bash">
Zend http://framework.zend.com/svn/framework/standard/trunk/library/Zend
ZendX http://framework.zend.com/svn/framework/extras/trunk/library/ZendX
</pre>
<p>finally commit everything and obtain.</p>
<pre name="code" class="bash">
svn ci -m 'ZF set as external dep'
svn up
</pre>
<p>The beauty of this approach &#8211; you always have up to date version of ZF.<br />
The danger of this approach &#8211; you always have up to date version of ZF!</p>
<p>Word of caution:<br />
Sometimes this may break things (when backward-compatibility is broken in ZF trunk), but actually if you have unit tests which check your build before deploying, you are pretty safe &#8211; you spot the problem, you resolve it.</p>
<p>NB: This approach supposes that you tag your releases, so that when new release is coming out, you create a tag, export everything into newly created tag (thus freezing the code), and checkout from tag on production server.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=_DaHWalUduM:3kzmWkfYBPU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=_DaHWalUduM:3kzmWkfYBPU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=_DaHWalUduM:3kzmWkfYBPU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=_DaHWalUduM:3kzmWkfYBPU:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=_DaHWalUduM:3kzmWkfYBPU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=_DaHWalUduM:3kzmWkfYBPU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=_DaHWalUduM:3kzmWkfYBPU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=_DaHWalUduM:3kzmWkfYBPU:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/_DaHWalUduM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/12/30/zend-framework-via-svnexternals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/12/30/zend-framework-via-svnexternals/</feedburner:origLink></item>
		<item>
		<title>Ubuntu 9.04 + PHP5 + GD2</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/zg_ADCPUfPk/</link>
		<comments>http://www.phpmag.ru/2009/09/12/ubuntu-9-04-php-5-gd-2/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 10:00:49 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=904</guid>
		<description><![CDATA[It all started when I decided to optimize image slicing algorithm for a new feature on UMapper &#8211; and since GD is quite RAM-intensive, I needed to check actual memory consumption, and the obvious choice to do so was PHP&#8217;s memory_get_usage() function. However, it failed to produce accurate results &#8211; it seemed like images loaded [...]]]></description>
			<content:encoded><![CDATA[<p>It all started when I decided to optimize image slicing algorithm for a new feature on <a href="http://www.umapper.com">UMapper</a> &#8211; and since GD is quite RAM-intensive, I needed to check actual memory consumption, and the obvious choice to do so was PHP&#8217;s memory_get_usage() function. However, it failed to produce accurate results &#8211; it seemed like images loaded into memory weren&#8217;t accounted by the function (RAM was still used <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).<br />
As it turned out, whoever prepared official php5-gd package, compiles against original GD, and not using PHP5 bundled version of the library. I actually wasn&#8217;t aware about the fork, but here is explanation from <a href="http://www.libgd.org/FAQ_PHP#How_do_I_get_gd_to_work_with_PHP.3F">GD Official Site</a>:</p>
<blockquote><p>
The PHP version of gd offers features similar to and sometimes in addition to those included in the latest version of gd found here as well as many bug fixes not present in the latest GD release. If you are working with PHP, using the built-in gd of PHP 4.3.0 or better is recommended.</p>
<p>We are working to merge the changes done in the PHP GD in the normal GD library.
</p></blockquote>
<p>Well, I was pretty sure that unexpected behavior was caused by using original GD library instead of bundled one. So I decided to remove php5-gd package, recompile php5 from sources, and install updated GD package &#8211; which is exactly what gets bundled with PHP5 on other distributions.</p>
<p>Google is my friend, so here is a walkthrough:</p>
<pre name="code" class="bash">
# Install build tools, debian helpers and fakeroot
apt-get install build-essential debhelper fakeroot
# Get PHP source (it should go into /usr/src)
cd /usr/src
apt-get source php5
# Install all packages required to build PHP5
apt-get build-dep php5

#Now what we need is to update compile options,
# so we need to edit debian/rules file:
cd php5-5.2.6.dfsg.1
vim debian/rules
# locate the line having "--with-gd=shared,/usr --enable-gd-native-ttf \"
# replace with "--with-gd=shared --enable-gd-native-ttf \"
# that's remove reference to /usr so that bundled library is used

# compile (drink some coffee, walk you dog, see the latest House episode)
dpkg-buildpackage -rfakeroot

# install the new php5-gd package
cd ..
dpkg -i php5-gd_5.2.6.dfsg.1-3ubuntu4.2_i386.deb

# finally restart apache
/etc/init.d/apache2 restart
</pre>
<p>That&#8217;s it &#8211; you should be able to see &laquo;bundled&raquo; near the GD version in the phpinfo() output. Well, that&#8217;s not the only gain &#8211; it solves problem with memory_get_usage() as well <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Now, once I had memory_get_usage() working correctly, back to optimization..</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=zg_ADCPUfPk:W4uKaKS11IA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=zg_ADCPUfPk:W4uKaKS11IA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=zg_ADCPUfPk:W4uKaKS11IA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=zg_ADCPUfPk:W4uKaKS11IA:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=zg_ADCPUfPk:W4uKaKS11IA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=zg_ADCPUfPk:W4uKaKS11IA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=zg_ADCPUfPk:W4uKaKS11IA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=zg_ADCPUfPk:W4uKaKS11IA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/zg_ADCPUfPk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/09/12/ubuntu-9-04-php-5-gd-2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/09/12/ubuntu-9-04-php-5-gd-2/</feedburner:origLink></item>
		<item>
		<title>How to create self-signed SSL certificate</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/Q7WOxz4JY4w/</link>
		<comments>http://www.phpmag.ru/2009/08/12/how-to-create-self-signed-ssl-certificate/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 02:05:17 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tricks & Tips]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[SSL]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=859</guid>
		<description><![CDATA[Note: this is really a how-to, w/o any in-depth explanation, just a note to myself.
Today, I needed to add SSL support to UMapper.com application running on my Slackware localhost. We use CA-signed certificates on our server, but for local box self-signed was quite enough (all I need is to be able to view development version [...]]]></description>
			<content:encoded><![CDATA[<p>Note: this is really a how-to, w/o any in-depth explanation, just a note to myself.</p>
<p>Today, I needed to add SSL support to <a href="http://www.umapper.com">UMapper.com</a> application running on my Slackware localhost. We use CA-signed certificates on our server, but for local box self-signed was quite enough (all I need is to be able to view development version of site via https). Here what I did:</p>
<p>1. Create private key:</p>
<pre name="code" class="bash">
$ openssl genrsa -out localhost.key 1024
</pre>
<p>2. Generate CSR (Certificate Signing Request):</p>
<pre name="code" class="php">
$ openssl req -new -key localhost.key -out localhost.csr
</pre>
<p>3. Generate certificate:</p>
<pre name="code" class="shell">
$ openssl x509 -req -days 365 -in localhost.csr \
        -signkey localhost.key -out localhost.crt
</pre>
<p>4. Make sure SSL is enabled in httpd.conf:</p>
<pre name="code" class="shell">
# Following two should be uncommented
LoadModule ssl_module lib/httpd/modules/mod_ssl.so
Include /etc/httpd/extra/httpd-ssl.conf
</pre>
<p>5. Edit httpd-ssl.conf so that virtual host users your created certificate:</p>
<pre name="code" class="shell">
# locate and edit cert.details. Make sure localhost.crt and localhost.key
# are present (you either created them there or copied)
SSLCertificateFile "/etc/httpd/certs/localhost.crt"
SSLCertificateKeyFile "/etc/httpd/certs/localhost.key"
</pre>
<p>6. Restart apache:</p>
<pre name="code" class="shell">
$ apachectl restart
</pre>
<p>That&#8217;s it. Please note that browser would still generate exception (and it is a good thing, as otherwise certificates wouldn&#8217;t be that useful). All you need is to add your localhost as exception &#8211; since we really trust that details we provided during certificate creation are our own <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>P.S. If you are getting &laquo;[warn] _default_ VirtualHost overlap on port 443,<br />
the first has precedence&raquo;, add <i>NameVirtualHost *:443</i> into your httpd.conf</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=Q7WOxz4JY4w:1NhZGMatJWM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Q7WOxz4JY4w:1NhZGMatJWM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=Q7WOxz4JY4w:1NhZGMatJWM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Q7WOxz4JY4w:1NhZGMatJWM:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Q7WOxz4JY4w:1NhZGMatJWM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=Q7WOxz4JY4w:1NhZGMatJWM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Q7WOxz4JY4w:1NhZGMatJWM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=Q7WOxz4JY4w:1NhZGMatJWM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/Q7WOxz4JY4w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/08/12/how-to-create-self-signed-ssl-certificate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/08/12/how-to-create-self-signed-ssl-certificate/</feedburner:origLink></item>
		<item>
		<title>Zend Framework: Authorize.net CIM proposal</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/Zi8CY2nV9Ao/</link>
		<comments>http://www.phpmag.ru/2009/08/07/zend-framework-authorize-net-cim-proposal/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 10:06:28 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[PHP5]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[ANet CIM]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=853</guid>
		<description><![CDATA[I have finally completed proposal for Authorize.net CIM API. Hopefully, this API gets included into ZF (in one form or another), as ANet is one of the best services to work with user payment profiles, let alone CC processing. On proposal page you can review use cases, and if you are interested in internals feel [...]]]></description>
			<content:encoded><![CDATA[<p>I have finally completed <a href="http://zendframework.com/wiki/display/ZFPROP/Zend_Service_AuthorizeNet_Cim+-+Victor+Farazdagi">proposal</a> for <a href="http://www.authorize.net/solutions/merchantsolutions/merchantservices/cim/">Authorize.net CIM</a> API. Hopefully, this API gets included into ZF (in one form or another), as ANet is one of the best services to work with user payment profiles, let alone CC processing. On proposal page you can review use cases, and if you are interested in internals feel free to download fully-working component&#8217;s <a href="http://www.phpmag.ru/AuthorizeNet.tar.gz">prototype</a> (it is still a prototype as most probably it would be updated in accordance with peer review on ZF wiki).</p>
<p>Let me know your suggestions on how the component can be improved.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=Zi8CY2nV9Ao:KJIkxjlKotw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Zi8CY2nV9Ao:KJIkxjlKotw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=Zi8CY2nV9Ao:KJIkxjlKotw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Zi8CY2nV9Ao:KJIkxjlKotw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Zi8CY2nV9Ao:KJIkxjlKotw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=Zi8CY2nV9Ao:KJIkxjlKotw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=Zi8CY2nV9Ao:KJIkxjlKotw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=Zi8CY2nV9Ao:KJIkxjlKotw:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/Zi8CY2nV9Ao" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/08/07/zend-framework-authorize-net-cim-proposal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/08/07/zend-framework-authorize-net-cim-proposal/</feedburner:origLink></item>
		<item>
		<title>__toString() must not throw an exception</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/DHmyKeAKxdI/</link>
		<comments>http://www.phpmag.ru/2009/08/07/__tostring-must-not-throw-an-exception/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 00:57:47 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[PHP5]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Magic Methods]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=846</guid>
		<description><![CDATA[This seems kind of limitation to me, indeed, if you use __toString() magic method for anything other than simple object variables concatenation, your code should be able to throw exceptions. Consider you have an object that generates XML as output, and you decide to provide even nicer interface, so that anyone using it in string [...]]]></description>
			<content:encoded><![CDATA[<p>This seems kind of limitation to me, indeed, if you use __toString() magic method for anything other than simple object variables concatenation, your code should be able to throw exceptions. Consider you have an object that generates XML as output, and you decide to provide even nicer interface, so that anyone using it in string context to get access to that XML. XML generation might not go well, and the obvious way to let the client know about this is to throw an exception. However, this is not possible (most probably due to some internal architecture limitations &#8211; as I honestly see no reason why this ideologically wrong).</p>
<p>One (not quite pretty) way to still provide some feedback from __toString() is using trigger_error:</p>
<pre name="code" class="php">
public function  __toString()
{
    try {
        $output = $this->generateXml();
        return $output;
    } catch(Exception $e) {
        trigger_error($e->getMessage(), E_USER_ERROR);
        return '';
    }
}
</pre>
<p>If you know of a better option, let me know!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=DHmyKeAKxdI:du1CxbxH1x0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=DHmyKeAKxdI:du1CxbxH1x0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=DHmyKeAKxdI:du1CxbxH1x0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=DHmyKeAKxdI:du1CxbxH1x0:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=DHmyKeAKxdI:du1CxbxH1x0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=DHmyKeAKxdI:du1CxbxH1x0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=DHmyKeAKxdI:du1CxbxH1x0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=DHmyKeAKxdI:du1CxbxH1x0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/DHmyKeAKxdI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/08/07/__tostring-must-not-throw-an-exception/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/08/07/__tostring-must-not-throw-an-exception/</feedburner:origLink></item>
		<item><title>Exploring SPL: Interfaces [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/t3YxRgk62A4/</link><category>php spl</category><dc:creator>farazdagi</dc:creator><pubDate>Wed, 05 Aug 2009 15:36:23 PDT</pubDate><guid isPermaLink="false">http://www.phpmag.ru/2009/08/05/exploring-spl-interfaces/</guid><description>Starting with PHP5 almost any PHP installation contained SPL (Standard PHP Library) extension - with few exceptions, when hosters intentionally disabled it. With PHP 5.3 out, this extension is considered to be within PHP core, and as such it&amp;#039;s not po&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/t3YxRgk62A4" height="1" width="1"/&gt;</description><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/php" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/spl" />
      </rdf:Bag>
    </taxo:topics><feedburner:origLink>http://www.phpmag.ru/2009/08/05/exploring-spl-interfaces/</feedburner:origLink></item><item>
		<title>Exploring SPL: Interfaces</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/t3YxRgk62A4/</link>
		<comments>http://www.phpmag.ru/2009/08/05/exploring-spl-interfaces/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 02:22:30 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[PHP5]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Interfaces]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=752</guid>
		<description><![CDATA[Starting with PHP5 almost any PHP installation contained SPL (Standard PHP Library) extension &#8211; with few exceptions, when hosters intentionally disabled it. With PHP 5.3 out, this extension is considered to be within PHP core, and as such it&#8217;s not possible to disable it anymore. This in fact is a good thing, as SPL really [...]]]></description>
			<content:encoded><![CDATA[<p>Starting with PHP5 almost any PHP installation contained SPL (Standard PHP Library) extension &#8211; with few exceptions, when hosters intentionally disabled it. With PHP 5.3 out, this extension is considered to be within PHP core, and as such it&#8217;s not possible to disable it anymore. This in fact is a good thing, as SPL really deserves to be the core component.</p>
<p>In an attempt to shed some light on and to draw attention to SPL, I plan to post several articles discussing various parts of this extension. I will start with SPL Interfaces so that you can grasp immediately the usefulness of the SPL. </p>
<p>Comprehending SPL interfaces presupposes that you know standard interfaces that come build-in with PHP5. So, I wrote <a href="http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/">preliminary article</a> discussing them &#8211; I consider it to be a prerequisite for good understanding of the current material.</p>
<p>Covered in this article:</p>
<ul>
<li><a href="#countable">The Countable Interface</a></li>
<li><a href="#outer.iterator">The OuterIterator Interface</a></li>
<li><a href="#seekable">The Seekable Interface</a></li>
<li><a href="#recursive.iterator">The RecursiveIterator Interface</a></li>
<li><a href="#spl.observer.subject">The SplObserver and SplSubject Interfaces</a></li>
</ul>
<p><span id="more-752"></span></p>
<p><a name="countable">&nbsp;</a><br />
<strong>The Countable Interface</strong></p>
<p><a href="http://ru.php.net/manual/en/class.countable.php">Countable</a> interface is quite simple: classes implementing it can be used with the <a href="http://php.net/manual/en/function.count.php">count()</a> function. </p>
<pre name="code" class="php">
Countable   {
    /* Methods */
    abstract public int count ( void )
}
</pre>
<p>As you see, all it takes to comply to interface&#8217;s contract is implementation of single method, namely <i>count()</i>:</p>
<pre name="code" class="php">
/**
 * Dummy "contained" class
 */
class Item {}

/**
 * Dummy "container" class implementing Countable
 */
class Items implements Countable
{
    protected $items = array();

    public function add(Item $item)
    {
        $this->items[] = $item;
        return $this;
    }

    public function count()
    {
        return count($this->items);
    }
}

$items = new Items();
$items->add(new Item())
      ->add(new Item())
      ->add(new Item());
echo count($items);     // outputs 3
// you can use sizeof() as well - since it's an alias for count()
echo sizeof($items);
</pre>
<p><a name="outer.iterator">&nbsp;</a><br />
<strong>The OuterIterator Interface</strong></p>
<p>I am not sure why php manual&#8217;s <a href="http://php.net/manual/en/spl.interfaces.php">respective section</a> doesn&#8217;t contain explanation of this interface, my wild guess &#8211; doc.team hasn&#8217;t time to fill it (hopefully, yet). Anyway, here is what OuterIterator is all about: OuterIterator serves as wrapper for another inner iterator (which is generally passed into constructor of implementing class). It is similar to IteratorAggregate, but while the former is extending Traversable, OuterIterator extends Iterator &#8211; so implementing class not only contains accessor method for contained iterator, but could be iterated itself as well <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I know, how it sounds, no need to panic though &#8211; everything would be clear in a moment. Let&#8217;s first look into synopsis:</p>
<pre name="code" class="php">
OuterIterator extends Iterator {
    /* Methods */
    abstract public Iterator getInnerIterator();

    /* Inherited methods */
    abstract public mixed current( void  )
    abstract public scalar key( void )
    abstract public void next( void )
    abstract public void rewind( void )
    abstract public boolean valid( void )
}
</pre>
<p>So, implementing object must be traversable and contain reference to some inner iterator. There&#8217;s great pre-build <a href="http://ru.php.net/manual/en/class.filteriterator.php">FilterIterator</a>, which is an abstract class, allowing to create filter iterators (iterators that filter out some unwanted values). FilterIterator implements OuterIterator &#8211; you pass the iterator to be filtered, and then you can traverse the FilterIterator for filtered values. Let&#8217;s build our own version of FilterIterator:</p>
<pre name="code" class="php">
class OddsFilter implements OuterIterator
{
    protected $innerIterator = null;

    public function __construct(Iterator $iterator)
    {
        $this->innerIterator = $iterator;
    }

    /**
     * whether the current element of the iterator is acceptable
     */
    public function accept()
    {
        return (bool)($this->current() % 2); // false on evens, true on odds
    }

    /* OuterIterator Methods */
    public function getInnerIterator()
    {
        return $this->innerIterator;
    }

    /* Inherited methods */
    public function current()
    {
        return $this->innerIterator->current();
    }

    public function key()
    {
        return $this->innerIterator->key();
    }

    public function next()
    {
        do {
            $this->innerIterator->next();
            if(!$this->valid()) break;
        } while (!$this->accept()); // traverse till acceptable element is found
    }

    public function rewind()
    {
        $this->innerIterator->rewind();
    }

    public function valid()
    {
        return $this->innerIterator->valid();
    }

}

$iterator = new ArrayIterator(array(1, 2, 3, 4, 5));
$filteredIterator = new OddsFilter($iterator);
print_r(iterator_to_array($filteredIterator));
</pre>
<p>Time to take a closer look at code. OddsFilter is an iterator that filters out even numbers and returns odd numbers only. It accepts instance of Iterator in its constructor, here we used ArrayIterator (very simple iterator, allowing us to traverse arrays and objects). So, on line 55, we created <b>$iterator</b> variable from sample array, and passed this iterator into OddsFilter. OddsFilter mainly delegates calls to contained/inner iterator with a prominent exception of next() method:</p>
<pre name="code" class="php">
public function next()
{
    do {
        $this->innerIterator->next();
        if(!$this->valid()) break; // don't traverse if we are out of bounds
    } while (!$this->accept()); // traverse till acceptable element is found
}
</pre>
<p>Here, again, we eventually call inner iterator&#8217;s next() method, but we might call it several times, untill acceptable value is found.</p>
<p>You might wonder what iterator_to_array() function does, simple &#8211; it copies iterator into array, so that resultant output of our code would be:</p>
<pre name="code" class="php">
Array
(
    [0] => 1
    [2] => 3
    [4] => 5
)
</pre>
<p>Of course, instead of using iterator_to_array(), I could have also traversed <b>$filteredIterator</b> with foreach loop &#8211; after all OddsFilter is an iterator itself.</p>
<p>To sum up, OuterIterator is helpful when we have some input iterator (which serves as inner iterator), that should be somehow manipulated (filtered in our case), and results should also be traversable (which is true, as OuterIterator implements Iterator interface itself). </p>
<p>Please note that extending <a href="http://ru.php.net/manual/en/class.filteriterator.php">FilterIterator</a> class is far superior way of building filters &#8211; all you need is to implement abstract accept() method to get very same results (all traversal logic is done within FilterIterator itself).</p>
<p><a name="seekable">&nbsp;</a><br />
<strong>The Seekable Interface</strong></p>
<p>This interface is build on <a href="http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/#iterator">Iterator</a> and adds support for quick navigating (seeking) of a certain positions. Everything is done via seek() method added with this interface:</p>
<pre name="code" class="php">
SeekableIterator extends Iterator {
    /* Methods */
    abstract public void seek( int $position )
    /* Inherited methods */
    abstract public mixed Iterator::current( void )
    abstract public scalar Iterator::key( void )
    abstract public void Iterator::next( void )
    abstract public void Iterator::rewind( void )
    abstract public boolean Iterator::valid( void )
}
</pre>
<p>Within seek() method internal iterator position should be set to requested value, if position not found or applicable <a href="http://www.php.net/manual/en/class.outofboundsexception.php">OutOfBoundsException</a> should be thrown.</p>
<p>Here is sample iterator implementing the SeekableIterator:</p>
<pre name="code" class="php">
class Item
{
    protected $title = null;

    public function __construct($title)
    {
        $this->title = $title;
    }

    public function __toString()
    {
        return $this->title;
    }
}

class Items implements Iterator, SeekableIterator
{
    /**
     * List of contained items
     * @var array
     */
    protected $items = array();

    /**
     * Current iterator position
     * @var int
     */
    protected $pos = 0;

    public function add(Item $item)
    {
        $this->items[] = $item;
        return $this;
    }

    /**
     * SeekableIterator methods
     */
    public function seek($pos)
    {
        $this->pos = $pos;
        if(!$this->valid()) { // position is not seekable!
            throw new OutOfBoundsException('Item at position ' . $pos . ' not found..');
        }
    }

    /**
     * Iterator methods
     */
    public function current()
    {
        return $this->items[$this->pos];
    }

    public function key()
    {
        return $this->pos;
    }

    public function next()
    {
        $this->pos++;
    }

    public function rewind()
    {
        $this->pos = 0;
    }

    public function valid()
    {
        return isset($this->items[$this->pos]);
    }
}

$items = new Items();
$items->add(new Item('milk'))
      ->add(new Item('butter'))
      ->add(new Item('bread'));

try {
    $items->seek(2);
    printf('%d - %s ', $items->key(), $items->current()); // 2 - bread

    $items->seek(3); // OutOfBoundsException should be thrown
                     // Item at position 3 not found..
} catch (OutOfBoundsException $e) {
    die($e->getMessage());
}
</pre>
<p>As you can see, I based this example on <a href="http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/#iterator">Iterator&#8217;s example</a> from preliminary article. Indeed, in order to make our iterator more flexible (next() method is cool but locating items in any order other than sequential is impossible), all we have to do is to add seek() method that does the job.</p>
<p><a name="recursive.iterator">&nbsp;</a><br />
<strong>The RecursiveIterator Interface</strong></p>
<p>Before we get into details, let&#8217;s give somewhat formal definition of interface.</p>
<p>RecursiveIterator extends <a href="http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/#iterator">Iterator</a> interface, so it is an iterator itself. What is special about this iterator is the fact that items it contains can be also traversed i.e. we can create iterators for them. Consider multi-dimensional array: </p>
<pre name="code" class="php">
$numbers = array(
    array(1, 2),
    array(3, 4, 5, array(6, 7)),
    8, 9
);
</pre>
<p>This array has 4 elements in total. Whilst first two are arrays, last two (8, 9) are scalars. Imagine that we wanted to print all numbers in that <b>$numbers</b> array &#8211; obviously the recursive function is the most elegant solution (which allows us to have as much depth as necessary). Here, we can traverse first two elements of the array, as they are arrays themselves, even more &#8211; the second element has not only scalars in it but yet another array to be traversed:</p>
<pre name="code" class="php">
    array(3, 4, 5, array(6, 7))
</pre>
<p>RecursiveIterator interface was designed to solve exactly this kinds of problems. If you have a complex structure with multiple levels of data, this interface helps you to recursively traverse all contained elements. Thus in PHP manual definition of this interface goes as following: </p>
<blockquote><p>Classes implementing RecursiveIterator can be used to iterate over iterators.</p></blockquote>
<p>Indeed, if any contained entry can be traversed (i.e. we can attach iterator to it), RecursiveIterator provides an interface to do so.</p>
<p>Here is the synopsis:</p>
<pre name="code" class="php">
RecursiveIterator extends Iterator {
    // Returns an iterator for the current entry
    public RecursiveIterator getChildren( void )

    // whether an iterator could be created for the current entry
    public bool hasChildren( void ) 

    /* Inherited methods */
    abstract public mixed Iterator::current ( void )
    abstract public scalar Iterator::key ( void )
    abstract public void Iterator::next ( void )
    abstract public void Iterator::rewind ( void )
    abstract public boolean Iterator::valid ( void )
}
</pre>
<p>As you see two new methods has been added. </p>
<p>Please note, these methods apply to the current entry, not the base iterator itself. So, hasChildren() should check whether current entry is an array or object, and as such is traversable, thus allowing to create iterator for it. By the same token, getChildren() returns iterator for the current entry&#8217;s contained items. Somewhat obvious, but when I first read the documentation, it took me some time to figure this out.</p>
<p>In order to iterate over children items, we have to be sure that entry is traversable &#8211; hasChildren() method is exactly for this. Once we know, that current entry is traversable, we should be able to obtain iterator to do so &#8211; getChildren() returns such an iterator (its type must be RecursiveIterator &#8211; what we are dealing with, on all levels of recursion, is always one type of interface).</p>
<p>It&#8217;s time to show you some code! First of all NumberIterator I have written to &laquo;flatten&raquo; arrays, so that despite the dimensions, I can have a list of all elements:</p>
<pre name="code" class="php">
class NumbersIterator implements RecursiveIterator
{
    /**
     * List of numbers. Array may be multi-dimensional.
     * @var array
     */
    public $numbers = array();

    /**
     * Current iterator's position
     * @var int
     */
    protected $pos = 0;

    /**
     * Initiates iterator
     * @param array $numbers
     */
    public function __construct($numbers = array())
    {
        $this->numbers = $numbers;
    }

    /**
     * RecursiveIterator methods
     */

    /**
     * Returns current entry's iterator
     * @return NumbersIterator
     */
    public function getChildren()
    {
        return new NumbersIterator($this->current());
    }

    /**
     * Returns true if iterator could be obtained for the current entry.
     * @return boolean
     */
    public function hasChildren()
    {
        return is_array($this->current());
    }

    /**
     * Iterator methods
     */
    public function current()
    {
        return $this->numbers[$this->pos];
    }

    public function key()
    {
        return $this->pos;
    }

    public function next()
    {
        $this->pos++;
    }

    public function rewind()
    {
        $this->pos = 0;
    }

    public function valid()
    {
        return isset($this->numbers[$this->pos]);
    }
}
</pre>
<p>Now we need a recursive function, which would help us traversing:</p>
<pre name="code" class="php">
function displayNumbers(NumbersIterator $iterator) {
    while($iterator->valid()) {
        if($iterator->hasChildren()) {
            displayNumbers($iterator->getChildren());
        } else {
            echo $iterator->current() . '';
        }
        $iterator->next();
    }
}
</pre>
<p>Finally, let&#8217;s traverse the array I have shown you at the beginning of this section:</p>
<pre name="code" class="php">
$numbers = array(
    array(1, 2),
    array(3, 4, 5, array(6, 7)),
    8, 9
);

$iterator = new NumbersIterator($numbers);
displayNumbers($iterator);
</pre>
<p>Everything should be pretty self-explanatory &#8211; scalars get printed &laquo;as is&raquo;, if current iteratable entry is an array (i.e. hasChildren() returns true), I traverse all its children, by recursively calling displayNumbers().</p>
<p>This section was one of the hardest to explain, so sorry for lengthy code and explanations. If you still feel lost, please, let me know via comments &#8211; I would try to clarify and improve current section.</p>
<p><a name="spl.observer.subject">&nbsp;</a><br />
<strong>The SplObserver and SplSubject Interfaces</strong></p>
<p>I would discuss both interfaces in a single section, as they describe well known <a href="http://en.wikipedia.org/wiki/Observer_pattern">Observer design pattern</a>.</p>
<p>Again, I am not sure why PHP Manual&#8217;s <a href="http://www.php.net/manual/en/spl.interfaces.php">respective section</a> does not provide any info regarding this interfaces, I believe they are quite important, so here is what they all about:</p>
<p>I would not go into any details regarding observer pattern &#8211; as there better places (<a href="http://www.a-scripts.com/object-oriented-php/2009/02/21/the-observer-pattern/">here</a> for eg) that provide explanation and PHP implementations of the pattern. In a nutshell, the pattern allows you to define one-to-many relationship between so called Subject and Observer(s), and once the state of the Subject changes, all bind Observer(s) get notified. If you know Java (read-only is enough), Head First Design Patterns is really mind-friendly intro (I don&#8217;t suggest GoF&#8217;s book, because if you are able to get through it, there&#8217;s 0 possibility you haven&#8217;t tried it yet <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p>Now, back to interfaces.</p>
<p>SplSubject</p>
<pre name="code" class="php">
SplSubject {
    public void attach(SplObserver $observer);
    public void detach(SplObserver $observer);
    public void notify();
}
</pre>
<p>Interface is pretty simple: you should be able to attach observing objects, detach them, and, once state of the subject is changed, notify observers. Here is sample implementation:</p>
<pre name="code" class="php">
class Subject implements SplSubject
{
    /**
     * List of attached observers
     * @var array
     */
    protected $observers = array();

    protected $title = null;

    /**
     * Update subject's title - observers notified!
     * @param string $title
     */
    public function setTitle($title)
    {
        $this->title = $title;
        $this->notify(); // all observers get notified of change
    }

    public function getTitle()
    {
        return $this->title;
    }

    /**
     * SplSubject methods
     */

    public function attach(SplObserver $observer)
    {
        $this->observers[] = $observer;
    }

    public function detach(SplObserver $observer)
    {
        // I cannot use array_search output in IF block directly,
        // as 0 might be returned (if what I am detaching is the first observer)
        // so I must make sure that $key is not false (taking type into account)
        $key = array_search($observer, $this->observers, true);
        if( !($key === false) ) {
            unset($this->observers[$key]);
        }
    }

    public function notify()
    {
        foreach($this->observers as $observer) {
            $observer->update($this);
        }
    }
}
</pre>
<p>SplObserver is even more simple, all you have to do is to provide update() method:</p>
<pre name="code" class="php">
SplObserver {
    public void update(SplSubject $subject);
}
</pre>
<p>Implementation of simple observer class:</p>
<pre name="code" class="php">
class Observer implements SplObserver
{
    public function update(SplSubject $subject)
    {
        echo 'Subject updated! New title: ' . $subject->getTitle();
    }
}
</pre>
<p>Now, let&#8217;s use our Subject and Observer together:</p>
<pre name="code" class="php">
$subject = new Subject();       // create subject
$observer = new Observer();     // create observer
$subject->attach($observer);    // attach observer
$subject->setTitle('Hi, there!'); // Subject updated! New title: Hi, there!
</pre>
<p>Well, SPL implementation of the observer pattern is not the best I&#8217;ve seen &#8211; since it tightly couples the subject and observer (for example, our observer is aware that subject has getTitle() method). However, for most needs it is good enough.</p>
<p><strong>Conclusion</strong></p>
<p>I hope you enjoyed at least some parts of this article, and hopefully it gives you better understanding of the SPL&#8217;s interfaces. </p>
<p>Next stop is SPL data structures &#8211; they are even more interesting than interfaces, as they build on what we saw in this article.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=t3YxRgk62A4:kM9thj4mWMw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=t3YxRgk62A4:kM9thj4mWMw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=t3YxRgk62A4:kM9thj4mWMw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=t3YxRgk62A4:kM9thj4mWMw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=t3YxRgk62A4:kM9thj4mWMw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=t3YxRgk62A4:kM9thj4mWMw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=t3YxRgk62A4:kM9thj4mWMw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=t3YxRgk62A4:kM9thj4mWMw:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/t3YxRgk62A4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/08/05/exploring-spl-interfaces/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/08/05/exploring-spl-interfaces/</feedburner:origLink></item>
		<item>
		<title>MySQL: ERROR 1064 (42000) when importing sql-dumps</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/rWk30f3fuqc/</link>
		<comments>http://www.phpmag.ru/2009/08/02/mysql-error-1064-42000-when-importing-sql-dumps/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 16:51:19 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=808</guid>
		<description><![CDATA[Today, I wanted to import quite a huge sql-dump, and got this error. What I was using was:

mysql --user=root -p dbName < sqlDumpName.sql

I was pretty sure about dump's integrity, so after receiving "Error 1064" decided to import using source command:

#mysql --user -p
mysql>use dbName;
mysql>source ./sqlDumpName.sql

This time import went through w/o any issues.
]]></description>
			<content:encoded><![CDATA[<p>Today, I wanted to import quite a huge sql-dump, and got this error. What I was using was:</p>
<pre name="code" class="sql">
mysql --user=root -p dbName < sqlDumpName.sql
</pre>
<p>I was pretty sure about dump's integrity, so after receiving "Error 1064" decided to import using source command:</p>
<pre name="code" class="sql">
#mysql --user -p
mysql>use dbName;
mysql>source ./sqlDumpName.sql
</pre>
<p>This time import went through w/o any issues.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=rWk30f3fuqc:_BBdW_vTz88:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=rWk30f3fuqc:_BBdW_vTz88:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=rWk30f3fuqc:_BBdW_vTz88:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=rWk30f3fuqc:_BBdW_vTz88:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=rWk30f3fuqc:_BBdW_vTz88:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=rWk30f3fuqc:_BBdW_vTz88:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=rWk30f3fuqc:_BBdW_vTz88:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=rWk30f3fuqc:_BBdW_vTz88:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/rWk30f3fuqc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/08/02/mysql-error-1064-42000-when-importing-sql-dumps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/08/02/mysql-error-1064-42000-when-importing-sql-dumps/</feedburner:origLink></item>
		<item><title>PHP5: Predefined Interfaces [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/qXNrwqLRVJ0/</link><category>php interface</category><dc:creator>farazdagi</dc:creator><pubDate>Sun, 02 Aug 2009 04:06:00 PDT</pubDate><guid isPermaLink="false">http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/</guid><description>Note: This article serves as preliminary for SPL Interfaces article to be published later on.&lt;br /&gt;
Overview of PHP5 predefined interfaces&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/qXNrwqLRVJ0" height="1" width="1"/&gt;</description><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/php" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/interface" />
      </rdf:Bag>
    </taxo:topics><feedburner:origLink>http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/</feedburner:origLink></item><item>
		<title>PHP5: Predefined Interfaces</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/qXNrwqLRVJ0/</link>
		<comments>http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 00:38:50 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[PHP5]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[SPL]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=794</guid>
		<description><![CDATA[Note: This article serves as preliminary for SPL Interfaces article to be published later on. 
I wanted to provide good overview of (highly under-used) Standard PHP Library (SPL) starting with interfaces. However, without firstly discussing predefined interfaces, which come bundled with each and every PHP distribution, discussion of SPL-provided ones seemed to be incomplete. 
To [...]]]></description>
			<content:encoded><![CDATA[<p>Note: This article serves as preliminary for SPL Interfaces article to be published later on. </p>
<p>I wanted to provide good overview of (highly under-used) Standard PHP Library (SPL) starting with interfaces. However, without firstly discussing predefined interfaces, which come bundled with each and every PHP distribution, discussion of SPL-provided ones seemed to be incomplete. </p>
<p>To be covered in this article:</p>
<ul>
<li><a href="#traversable">The Traversable Interface</a></li>
<li><a href="#iterator">The Iterator Interface</a></li>
<li><a href="#iterator.aggregate">The IteratorAggregate Interface</a></li>
<li><a href="#array.access">The ArrayAccess Interface</a></li>
<li><a href="#serializable">The Serializable Interface</a></li>
</ul>
<p><span id="more-794"></span></p>
<p><a name="traversable">&nbsp;</a><br />
<strong>The Traversable Interface</strong></p>
<p>Basically this interface is used to mark that object of the class can be used in <a href="http://ru.php.net/manual/en/control-structures.foreach.php">foreach</a> i.e. it could be traversed. This interface is internal in a sense that you cannot use it directly in your scripts, instead you have to implement either <a href="#iterator">Iterator</a> or <a href="#iterator.aggregate">IteratorAggregate</a> interfaces (which extend the Traversable). Since the interface is not implementable within your PHP classes, it&#8217;s synopsis does not enforce any methods:</p>
<pre name="code" class="php">
Traversable
{}
</pre>
<p><a name="iterator">&nbsp;</a><br />
<strong>The Iterator Interface</strong></p>
<p>Extends the <a href="#traversable">Traversable</a>, this interface can be used to produce objects that can iterate themselves. As a rule of thumb: if your object holds number of some items, and you need to access them individually in foreach, <a href="#iterator">Iterator</a> (or <a href="#iterator.aggregate">IteratorAggregate</a> for that matter) is the good bid. Here is the synopsis:</p>
<pre name="code" class="php">
Iterator extends Traversable {
    /* Methods */
    abstract public mixed current ( void )  // return current element's value
    abstract public scalar key ( void )     // return current element's key
    abstract public void next ( void )      // move internal pointer forward
    abstract public void rewind ( void )    // move to the beginning
    abstract public boolean valid ( void )  // check if current position is valid
}
</pre>
<p>To illustrate, here is sample Iterator implementation and usage:</p>
<pre name="code" class="php">
class Item
{
    protected $title = null;

    public function __construct($title)
    {
        $this->title = $title;
    }

    public function __toString()
    {
        return $this->title;
    }
}

class Items implements Iterator
{
    /**
     * List of contained items
     * @var array
     */
    protected $items = array();

    /**
     * Current iterator position
     * @var int
     */
    protected $pos = 0;

    public function add(Item $item)
    {
        $this->items[] = $item;
        return $this;
    }

    /**
     * Iterator methods
     */
    public function current()
    {
        return $this->items[$this->pos];
    }

    public function key()
    {
        return $this->pos;
    }

    public function next()
    {
        $this->pos++;
    }

    public function rewind()
    {
        $this->pos = 0;
    }

    public function valid()
    {
        return isset($this->items[$this->pos]);
    }
}

$items = new Items();
$items->add(new Item('milk'))
      ->add(new Item('butter'))
      ->add(new Item('bread'));

foreach($items as $key => $item) {
    printf('%d - %s ', $key, $item);
}
// Output:
// 0 - milk
// 1 - butter
// 2 - bread
</pre>
<p>Pretty simple, isn&#8217;t it? Granted, it takes time to get used to, but once you do, you would never look back.</p>
<p><a name="iterator.aggregate">&nbsp;</a><br />
<strong>The IteratorAggregate Interface</strong></p>
<p>PHP5 comes with a lot of predefined iterators (and SPL adds to the list), so you rarely need to write your own. For situations when there&#8217;s already suitable iterator for your object (either pre-build or written by you), there&#8217;s little sense to implement Iterator interface, instead it&#8217;s just enough to implement the IteratorAggregate, which allows you to use external iterators. Here is interface synopsis:</p>
<pre name="code" class="php">
IteratorAggregate extends Traversable {
    /* Methods */
    abstract public Traversable getIterator( void )
}
</pre>
<p>As you see, all you have to do is to provide <i>getIterator()</i> method, which would return suitable instance of iterator to be used for traversal:</p>
<pre name="code" class="php">
class Numbers implements IteratorAggregate
{
    protected $numbers = array(1, 2, 3);

    public function getIterator()
    {
        return new ArrayIterator($this->numbers);
    }
}

$nums = new Numbers();
foreach($nums as $k=>$v) {
    printf('%d - %d ', $k, $v);
}

// Output:
//0 - 1
//1 - 2
//2 - 3
</pre>
<p>I used predefined <a href="http://ru.php.net/manual/en/class.arrayiterator.php">ArrayIterator</a> iterator, which allows to traverse arrays and objects. You can use your own iterator as well (the only requirement is that it implements on <a href="#traversable">Traversable</a>).</p>
<p><a name="array.access">&nbsp;</a><br />
<strong>The ArrayAccess Interface</strong></p>
<p>One of the coolest interfaces that come with PHP5, ArrayAccess allows you to interact with your objects as if they were arrays. If you are familiar with C++, it&#8217;s like overloading [] operator (well, almost). Anyway, here is interface synopsis:</p>
<pre name="code" class="php">
ArrayAccess {
    // whether an offset exists
    abstract public boolean offsetExists( string $offset )
    // returns the value at specified offset
    abstract public mixed offsetGet( string $offset )
    // assigns a value to the specified offset
    abstract public void offsetSet( string $offset , string $value )
    // unsets an offset
    abstract public void offsetUnset( string $offset )
}
</pre>
<p>Don&#8217;t worry if interface doesn&#8217;t seem simple at first, everything would clear up once you review the example:</p>
<pre name="code" class="php">
class Config implements ArrayAccess
{
    protected $options = array(
        'username' => 'torio',
        'uri'      => 'http://www.phpmag.ru/'
    );

    /**
     * ArrayAccess implementation
     */
    public function offsetExists($offset)
    {
        return isset($this->options[$offset]);
    }

    public function offsetGet($offset )
    {
        return $this->options[$offset];
    }

    public function offsetSet($offset, $value )
    {
        $this->options[$offset] = $value;
    }

    public function offsetUnset($offset )
    {
        unset($this->options[$offset]);
    }
}

$config = new Config();
if(isset($config['uri'])) { // offsetExists() is called internally
    printf('URI: %s ', $config['uri']);   // offsetGet()
}
$config['username'] = 'vic';                    // offsetSet()
printf('Username: %s', $config['username']);

unset($config['uri']);                          // offsetUnset()
if(!isset($config['uri'])) {
    echo 'Offset deleted..';
}

// Output:
// URI: http://www.phpmag.ru/
// Username: vic
// Offset deleted..
</pre>
<p><a name="serializable">&nbsp;</a><br />
<strong>The Serializable Interface</strong></p>
<p>This is the last of predefined interfaces, and is actually quite a simple one (if you are familiar with data serialization). If you want your object to control its serialization/unserialization process you can either use magic methods <a href="http://ru.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep">__sleep()</a>/<a href="http://ru.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep">__wakeup()</a> or, more explicitly, just to implement the <a href="http://ru.php.net/manual/en/class.serializable.php">Serializable</a> interface:</p>
<pre name="code" class="php">
Serializable {
    /* Methods */
    abstract public string serialize( void )
    abstract public mixed unserialize( string $serialized )
}
</pre>
<p>Here is trivial example:</p>
<pre name="code" class="php">
class Item implements Serializable
{
    protected $title = null;

    public function __construct($title)
    {
        $this->title = $title;
    }

    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Serializable implementation
     */
    public function serialize()
    {
        return serialize(array($this->title));
    }

    public function unserialize($serialized )
    {
        list($title) = unserialize($serialized);
        // this method is invoked as constructor, if you need to use
        // default constructor, invoke it manually:
        $this->__construct($title);
    }

}

$serialized = serialize(new Item('milk'));
$obj = unserialize($serialized);
printf('Title: %s ', $obj->getTitle()); // Title: milk
</pre>
<p>That&#8217;s about it! If you liked the article, consider <a href="http://feeds2.feedburner.com/php-addicted">subscribing to RSS</a>, so that you can follow up the incoming SPL tutorials.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=qXNrwqLRVJ0:zsvWgx41fXs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=qXNrwqLRVJ0:zsvWgx41fXs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=qXNrwqLRVJ0:zsvWgx41fXs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=qXNrwqLRVJ0:zsvWgx41fXs:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=qXNrwqLRVJ0:zsvWgx41fXs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=qXNrwqLRVJ0:zsvWgx41fXs:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=qXNrwqLRVJ0:zsvWgx41fXs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=qXNrwqLRVJ0:zsvWgx41fXs:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/qXNrwqLRVJ0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/08/02/php5-predefined-interfaces/</feedburner:origLink></item>
		<item>
		<title>Zend Framework: dynamically change view script</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/bFSuD-G7RE4/</link>
		<comments>http://www.phpmag.ru/2009/07/31/zend-framework-dynamically-change-view-script/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 13:55:47 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=731</guid>
		<description><![CDATA[Rendering view script for particular controller action is really easy. Indeed, thanks to (enabled by default) ViewRenderer helper, scripts are auto-loaded: renderer searches script directory(ies) for a view script called CONTROLLER_NAME/ACTION_NAME.SCRIPT_EXTENSION once found, view is auto-rendered. 
However, sometimes it&#8217;s not what you want, instead you need to render some other view depending on some internal [...]]]></description>
			<content:encoded><![CDATA[<p>Rendering view script for particular controller action is really easy. Indeed, thanks to (enabled by default) ViewRenderer helper, scripts are auto-loaded: renderer searches script directory(ies) for a view script called <code>CONTROLLER_NAME/ACTION_NAME.SCRIPT_EXTENSION</code> once found, view is auto-rendered. </p>
<p>However, sometimes it&#8217;s not what you want, instead you need to render some other view depending on some internal criteria. For example, you may want to render some custom error displaying view. So, if we are positive on what we want, let me show you how to do it:</p>
<pre name="code" class="php">
class TestController extends Zend_Controller_Action
{
    /**
     * test/index.phtml would be rendered by default
     * @return void
     */
    public function indexAction()
    {
        // render test/foo.phtml
        $this->_helper->viewRenderer('foo');

        // render bar/foo.phtml to the default response segment, without using a
        // controller view script subdirectory ("test" in this case):
        // so you may use scripts from other controllers
        $this->_helper->viewRenderer('bar/foo', null, true);

        // now render the script, as previous calls do not render anything,
        // they are just used so that default script is swapped and not rendered:
        $this->render('foo');
        // OR
        $this->render('bar/foo', null, true);
    }
}
</pre>
<p>Please, note that you do not need to provide view extension (foo but not foo.phtml or any extension you happen to use for your views) &#8211; what renderer expects is action name, and we simply swapping the current action. Internally, direct() method is called when you update view renderer, which in turn is proxy for setRender():</p>
<pre name="code" class="php">
// allows you to set any of scriptAction, responseSegment,
// and noController in one pass.
setRender($action = null, $name = null, $noController = false)
</pre>
<p>So, you may use </p>
<pre name="code" class="php">
$this->_helper->viewRenderer->setRender('foo');
</pre>
<p>to change current view, but this form is less common, as it requires more typing <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
NB: If you need more info on ViewRenderer there&#8217;s no better place but <a href="http://framework.zend.com/manual/en/zend.controller.actionhelpers.html">ZF Manual</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=bFSuD-G7RE4:bKff0LDhVWM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=bFSuD-G7RE4:bKff0LDhVWM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=bFSuD-G7RE4:bKff0LDhVWM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=bFSuD-G7RE4:bKff0LDhVWM:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/php-addicted?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=bFSuD-G7RE4:bKff0LDhVWM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=bFSuD-G7RE4:bKff0LDhVWM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=bFSuD-G7RE4:bKff0LDhVWM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=bFSuD-G7RE4:bKff0LDhVWM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/bFSuD-G7RE4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2009/07/31/zend-framework-dynamically-change-view-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2009/07/31/zend-framework-dynamically-change-view-script/</feedburner:origLink></item>
	<item><title>Google API Translate, реализация / Web-разработка / Хабрахабр [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/nGB3keZ8_fA/</link><category>tranlation google api</category><dc:creator>farazdagi</dc:creator><pubDate>Thu, 11 Jun 2009 13:21:34 PDT</pubDate><guid isPermaLink="false">http://habrahabr.ru/blogs/webdev/61678/</guid><description>Kewl example of implementation&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/nGB3keZ8_fA" height="1" width="1"/&gt;</description><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/tranlation" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/google" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/api" />
      </rdf:Bag>
    </taxo:topics><feedburner:origLink>http://habrahabr.ru/blogs/webdev/61678/</feedburner:origLink></item><item><title>MySQL: how to drop multiple tables using single query [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/m7UZ3T_mVNw/</link><category>mysql</category><dc:creator>farazdagi</dc:creator><pubDate>Wed, 04 Mar 2009 15:21:18 PST</pubDate><guid isPermaLink="false">http://www.phpmag.ru/2009/03/05/mysql-how-to-drop-multiple-tables-using-single-query/</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/mysql" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/m7UZ3T_mVNw" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.phpmag.ru/2009/03/05/mysql-how-to-drop-multiple-tables-using-single-query/</feedburner:origLink></item><item><title>Проект ВААЛ. Контент-анализ. История метода. [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/g1USyMequR0/content.php</link><category>recommendation engine</category><dc:creator>farazdagi</dc:creator><pubDate>Mon, 02 Mar 2009 17:03:15 PST</pubDate><guid isPermaLink="false">http://www.vaal.ru/cont/content.php</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/recommendation" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/engine" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/g1USyMequR0" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.vaal.ru/cont/content.php</feedburner:origLink></item><item><title>Collaborative Filtering Resources [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/R5kBmJdmzcc/CollaborativeFiltering.html</link><category>collaborative filtering resources</category><dc:creator>farazdagi</dc:creator><pubDate>Mon, 02 Mar 2009 17:00:05 PST</pubDate><guid isPermaLink="false">http://www.adastral.ucl.ac.uk/~junwang/CollaborativeFiltering.html#code</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/resources" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/R5kBmJdmzcc" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.adastral.ucl.ac.uk/~junwang/CollaborativeFiltering.html#code</feedburner:origLink></item><item><title>Paul Perry - Automated Collaborative Filtering in SQL [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/bBHotCg0ybc/acf_sql.asp</link><category>collaborative filtering</category><dc:creator>farazdagi</dc:creator><pubDate>Mon, 02 Mar 2009 16:57:06 PST</pubDate><guid isPermaLink="false">http://www.paulperry.net/notes/acf_sql.asp</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/bBHotCg0ybc" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.paulperry.net/notes/acf_sql.asp</feedburner:origLink></item><item><title>Vogoo - Web Site Personalization &amp; Collaborative Filtering [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/fH9MBaKkeGc/index.php</link><category>collaborative filtering php</category><dc:creator>farazdagi</dc:creator><pubDate>Mon, 02 Mar 2009 16:56:47 PST</pubDate><guid isPermaLink="false">http://www.vogoo-api.com/index.php</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/php" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/fH9MBaKkeGc" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.vogoo-api.com/index.php</feedburner:origLink></item><item><title>Collaborative Filtering Resources [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/D-TKDdWakec/cf.asp</link><category>collaborative filtering</category><dc:creator>farazdagi</dc:creator><pubDate>Mon, 02 Mar 2009 16:56:28 PST</pubDate><guid isPermaLink="false">http://www.paulperry.net/notes/cf.asp</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/D-TKDdWakec" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.paulperry.net/notes/cf.asp</feedburner:origLink></item><item><title>NEWS | COllaborative Filtering Engine [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/l2TYMcHZPXc/</link><category>collaborative filtering</category><dc:creator>farazdagi</dc:creator><pubDate>Mon, 02 Mar 2009 16:55:01 PST</pubDate><guid isPermaLink="false">http://eecs.oregonstate.edu/iis/CoFE/</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/l2TYMcHZPXc" height="1" width="1"/&gt;</description><feedburner:origLink>http://eecs.oregonstate.edu/iis/CoFE/</feedburner:origLink></item><item><title>Taste Documentation [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/iJSOC2FuFO4/</link><category>java collaborative filtering</category><dc:creator>farazdagi</dc:creator><pubDate>Sun, 01 Mar 2009 07:08:38 PST</pubDate><guid isPermaLink="false">http://taste.sourceforge.net/</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/java" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/iJSOC2FuFO4" height="1" width="1"/&gt;</description><feedburner:origLink>http://taste.sourceforge.net/</feedburner:origLink></item><item><title>Collaborative filtering - Wikipedia, the free encyclopedia [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/vmnYZ1Q58xM/Collaborative_filtering</link><category>collaborative filtering</category><dc:creator>farazdagi</dc:creator><pubDate>Sun, 01 Mar 2009 07:08:29 PST</pubDate><guid isPermaLink="false">http://en.wikipedia.org/wiki/Collaborative_filtering</guid><description>Wikipedia definition&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/vmnYZ1Q58xM" height="1" width="1"/&gt;</description><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/collaborative" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/filtering" />
      </rdf:Bag>
    </taxo:topics><feedburner:origLink>http://en.wikipedia.org/wiki/Collaborative_filtering</feedburner:origLink></item><item><title>In the Woods - 15 CSS Tricks That Must be Learned [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/QPaLEfjNbUk/</link><category>css tips</category><dc:creator>farazdagi</dc:creator><pubDate>Wed, 11 Feb 2009 17:02:05 PST</pubDate><guid isPermaLink="false">http://blog.themeforest.net/general/15-css-tricks-that-must-be-learned/</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/css" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/tips" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/QPaLEfjNbUk" height="1" width="1"/&gt;</description><feedburner:origLink>http://blog.themeforest.net/general/15-css-tricks-that-must-be-learned/</feedburner:origLink></item><item><title>CSS Code Snippets : 15 Wicked Tricks | DevSnippets [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/4PEtCFGOFzI/css-code-snippets-15-wicked-tricks.html</link><category>css tips</category><dc:creator>farazdagi</dc:creator><pubDate>Wed, 11 Feb 2009 17:01:55 PST</pubDate><guid isPermaLink="false">http://devsnippets.com/reviews/css-code-snippets-15-wicked-tricks.html</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/css" />
        <rdf:li rdf:resource="http://delicious.com/farazdagi/tips" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/4PEtCFGOFzI" height="1" width="1"/&gt;</description><feedburner:origLink>http://devsnippets.com/reviews/css-code-snippets-15-wicked-tricks.html</feedburner:origLink></item><item><title>Java Programming Notes [del.icio.us]</title><link>http://feedproxy.google.com/~r/php-addicted/~3/SSeKPje5sQY/</link><category>java</category><dc:creator>farazdagi</dc:creator><pubDate>Wed, 11 Feb 2009 16:53:26 PST</pubDate><guid isPermaLink="false">http://leepoint.net/notes-java/</guid><taxo:topics xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
      <rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:li rdf:resource="http://delicious.com/farazdagi/java" />
      </rdf:Bag>
    </taxo:topics><description>&lt;img src="http://feeds.feedburner.com/~r/php-addicted/~4/SSeKPje5sQY" height="1" width="1"/&gt;</description><feedburner:origLink>http://leepoint.net/notes-java/</feedburner:origLink></item></channel>
</rss>
