<?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>Mon, 06 Sep 2010 21:04:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<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>Vim 7.3 is out!!</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/oR8DieYV2i8/</link>
		<comments>http://www.phpmag.ru/2010/08/17/vim-7-3-is-out/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 13:07:07 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[cli]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=1085</guid>
		<description><![CDATA[Couple of days ago, Vim team released new version of their great text editor. Once I had a little time, that&#8217;s today, I upgraded all my boxes. There couple of new features that are particularly interesting: a) Persistent undo Small but nevertheless very useful addition. Basically, your undo lists are dumped into undo files allowing [...]]]></description>
			<content:encoded><![CDATA[<p>Couple of days ago, Vim team <a href="https://groups.google.com/group/vim_announce/browse_thread/thread/66c02efd1523554b">released</a> new version of their great text editor. Once I had a little time, that&#8217;s today, I upgraded all my boxes. There couple of new features that are particularly interesting:<br />
<span id="more-1085"></span></p>
<h3>a) Persistent undo</h3>
<p>Small but nevertheless very useful addition. Basically, your undo lists are dumped into undo files allowing you to undo/redo even if buffer is unloaded (or even if editor closed). Plus now you are able to undo even after buffer reload (this is separate feature actually).</p>
<p>To enable, add to your .vimrc:</p>
<pre name="code" class="bash">
set undofile
set undodir=/tmp
</pre>
<p>That will enable dumping undo lists into undofile, which will be located in /tmp folder.</p>
<h3>b) Arbitrary columns</h3>
<p>Main use for me is to highlight maximum line length. You could have similar functionality before, but now it is supported out of box:</p>
<pre name="code" class="bash">
" make sure that max lines are displayed
" (80 and 120 are from ZF Coding standards)
set colorcolumn=80,120
</pre>
<p>To update the color of the ruler use hl-ColorColumn. In our custom theme (based on <a href="http://dengmao.wordpress.com/2007/01/22/vim-color-scheme-wombat/">wombat</a>), I set color as:</p>
<pre name="code" class="bash">
hi ColorColumn guibg=#2d2d2d
</pre>
<h3>c) Relative line numbers</h3>
<p>Well, at first I though this kind of controversial feature, but once I tried to navigate inside document using it &#8211; I suppose I like this feature. In any case, not added to my .vimrc by default. I turn it manually:</p>
<pre name="code" class="bash">
:set rnu
</pre>
<p>and to get back to original line numbers:</p>
<pre name="code" class="bash">
:set nu
</pre>
<h3>d) Conceal text</h3>
<p>Well, this feature is mainly for syntax file writers, as it <em>might</em> make markup text more readable. I, honestly, haven&#8217;t enough incentive to dig into it any deeper, as I don&#8217;t really see how can I use it in my immediate work (I actually like to see all the markup).</p>
<h3>Conclusion</h3>
<p>Although 7.3 is a minor release, it is still the result of two-years of work, with a lot of issues fixed and several very cool additions.</p>
<h3>Couple of notes on installation</h3>
<p>On our <a href="http://4cinc.com/">4C&#8217;s development server</a> (running CentOS), I was able to compile 7.3 without any issues whatsoever. </p>
<p>While recently switching to Mac, I still program on my old Ubuntu box and updating the Vim installation didn&#8217;t work the first time I tried. I noticed that my Ubuntu installation needed <strong>xorg-dev</strong> and <strong>libgtk2.0-dev</strong> packages, once installed I was able to compile an complete the Vim&#8217;s installation.</p>
<p>Here is little script I use to compile and install Vim on CentOS (used it on Ubuntu as well):</p>
<pre name="code" class="php">
#!/bin/bash
export CONF_OPT_GUI='--enable-gui=gtk2'
export CONF_OPT_PYTHON='--enable-pythoninterp'
export CONF_OPT_MULTIBYTE='--enable-multibyte'
export CONF_OPT_FEAT='--with-features=huge'
export CONF_OPT_COMPBY='--with-compiledby="yourname@here.com'

make distclean
./configure $CONF_OPT_FEAT $CONF_OPT_MULTIBYTE $CONF_OPT_PYTHON $CONF_OPT_COMPBY $CONF_OPT_GUI
make
make install
</pre>
<p>Save it into extracted <strong>vim73</strong> directory (I prefer to use name &#8220;configure-my&#8221;), then simply source:</p>
<pre name="code" class="shell">
source configure-my
</pre>
<p>Hope that saves you some time and happy Viming!!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=oR8DieYV2i8:8mkgvOZEcRk: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=oR8DieYV2i8:8mkgvOZEcRk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=oR8DieYV2i8:8mkgvOZEcRk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=oR8DieYV2i8:8mkgvOZEcRk: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=oR8DieYV2i8:8mkgvOZEcRk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=oR8DieYV2i8:8mkgvOZEcRk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=oR8DieYV2i8:8mkgvOZEcRk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=oR8DieYV2i8:8mkgvOZEcRk:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/oR8DieYV2i8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2010/08/17/vim-7-3-is-out/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/08/17/vim-7-3-is-out/</feedburner:origLink></item>
		<item>
		<title>Subversion Gems: Sparse Directories</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/P1Oz_v05y3U/</link>
		<comments>http://www.phpmag.ru/2010/06/01/subversion-sparse-directories/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 14:41:20 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[PHP5]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=1041</guid>
		<description><![CDATA[Recently, I become involved in Zend Framework even more &#8211; this time not only developing using it (which I am doing for some 3 years now), but actually contributing back whenever I can. And I plan to dedicate even more hrs/week to work on this undoubtedly nice, yet complex piece of software. So, lyrics aside [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I become involved in Zend Framework even more &#8211; this time not only developing <em>using</em> it (which I am doing for some 3 years now), but actually <em>contributing</em> back whenever I can. And I plan to dedicate even more hrs/week to work on this undoubtedly nice, yet complex piece of software. </p>
<p>So, lyrics aside &#8211; today I had to learn new Subversion trick (the hard way), so I am writing it down here, in hope that it saves some other hacker time to play PacMan.</p>
<p><strong>Problem</strong>:<br />
I needed to checkout into single working copy all relevant (to me) parts of ZF repository. Not doing separate checkouts for the trunk, then branches, then incubator, but having single checkout of repo which I can keep up to date by simple</p>
<pre name="code" class="bash">
svn up</pre>
<p>directly from the root of working copy.</p>
<p>Now the problematic part: you never ever want to checkout whole ZF repository &#8211; need I mention that it is HUGE? So, what I actually wanted is to checkout the whole repo <em>excluding</em> some paths &#8211; such as lots of previous releases in tags/branches folders.<br />
<span id="more-1041"></span><br />
<strong>Solution</strong>:<br />
That&#8217;s where <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.sparsedirs.html">Sparse Directories chapter</a> from svn book comes handy.</p>
<p>I will not repeat what&#8217;s written there, as I doubt I can explain it better. Yet I would add couple of notes, that might be a time savers I was talking about:</p>
<p>First, as of Subversion 1.6 you can actually exclude directories <em>explicitly</em> (go on and actually read that chapter, to find out that 1.5 supports what they call implicit exclusion).</p>
<p>And second, if you are tempted to run</p>
<pre name="code" class="bash">
$ svn co http://framework.zend.com/svn/framework/standard zf-standard --depth immediates
</pre>
<p>it is  <strong>probably</strong> a bad idea. </p>
<p>In theory it should work like a charm, in practice on my Ubuntu box it takes for ever to bring those 4 immediate directories located in &#8220;standard&#8221; repo. I checked those directories with <strong>svn info</strong> and they have Depth attribute set (quite correctly) to &#8220;empty&#8221; &#8211; yet it takes a lot of network traffic and time to checkout them (once that&#8217;s done &#8211; <strong>svn up</strong> takes no time at all though). It takes so much time, as to make all this sparse directory magic not worth using. </p>
<p>Fortunately, there&#8217;s a work around: proceed one directory at a time, using &#8220;empty&#8221; as depth:</p>
<pre name="code" class="bash">
$ svn co http://framework.zend.com/svn/framework/standard zf-standard --depth empty
$ cd zf-standard
$ svn co http://framework.zend.com/svn/framework/standard/branches --depth empty
$ svn co http://framework.zend.com/svn/framework/standard/tags --depth empty
$ svn co http://framework.zend.com/svn/framework/standard/trunk --depth infinity
</pre>
<p>As you see, I made sure that <strong>trunk</strong> directory is fetched recursively. That&#8217;s because I work on trunk and need it in full.</p>
<p>Now let&#8217;s fetch some branch that we are interested in, while ignoring (and as such implicitly excluding) those that are too outdated to waste time and traffic on them. </p>
<p>Descend to <strong>zf-standard/branches</strong> directory of your newly created working copy and issue following command:</p>
<pre name="code" class="bash">
$ svn up release-1.10
</pre>
<p>As you don&#8217;t provide any depth specifiers &#8220;infinity&#8221; is assumed, and whole branch is fetched. Once that done, you can use your regular svn up/ci workflow &#8211; directory depth parameter is sticky, so you don&#8217;t have to worry about any directory that you didn&#8217;t fetch. Everything works as in normal checkouts, you just don&#8217;t have some of files (and in our case number of files tends to be 6-7 digit number) from your central repo.</p>
<p>Although I tend to <a href="http://github.com/farazdagi">git</a> more and more lately, subversion can still amaze me (after all these years!) <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=P1Oz_v05y3U:Jk7iSlnp7Yc: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=P1Oz_v05y3U:Jk7iSlnp7Yc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=P1Oz_v05y3U:Jk7iSlnp7Yc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=P1Oz_v05y3U:Jk7iSlnp7Yc: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=P1Oz_v05y3U:Jk7iSlnp7Yc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=P1Oz_v05y3U:Jk7iSlnp7Yc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=P1Oz_v05y3U:Jk7iSlnp7Yc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=P1Oz_v05y3U:Jk7iSlnp7Yc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/P1Oz_v05y3U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2010/06/01/subversion-sparse-directories/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/06/01/subversion-sparse-directories/</feedburner:origLink></item>
		<item>
		<title>DOS end of lines in Vim</title>
		<link>http://feedproxy.google.com/~r/php-addicted/~3/ZHNVWMSz6aY/</link>
		<comments>http://www.phpmag.ru/2010/03/28/dos-end-of-lines-in-vim/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 04:42:50 +0000</pubDate>
		<dc:creator>Victor Farazdagi</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tricks & Tips]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://www.phpmag.ru/?p=983</guid>
		<description><![CDATA[Sometimes I get annoying ^M chars when opening files using Vim &#8211; obviously it&#8217;s a DOS EOL which mixes the picture. The good place to seek for fixes and workarounds is Vim Wikia, which not only shows you what to do, but also gives you a brief background on what is going on (if you [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes I get annoying ^M chars when opening files using Vim &#8211; obviously it&#8217;s a DOS EOL which mixes the picture.</p>
<p>The good place to seek for fixes and workarounds is <a href="http://vim.wikia.com/wiki/Change_end-of-line_format_for_dos-mac-unix">Vim Wikia</a>, which not only shows you what to do, but also gives you a brief background on what is going on (if you are unaware).</p>
<p>I am generally happy with dos2unix utility to convert files, but sometimes it seems to be unable to fix the issue. In such situations I do a simple search/replace, right inside of Vim (in ex mode):<br />
<span id="more-983"></span></p>
<pre name="code" class="bash">
:%s/\r/\r/g
</pre>
<p>In my opinion it is real magic &#8211; it replaces carriage returns (CR) with line-feeds (LF), but the actual command reads: do a replacement of \r with \r, right?<br />
Well, Vim is clever enough to look into file-type, and if it&#8217;s unix &#8211; it presumes that first \r can be either CR or LF, while second (replacement) is always LF <img src='http://www.phpmag.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>If it doesn&#8217;t work for you check your buffer&#8217;s file type:</p>
<pre name="code" class="bash">
:set ff?
</pre>
<p>I only recently moved to Vim, but start loving it for such small but extremely useful gems.</p>
<p>Should you have any questions/suggestions &#8211; hit me back on <a href="http://twitter.com/farazdagi">my tweeter</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/php-addicted?a=ZHNVWMSz6aY:cb33j780Hdo: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=ZHNVWMSz6aY:cb33j780Hdo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=ZHNVWMSz6aY:cb33j780Hdo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=ZHNVWMSz6aY:cb33j780Hdo: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=ZHNVWMSz6aY:cb33j780Hdo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=ZHNVWMSz6aY:cb33j780Hdo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/php-addicted?a=ZHNVWMSz6aY:cb33j780Hdo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/php-addicted?i=ZHNVWMSz6aY:cb33j780Hdo:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/php-addicted/~4/ZHNVWMSz6aY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.phpmag.ru/2010/03/28/dos-end-of-lines-in-vim/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:origLink>http://www.phpmag.ru/2010/03/28/dos-end-of-lines-in-vim/</feedburner:origLink></item>
		<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 &#8220;unwise&#8221; characters, such as [...]]]></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 &#8220;unwise&#8221; characters, such as spaces, &#8220;{&#8220;, &#8220;}&#8221;, &#8220;^&#8221; 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 &#8220;unwise&#8221; 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 &#8220;%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, [...]]]></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 &#8220;bundled&#8221; 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>7</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 [...]]]></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 &#8220;[warn] _default_ VirtualHost overlap on port 443,<br />
the first has precedence&#8221;, 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>7</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 SeekableIterator 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><del datetime="2010-05-29T12:00:16+00:00">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)</del>. 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;

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

    /**
     * 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()
    {
        $this->innerIterator->next();
        $this->fetch();
    }

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

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

    /**
     * Move forward until the condition defined in accept() is met
     */
    protected function fetch()
    {
        while($this->innerIterator->valid()) {
            if($this->accept()) {
                return;
            }
            $this->innerIterator->next();
        }
    }
}

$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 70, 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() and rewind() methods, they call additional method fetch():</p>
<pre name="code" class="php">
protected function fetch()
{
    while($this->innerIterator->valid()) {
        if($this->accept()) {
            return;
        }
        $this->innerIterator->next();
    }
}
</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://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>Note: Thanks to <a href="http://www.phpmag.ru/2009/08/05/exploring-spl-interfaces/#comment-825">P18X</a> for spotting the bug in original code &#8211; fixed now.</p>
<p><a name="seekable">&nbsp;</a><br />
<strong>The SeekableIterator 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 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 &#8220;flatten&#8221; 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 &#8220;as is&#8221;, 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><del datetime="2010-05-29T12:00:16+00:00">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,</del> 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.ibm.com/developerworks/library/os-php-designptrns/">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>
<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>7</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>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>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>
