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

<channel>
	<title>Paul Osman &#187; PHP</title>
	<atom:link href="http://blog.eval.ca/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.eval.ca</link>
	<description>Thoughts on Software and Other Things</description>
	<lastBuildDate>Wed, 07 Jul 2010 18:56:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Wrapping C++ Classes in a PHP Extension</title>
		<link>http://blog.eval.ca/2009/04/21/wrapping-c-classes-in-a-php-extension/</link>
		<comments>http://blog.eval.ca/2009/04/21/wrapping-c-classes-in-a-php-extension/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 13:51:33 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://eval.ca/?p=91</guid>
		<description><![CDATA[I have a tutorial at the Zend Developer Zone called Wrapping C++ Classes in a PHP Extension. It walks you through writing a simple PHP extension that wraps a class written in C++. This is a useful thing to be able to do, especially when exposing an already existing library&#8217;s API to PHP userland scripts, [...]]]></description>
			<content:encoded><![CDATA[<p>I have a tutorial at the <a href="http://devzone.zend.com">Zend Developer Zone</a> called <a href="http://devzone.zend.com/article/4486-Wrapping-C-Classes-in-a-PHP-Extension">Wrapping C++ Classes in a PHP Extension</a>. It walks you through writing a simple PHP extension that wraps a class written in C++. This is a useful thing to be able to do, especially when exposing an already existing library&#8217;s API to PHP userland scripts, which seems like a fairly common task.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2009/04/21/wrapping-c-classes-in-a-php-extension/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Bad Signs &#8211; PHP&#8217;s &#8220;Shut Up&#8221; (@) Operator</title>
		<link>http://blog.eval.ca/2009/01/04/bad-signs-phps-shut-up-operator/</link>
		<comments>http://blog.eval.ca/2009/01/04/bad-signs-phps-shut-up-operator/#comments</comments>
		<pubDate>Sun, 04 Jan 2009 03:22:21 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rants]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=40</guid>
		<description><![CDATA[Derick Rethans has a post about PHP&#8217;s &#8220;shut-up&#8221; operator (@) and why it should be avoided. He outlines a fairly common debugging scenario and gives some &#8220;under-the-hood&#8221; explanations on why that particular operator sucks. I couldn&#8217;t agree more (that it should be avoided) and I want to go further and talk about something that has [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://derickrethans.nl">Derick Rethans</a> has a <a href="http://derickrethans.nl/five_reasons_why_the_shutop_operator_@_should_be_avoided.php">post</a> about PHP&#8217;s &#8220;shut-up&#8221; operator (@) and why it should be avoided. He outlines a fairly common debugging scenario and gives some &#8220;under-the-hood&#8221; explanations on why that particular operator sucks. I couldn&#8217;t agree more (that it should be avoided) and I want to go further and talk about something that has always bugged me about that operator. In my opinion, it&#8217;s a hackish, band-aid fix to a much larger, much more worrisome problem: horrendous API design.</p>
<p>First, a disclaimer. I know that there are some historical reasons for a lot of these things (i.e. Exceptions not appearing until PHP5) but that doesn&#8217;t change the current reality. Consider for instance filesystem functions in the standard extension:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$lines</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/tmp/file.txt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If the file &#8220;/tmp/file.txt&#8221; does not exist, depending on your php.ini settings (because display_errors should always be &#8216;Off&#8217; on production systems), you may get something similar to the following output:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">Warning: file(/tmp/file.txt) [function.file]: failed to open stream: No such file or directory in /path/to/your/docroot/test.php on line 3</pre></div></div>

<p>Now the proper thing to do of course would be to verify up front that the file exists and is readable with a call to <a href="http://php.net/is_readable">is_readable()</a> or something similar, but imagine this is a case where there is no way to determine ahead of time if a warning or error will be generated (Derick mentions silencing network errors with <a href="http://php.net/stream_socket_client">stream_socket_client()</a> as one example). In this case, you might be tempted to use the shut-up operator and depend on the return value as the one true way to see if something was succesful or not.</p>
<p>Now compare this with what languages like Python (for example) do, If you were to write similar code in Python:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">fp = <span style="color: #008000;">file</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/tmp/file.txt&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>If the file did not exist, you&#8217;ll get an IOError which, if left uncaught, will result in the following being written to standard error:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">Traceback (most recent call last):
  File &quot;test.py&quot;, line 1, in &lt;module&gt;
IOError: [Errno 2] No such file or directory: '/tmp/test.txt'</pre></div></div>

<p>The difference here of course is that an IOError can be caught, ignored or whatever best suits your needs. It&#8217;s a part of the language, the API is not just spewing out garbage to standard output or standard error. More importantly, having a function (or technically a constructor) like file() throw an exception follows a consistent design philosophy whereas PHP&#8217;s error system always leaves me guessing or consulting the docs.</p>
<p>I guess what I&#8217;m saying is that I think the shut-up operator is just one of those signs that PHP is suffering from some serious cruft and I don&#8217;t think those kinds of things bode well for a language.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2009/01/04/bad-signs-phps-shut-up-operator/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP is Lazy</title>
		<link>http://blog.eval.ca/2008/10/30/php-is-lazy/</link>
		<comments>http://blog.eval.ca/2008/10/30/php-is-lazy/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 20:10:54 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=36</guid>
		<description><![CDATA[Last week I started reading Extending and Embedding PHP. I really like extending scripting languages for a number of reasons, most of all because it&#8217;s a great way to learn about the more esoteric features of a language. So far I&#8217;ve discovered two neat things about PHP that made me smile, so I thought I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I started reading <a href="http://www.amazon.ca/Extending-Embedding-PHP-Sara-Golemon/dp/067232704X/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1225346121&#038;sr=8-1">Extending and Embedding PHP</a>. I really like extending scripting languages for a number of reasons, most of all because it&#8217;s a great way to learn about the more esoteric features of a language. So far I&#8217;ve discovered two neat things about PHP that made me smile, so I thought I&#8217;d share them here.</p>
<h3>Copy on Write</h3>
<p>In an effort to save CPU cycles, PHP uses an optimization strategy called &#8220;Copy on Write&#8221;. Basically what this means is that variable data isn&#8217;t copied until it needs to be. Using an example similar to the one found in the book:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">50</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$b</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$a</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$b</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span></pre></div></div>

<p>
At the first line, the variable $a is created and memory is allocated for it. When we set $b to equal $a however, you might think that the data in $a is copied to $b. PHP doesn&#8217;t actually copy the data until the 3rd line when $b is incremented by 5. The value in this is that data is not copied unnecessarily. If, for some reason, we took out the 3rd line and $b was never modified after the initial assignment, the data would actually never have to be copied.
</p>
<h3>Return Value Used?</h3>
<p>The second, admittedly more surprising thing I learned was that PHP provides internal functions a parameter called <code>return_value_used</code> whose value can be inspected to determine whether the return value being prepared by the function is actually being saved or not. Imagine you have a function that does some heavy crunching to compute a return value, and a caller (for some reason beyond us) does this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #339933;">...</span>
myextension_compute_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">...</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>In other words, they call the function but don&#8217;t store the return value. Well, being a thoughtful internal function author, you can check to see that <code>return_value_used</code> evaluates to false and just skip doing any work, saving CPU cycles and time, like so:
</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">PHP_FUNCTION<span style="color: #009900;">&#40;</span>myextension_compute_something<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>return_value_used<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// some fancy but expensive algorithm</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
        RETURN_DOUBLE<span style="color: #009900;">&#40;</span>some_value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        RETURN_NULL<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2008/10/30/php-is-lazy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZendCon 2008 &#8211; Day 2</title>
		<link>http://blog.eval.ca/2008/09/18/zendcon-2008-day-2/</link>
		<comments>http://blog.eval.ca/2008/09/18/zendcon-2008-day-2/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 18:23:37 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[zendcon08]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=33</guid>
		<description><![CDATA[Harold Goldberg, the CEO of Zend Technologies, started the day off with a talk called &#8220;Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP Applications&#8221;. The talk was basically a run-down of how PHP is doing out there. (Answer: Fairly well!). There were a few case studies of larger companies using PHP (and [...]]]></description>
			<content:encoded><![CDATA[<p>Harold Goldberg, the CEO of Zend Technologies, started the day off with a talk called &#8220;Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP Applications&#8221;. The talk was basically a run-down of how PHP is doing <i>out there</i>. (<small>Answer: Fairly well!</small>). There were a few case studies of larger companies using PHP (and of course Zend products) and a few reports / surveys / etc. Nothing particularly groundbreaking but it was good to start the day feeling pumped about being a PHP programmer&#8230;</p>
<p>Later on I attended &#8220;Tiery-Eyed&#8221;, a talk given by a Zend employee, Kevin Schroeder on &#8230; you guessed it, tiered application development. It was pretty decent, Kevin walked the audience through the creation of a micro-blogging application using a variety of different backend tiers. I left with an urge to create the smallest application I could think off with one SOAP backend, one XML-RPC backend and one REST backend.</p>
<p>The highlight of the day was Sara Goleman&#8217;s talk on PHP Extension Writing. This was the most in-depth of the talks I attended and despite a few technical problems, the talk went smoothly. It was pretty broad but still managed to be quite inspiring.</p>
<p>The day ended with a reception in the exhibit hall. Free drinks and food is never a bad way to end a day&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2008/09/18/zendcon-2008-day-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZendCon 2008 &#8211; Day 1</title>
		<link>http://blog.eval.ca/2008/09/16/zendcon-2008-day-1/</link>
		<comments>http://blog.eval.ca/2008/09/16/zendcon-2008-day-1/#comments</comments>
		<pubDate>Tue, 16 Sep 2008 19:32:51 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[zendcon08]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=31</guid>
		<description><![CDATA[Well yesterday was day one of ZendCon 2008. Actually, the conference proper started today, yesterday was just tutorials.


So far I&#8217;m pretty impressed. I attended the PHP Developer Best Practices tutorial in the morning and the Quality Assurance in PHP Projects tutorial in the afternoon.
The Best Practices tutorial was a little broad and most of it [...]]]></description>
			<content:encoded><![CDATA[<p>Well yesterday was day one of ZendCon 2008. Actually, the conference proper started today, yesterday was just tutorials.
</p>
<p>
So far I&#8217;m pretty impressed. I attended the <a href="http://www.zendcon.com/ZendCon08/public/schedule/detail/95">PHP Developer Best Practices</a> tutorial in the morning and the <a href="http://www.zendcon.com/ZendCon08/public/schedule/detail/204">Quality Assurance in PHP Projects</a> tutorial in the afternoon.</p>
<p>The Best Practices tutorial was a little broad and most of it was focused on topics that were pretty common / basic. I&#8217;m not sure exactly what I wanted to get out of it, but for somebody who already uses an SCM system, who already tests (although not as much as I should) and writes api documentation it wasn&#8217;t the most informative tutorial.
</p>
<p>Sebastian Bergmann&#8217;s QA tutorial was excellent. Of course, as the primary author of <a href="http://phpunit.de/">PHPUnit</a>, I assumed Sebastian would know what he was talking about and I was right. He offered a really good, in depth look at <a href="http://phpunit.de/">PHPUnit</a> and covered some of the newer features. He also covered <a href="http://selenium.openqa.org/">Selenium</a> and specifically Selenium RC in quite a bit of detail. </p>
<p>Looking forward to more sessions&#8230; the day of tutorials was a great start, can&#8217;t wait to see what the conference proper has to offer.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2008/09/16/zendcon-2008-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using YAML with the Zend Framework</title>
		<link>http://blog.eval.ca/2008/02/18/using-yaml-with-the-zend-framework/</link>
		<comments>http://blog.eval.ca/2008/02/18/using-yaml-with-the-zend-framework/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 18:23:18 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=29</guid>
		<description><![CDATA[One of the many great components provided by the Zend Framework is Zend_Config. In a nutshell, this component allows you to access configuration data (from a file, array, etc) through a nested object property based interface. Out of the box, the component supports working with XML and INI files via the Zend_Config_Ini and Zend_Config_Xml Config [...]]]></description>
			<content:encoded><![CDATA[<p>One of the many great components provided by the <a href="http://framework.zend.com">Zend Framework</a> is <a href="http://framework.zend.com/manual/en/zend.config.html">Zend_Config</a>. In a nutshell, this component allows you to access configuration data (from a file, array, etc) through a nested object property based interface. Out of the box, the component supports working with XML and INI files via the <a href="http://framework.zend.com/manual/en/zend.config.adapters.ini.html">Zend_Config_Ini</a> and <a href="http://framework.zend.com/manual/en/zend.config.adapters.xml.html">Zend_Config_Xml</a> Config adapters.</p>
<p>If you&#8217;re familiar with frameworks like <a href="http://www.rubyonrails.org/">Ruby on Rails</a> or <a href="http://www.symfony-project.org/">Symfony</a> however, you may notice that <a href="http://www.yaml.org/">YAML</a> support is missing. This is mostly because there is no one YAML parsing library for PHP. If you are willing to introduce another dependency to your application however, there is a really easy way to use <a href="http://spyc.sourceforge.net/">Spyc</a> to bridge YAML and Zend_Config. One of the nice things about the Zend_Config component is that it can take data right out of a PHP array (as opposed to an XML or INI file). This gives us quite a lot of flexibility, especially considering that Spyc returns parsed YAML data as a PHP array. Armed with this knowledge, the solution becomes really, really simple:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Config.php'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'spyc.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$configFile</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;config.yml&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Config<span style="color: #009900;">&#40;</span>Spyc<span style="color: #339933;">::</span><span style="color: #004000;">YAMLLoad</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$confFile</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Remarkably simple isn&#8217;t it? Now, given the YAML config file:</p>

<div class="wp_syntax"><div class="code"><pre class="yaml" style="font-family:monospace;"> webhost: www.example.com
 database: 
     adapter: pdo_mysql
     host: db.example.com
     username: dbuser
     password: secret
     dbname: mydatabase</pre></div></div>

<p>The above PHP code will create a config object that can then be used like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">print</span> <span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">webhost</span><span style="color: #339933;">;</span>        <span style="color: #666666; font-style: italic;">// prints 'www.example.com'</span>
<span style="color: #b1b100;">print</span> <span style="color: #000088;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">database</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">host</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// prints 'db.example.com'</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2008/02/18/using-yaml-with-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Letting the masses decide&#8230;</title>
		<link>http://blog.eval.ca/2008/01/08/letting-the-masses-decide/</link>
		<comments>http://blog.eval.ca/2008/01/08/letting-the-masses-decide/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 06:54:22 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=27</guid>
		<description><![CDATA[
Sho Kuwamoto has been doing some excellent work on implementing improved pluralization support for PHP, Ruby on Rails and AppleScript. When I put together a quick solution for this in PHP, I couldn&#8217;t help but think that there might be some missing special cases or what have you. Well, Sho has now put together a [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://kuwamoto.org/">Sho Kuwamoto</a> has been doing some excellent work on implementing improved pluralization support for PHP, Ruby on Rails and AppleScript. When I put together a <a href="/articles/php-pluralize">quick solution</a> for this in PHP, I couldn&#8217;t help but think that there might be some missing special cases or what have you. Well, Sho has now put together a <a href="http://kuwamoto.org/2008/01/04/mob-intelligence-please-feed-the-pluralizer/">feeder app</a> for the pluralizer. What a neat experiment in collaborative web production! <a href="http://kuwamoto.org/2008/01/04/mob-intelligence-please-feed-the-pluralizer/">Go on and give it a try.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2008/01/08/letting-the-masses-decide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perforce Knowledge Base Launched</title>
		<link>http://blog.eval.ca/2007/11/04/perforce-knowledge-base-launched/</link>
		<comments>http://blog.eval.ca/2007/11/04/perforce-knowledge-base-launched/#comments</comments>
		<pubDate>Sun, 04 Nov 2007 10:21:59 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[SCM]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=23</guid>
		<description><![CDATA[In case you missed the announcement, the Perforce Knowledge Base is now available. Click here for more information about the technology driving the site. 
]]></description>
			<content:encoded><![CDATA[<p>In case you missed the announcement, the Perforce Knowledge Base is now <a href="http://kb.perforce.com/">available</a>. Click <a href="http://www.perforce.com/perforce/conferences/us/2007/presentations/kbpresentation.pdf">here</a> for more information about the technology driving the site. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2007/11/04/perforce-knowledge-base-launched/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Smarty with the Zend Framework</title>
		<link>http://blog.eval.ca/2007/05/15/using-smarty-with-the-zend-framework/</link>
		<comments>http://blog.eval.ca/2007/05/15/using-smarty-with-the-zend-framework/#comments</comments>
		<pubDate>Tue, 15 May 2007 19:15:22 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=19</guid>
		<description><![CDATA[
So it appears that the Zend Framework is approaching a 1.0 release, which is very exciting. The last time I worked with the ZF, I found the capabilities of the Zend_View class to be a little bit limited. Luckily, somebody has written a tutorial on using the Smarty template engine with the Zend Framework. Read [...]]]></description>
			<content:encoded><![CDATA[<p>
So it appears that the <a href="http://framework.zend.com">Zend Framework</a> is approaching a 1.0 release, which is very exciting. The last time I worked with the ZF, I found the capabilities of the Zend_View class to be a little bit limited. Luckily, somebody has written a tutorial on using the <a href="http://smarty.php.net">Smarty</a> template engine with the Zend Framework. Read more about it <a href="http://devzone.zend.com/node/view/id/2028">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2007/05/15/using-smarty-with-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Pluralize Method</title>
		<link>http://blog.eval.ca/2007/03/03/php-pluralize-method/</link>
		<comments>http://blog.eval.ca/2007/03/03/php-pluralize-method/#comments</comments>
		<pubDate>Sat, 03 Mar 2007 19:06:41 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.paulosman.com/?p=17</guid>
		<description><![CDATA[I recently found myself wanting a rails-esque pluralize function like that found in the Rails Inflector class. After inspecting the Rails implementation, and playing around a bit, I was able to get a PHP version working as a Smarty variable modifier. Thank goodness for the rails version, I have no idea how I would go [...]]]></description>
			<content:encoded><![CDATA[<p>I recently found myself wanting a rails-esque pluralize function like that found in the Rails Inflector class. After inspecting the Rails implementation, and playing around a bit, I was able to get a PHP version working as a Smarty variable modifier. Thank goodness for the rails version, I have no idea how I would go about listing all the various kinds of singular / plural nouns. Where would one go for a list of those kinds of things?</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MyClass 
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> conditionallyPluralize<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$string</span><span style="color: #339933;">,</span> <span style="color: #000088;">$count</span> <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$count</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span>
            <span style="color: #b1b100;">return</span> MyClass<span style="color: #339933;">::</span><span style="color: #004000;">pluralize</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$string</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$string</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> pluralize<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$string</span> <span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000088;">$plural</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(quiz)$/i'</span><span style="color: #339933;">,</span>               <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1zes</span>&quot;</span>   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/^(ox)$/i'</span><span style="color: #339933;">,</span>                <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1en</span>&quot;</span>    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/([m|l])ouse$/i'</span><span style="color: #339933;">,</span>          <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1ice</span>&quot;</span>   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(matr|vert|ind)ix|ex$/i'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1ices</span>&quot;</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(x|ch|ss|sh)$/i'</span><span style="color: #339933;">,</span>         <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1es</span>&quot;</span>    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/([^aeiouy]|qu)y$/i'</span><span style="color: #339933;">,</span>      <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1ies</span>&quot;</span>   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/([^aeiouy]|qu)ies$/i'</span><span style="color: #339933;">,</span>    <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1y</span>&quot;</span>     <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(hive)$/i'</span><span style="color: #339933;">,</span>               <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1s</span>&quot;</span>     <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(?:([^f])fe|([lr])f)$/i'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1</span><span style="color: #006699; font-weight: bold;">$2ves</span>&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/sis$/i'</span><span style="color: #339933;">,</span>                  <span style="color: #0000ff;">&quot;ses&quot;</span>     <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/([ti])um$/i'</span><span style="color: #339933;">,</span>             <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1a</span>&quot;</span>     <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(buffal|tomat)o$/i'</span><span style="color: #339933;">,</span>      <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1oes</span>&quot;</span>   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(bu)s$/i'</span><span style="color: #339933;">,</span>                <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1ses</span>&quot;</span>   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(alias|status)$/i'</span><span style="color: #339933;">,</span>       <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1es</span>&quot;</span>    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(octop|vir)us$/i'</span><span style="color: #339933;">,</span>        <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1i</span>&quot;</span>     <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/(ax|test)is$/i'</span><span style="color: #339933;">,</span>          <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1es</span>&quot;</span>    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/s$/i'</span><span style="color: #339933;">,</span>                    <span style="color: #0000ff;">&quot;s&quot;</span>       <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'/$/'</span><span style="color: #339933;">,</span>                      <span style="color: #0000ff;">&quot;s&quot;</span>       <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$irregular</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'move'</span><span style="color: #339933;">,</span>   <span style="color: #0000ff;">'moves'</span>    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'sex'</span><span style="color: #339933;">,</span>    <span style="color: #0000ff;">'sexes'</span>    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'child'</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'children'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'man'</span><span style="color: #339933;">,</span>    <span style="color: #0000ff;">'men'</span>      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'person'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'people'</span>   <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$uncountable</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> 
	    <span style="color: #0000ff;">'sheep'</span><span style="color: #339933;">,</span> 
	    <span style="color: #0000ff;">'fish'</span><span style="color: #339933;">,</span>
	    <span style="color: #0000ff;">'series'</span><span style="color: #339933;">,</span>
	    <span style="color: #0000ff;">'species'</span><span style="color: #339933;">,</span>
	    <span style="color: #0000ff;">'money'</span><span style="color: #339933;">,</span>
	    <span style="color: #0000ff;">'rice'</span><span style="color: #339933;">,</span>
	    <span style="color: #0000ff;">'information'</span><span style="color: #339933;">,</span>
	    <span style="color: #0000ff;">'equipment'</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// save some time in the case that singular and plural are the same</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$string</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$uncountable</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$string</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// check for irregular singular forms</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$irregular</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$noun</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
	    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$string</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$noun</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span>
	        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$noun</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// check for matches using regular expressions</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$plural</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$pattern</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
	    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$pattern</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$string</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	        <span style="color: #b1b100;">return</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$pattern</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pattern</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$string</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$string</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Works like a charm!</p>
<p><b>EDIT:</b> <a href="http://kuwamoto.org/">Sho Kuwamoto</a> took this example and ran with it, creating a really robust and complete pluralization solution for PHP (and ActionScript!). Check out his improvements <a href="http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.eval.ca/2007/03/03/php-pluralize-method/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
