<?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>Code Fury &#187; PHP Development</title>
	<atom:link href="http://codefury.net/category/php-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://codefury.net</link>
	<description>One programmer's formatted output stream</description>
	<lastBuildDate>Sat, 31 Dec 2011 22:20:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>GetSparks.org Beta Released, Big Changes</title>
		<link>http://codefury.net/2011/05/getsparks-org-beta-released-big-changes/</link>
		<comments>http://codefury.net/2011/05/getsparks-org-beta-released-big-changes/#comments</comments>
		<pubDate>Fri, 06 May 2011 13:00:30 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[respository]]></category>
		<category><![CDATA[sparks]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=442</guid>
		<description><![CDATA[Note: CodeIgniter Reactor 2.0.2 has a bug in it&#8217;s core Loader class that breaks package config file loading (and sparks, sadly). It&#8217;s recommended that you use 2.0.1 OR the latest at https://bitbucket.org/ellislab/codeigniter-reactor OR make the following change in your 2.0.2 installation: https://bitbucket.org/ellislab/codeigniter-reactor/changeset/c461483c8ca0 . The last option is the best. It took a month longer than [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2011%2F05%2Fgetsparks-org-beta-released-big-changes%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2011%2F05%2Fgetsparks-org-beta-released-big-changes%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Note:</strong> <em>CodeIgniter Reactor 2.0.2 has a bug in it&#8217;s core Loader class that breaks package config file loading (and sparks, sadly). It&#8217;s recommended that you use 2.0.1 <strong>OR</strong> the latest at <a href="https://bitbucket.org/ellislab/codeigniter-reactor">https://bitbucket.org/ellislab/codeigniter-reactor</a> <strong>OR</strong> make the following change in your 2.0.2 installation: <a href="https://bitbucket.org/ellislab/codeigniter-reactor/changeset/c461483c8ca0">https://bitbucket.org/ellislab/codeigniter-reactor/changeset/c461483c8ca0</a> . The last option is the best.</em></p>
<p>It took a month longer than expected, but we&#8217;ve finally released the Beta version of <a href="http://getsparks.org">GetSparks.org</a>, the <a href="http://codefury.net/2011/03/introducing-codeigniter-sparks/">repository and package manager system for CodeIgniter</a>.</p>
<p>Here&#8217;s the very minimum of what you need to know:</p>
<ol>
<li>A spark.info file is now required in every spark</li>
<li>You should upgrade your spark system as soon as possible (just follow the usual installation instructions)</li>
<li>If you submitted a spark prior to the beta, we&#8217;ve normalized all version numbers to x.x.x. So curl 1.0 becomes curl 1.0.0. Check the site.</li>
</ol>
<p>The alpha was all about weeding out fundamental issues in the initial repo and system. The big problems we had were:</p>
<ul>
<li>Some spark developers wanted the ability to specify dependencies</li>
<li>There was no difference between a repository tag and the spark version — They had to be in sync</li>
<li>Users wanted RSS feeds for latest spark overall, and latest versions of individual sparks</li>
<li>There was no way to rate a spark</li>
<li>There was no way to tell if your spark was going to be accepted by the spark processor prior to submission</li>
</ul>
<p>We knocked those out and a little more with the beta. Going forward:</p>
<p>All sparks must have a spark.info file at the root. <a href="http://getsparks.org/spec-format">Details are here.</a></p>
<ul>
<li> You can now specify spark dependencies in spark.info</li>
<li> The spark manager will now install a spark and all of its dependencies</li>
<li> The spark manager can now self-update</li>
<li> All spark versions must be in x.x.x format. Sparks released prior to the beta had their version numbers change in the system (tags remained the same though)</li>
<li>Versions and tags are now decoupled. The version is pulled from spark.info</li>
<li>Sparks are now ratable via a simple &#8220;Love&#8221;, &#8220;Like&#8221;, or &#8220;Hate&#8221; rating</li>
<li><a href="http://getsparks.org/packages/spark-sdk/versions/HEAD/show">A Spark-SDK is available</a> to spark developers in order to validate their sparks prior to submission</li>
</ul>
<p><strong>It is necessary that you upgrade your spark manager with the release.</strong> The current version is 0.0.4. You can upgrade by removing the &#8216;tools&#8217; folder from your webroot and following the same installation instructions at: <a href="http://getsparks.org/install">http://getsparks.org/install</a></p>
<p>Send any issues to <a href="mailto:ohcrap@getsparks.org">ohcrap@getsparks.org</a>!</p>
<p>Now that the structural changes have been made, we can focus on tightening up the spark system&#8217;s feature set. This is what you see in the coming weeks:</p>
<ul>
<li>The ability to install sparks in configurations where the application folder is not in your webroot (possible now, but not automated)</li>
<li>The ability for sparks to act more like modules — ie, sparks will be able to override core libraries and more</li>
</ul>
<p>Also, we plan to:</p>
<ul>
<li>Put a news section on the site (long overdue)</li>
<li> Configure our notification system better so its emails don&#8217;t land in your spam folder</li>
</ul>
<p>And don&#8217;t forget the ultimate goal: <strong>Integration in CodeIgniter Reactor.</strong></p>
<p>Check out the beta and ping the team with any problems! ohcrap@getsparks.org</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2011/05/getsparks-org-beta-released-big-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why PHP Was a Ghetto</title>
		<link>http://codefury.net/2011/04/why-php-was-a-ghetto/</link>
		<comments>http://codefury.net/2011/04/why-php-was-a-ghetto/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 12:14:08 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Soap Box]]></category>
		<category><![CDATA[ghetto]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=389</guid>
		<description><![CDATA[Note: I wrote this over a month ago, but decided not to publish it until now. I was talking with the Co-founder of a pretty cool start-up in DUMBO the other day about why the non-PHP development world generally has such disdain for PHP and the community surrounding it. He brought up an interesting point [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2011%2F04%2Fwhy-php-was-a-ghetto%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2011%2F04%2Fwhy-php-was-a-ghetto%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Note:</strong> I wrote this over a month ago, but decided not to publish it until now.</p>
<p>I was talking with the Co-founder of a <a href="http://www.saaspire.com/">pretty cool start-up</a> in <a href="http://dumbonyc.com/">DUMBO</a> the other day about why the non-PHP development world generally has such disdain for PHP and the community surrounding it. He brought up an interesting point that stuck with me, largely because I hadn&#8217;t heard it before.</p>
<p>If you&#8217;re unaware of the usual beef most developers have with PHP, it tends to revolve around:</p>
<ol>
<li>Ugly syntax</li>
<li>Lack of some necessary features that other languages have (prior to 5.3, namespacing, closures)</li>
<li>Inconsistent function naming, usage, and other quirks</li>
<li>Mix of procedural and OO-ness</li>
<li>The fact that 80-90% of PHP projects are probably gigantic piles of shit</li>
</ol>
<p>But his problem with PHP was a little different. He didn&#8217;t say the actual language was poor — he said it was the general culture surrounding the language, which is usually iconified by a language&#8217;s founder, that seems to encourage bad practices. That is, PHP code bases tend to be hacky and unmaintainable.</p>
<p>The concept that the community surrounding a language or framework embodies an author&#8217;s philosophy seems to be true. He brought up Ruby and <a href="http://en.wikipedia.org/wiki/Yukihiro_Matsumoto">Matz</a>. Matz wanted a language that was easy to read and write, and enhanced programmer productivity. Don&#8217;t Ruby developers seem to harp on rapid application development and the elegance of their language?</p>
<p>Then <a href="http://en.wikipedia.org/wiki/David_Heinemeier_Hansson">DHH</a> and the Rails came up. Then <a href="http://www.python.org/~guido/">Guido</a> and Python. So I thought: What about <a href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf">Rasmus</a>?</p>
<p>Rasmus Lerdorf is an interesting figure. He created the original version of PHP, continues to contribute, is widely considered a demigod in the community and the authority on almost anything PHP. He <a href="http://www.urbandictionary.com/define.php?term=rasmussed">steals masses of attendees at conferences</a>, <a href="http://yahoo.com">gets hired by big internet places</a>, and garners the respect of everyone despite one glaring property: Rasmus represents what most non-PHP developers hate about PHP.</p>
<p>Rasmus generally promotes abstention from using frameworks, and the use of PHP as more of a templating language. To him, this translates to raw speed and scalability (load-wise). To everyone else, this translates to piles of procedural spaghetti code, and unmaintainable projects. For roughly 10 years following the birth of PHP in 1995, this was how PHP projects were written.</p>
<p>But another issue cropped up:  In it&#8217;s pizza-faced adolescent years (pre-5.0), PHP gained a serious following among novices. The language has a fantastically low barrier to entry, so anyone could get started in 2 minutes by downloading some self-extracting *AMP stack for Windows. Additionally, the acceptance of the MVC paradigm hadn&#8217;t really occurred yet in web development. What do you get when you mix n00bs and a lack of best practices? Unmaintainable garbage. And that&#8217;s what proliferated.</p>
<p>Don&#8217;t get me wrong — there were some great PHP developers around, even back then. But like I said, unrefined n00b-sauce was all around. When cowboy PHP developers with no standards got together to build a project, it came out looking like PHPbb, PHPNuke, or some other gnarled mash of .php3 files. But can you singularly blame PHP developers? No! The other web language giants, ASP and Perl, were also gross as hell and promoting the same spaghetti-code practices.</p>
<p>So why does PHP get a bad rap? Because of its legacy. And most old-time PHP devs who have fled to Python, Ruby, and Java haven&#8217;t really looked back to see what kind of development has happened in the language since the introduction of MVC on the web. Additionally, there were super-outspoken critics like &#8220;Ruby guy&#8221; Zed Shaw complaining of developers with &#8220;PHP-Infected Brains&#8221;, and the distribution of <a href="http://www.rubyinside.com/holiday-fun-how-programming-language-fanboys-see-each-others-languages-2911.html">stuff like this on RubyInside</a>.</p>
<p><em>PHP was a ghetto.</em></p>
<p>But the development of frameworks like Zend and CodeIgniter have greatly pushed the language development into the right direction. In fact, it&#8217;s been pushed in the <em>opposite </em>direction of where Rasmus would probably like to see it. Check out the Zend or CodeIgniter frameworks and tell me it&#8217;s not some of the best documented, most well-written code you&#8217;ve seen.</p>
<p>When most developers learned Ruby, they were learning Rails and MVC  at the same time. PHP was in use for a full 10 years before that. So there really wasn&#8217;t a period of time when heinous Ruby was being written by novices. There was an established standard in place for Rails, and the barrier to entry was a much higher, typically keeping less experienced developers out.</p>
<p>The fact is, a PHP applications can be as well-written as an application in any other language, and probably have the additional advantage of speed. The widespread use of MVC-style development in the PHP world is a relatively recent phenomena though, and admittedly, we can probably thank Rails for it.</p>
<p>So what does PHP have going for it now?</p>
<ol>
<li>Standards (not universal, but generally a flavor of MVC for most projects, and little procedural crap)</li>
<li>A very low barrier to entry</li>
<li>Speed &amp; Scalability (maybe the best among script-based languages)</li>
<li>A great unit testing framework</li>
<li>Arguably the best documentation for any language</li>
</ol>
<p>Additionally, it&#8217;s behind some of the internet&#8217;s most influential websites and tools, like Facebook, Digg, Wikipedia, WordPress, Drupal, etc. I&#8217;d bet that having a solid understanding of it opens more doors for a developer than any other.</p>
<p>If you don&#8217;t agree with the above, comment on this post, or email me — I&#8217;d like to hear why you don&#8217;t think so.</p>
<p>I&#8217;m no PHP fanboy — in fact, I&#8217;m very language-agnostic. I write PHP more often because, you guessed it, people pay me to. So it all comes down to this:</p>
<p><em>If you are capable of making wise software design decisions, PHP is a great choice to build your web application with.<br />
</em></p>
<p>By the way, if I just convinced you to build your next webapp in PHP, check out CodeIgniter. <a href="http://codeigniter.com">It&#8217;s the lightweight, no magic, ultra fast framework for PHP</a>. When it comes to CodeIgniter, I am a fanboy.</p>
<p><strong>4/4 Edit</strong>: I&#8217;ll be presenting a tool I wrote in Perl called &#8216;<a href="https://github.com/katzgrau/chip">divvy</a>&#8216; tonight at <a href="http://www.meetup.com/hack-and-tell/">Hack and Tell</a> in NYC. Here&#8217;s a<a href="http://blip.tv/file/4739441"> video of a previous event</a> (about 10 minutes in) where a developer plugs in his laptop to reveal Windows XP on his desktop (strike 1.5) and then admits to being a &#8220;PHP Coder&#8221; (strike 4). Is it me, or can you feel the judgment in the air? Maybe it&#8217;s me.</p>
<p><em>On Twitter, I&#8217;m <a title="@_kennyk_" href="http://twitter.com/_kennyk_" target="_blank">@_kennyk_</a></em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2011/04/why-php-was-a-ghetto/feed/</wfw:commentRss>
		<slash:comments>91</slash:comments>
		</item>
		<item>
		<title>CodeIgniter 2.0 Released, User-Contributed Notes Coming</title>
		<link>http://codefury.net/2011/02/codeigniter-2-0-released-user-contributed-notes-coming/</link>
		<comments>http://codefury.net/2011/02/codeigniter-2-0-released-user-contributed-notes-coming/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 14:03:38 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=339</guid>
		<description><![CDATA[In my initial post after joining the CodeIgniter Reactor team (over Thanksgiving weekend &#8217;10), I went as far as to saying that you could hold me responsible for the quality of the CodeIgniter documentation. Here&#8217;s a universal truth: Documentation &#62; magic. CodeIgniter 2.0 was released last week, with an announcement on the EllisLab news feed. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2011%2F02%2Fcodeigniter-2-0-released-user-contributed-notes-coming%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2011%2F02%2Fcodeigniter-2-0-released-user-contributed-notes-coming%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>In my initial post after joining the CodeIgniter Reactor team (over Thanksgiving weekend &#8217;10), I went as far as to saying that you could hold me responsible for the quality of the CodeIgniter documentation. Here&#8217;s a universal truth: Documentation &gt; magic.</p>
<p>CodeIgniter 2.0 was released last week, with an announcement on the EllisLab news feed. The &#8220;Reactor&#8221; project is now considered to be &#8220;CodeIgniter&#8221;. All official forum references, downloads, and docs referring to CodeIgniter are referring to the project sitting here at <a target="_blank" href="https://bitbucket.org/ellislab/codeigniter-reactor">BitBucket</a>.</p>
<p>You can check out the lengthy change-log here: <a target="_blank" href="http://codeigniter.com/user_guide/changelog.html">http://codeigniter.com/user_guide/changelog.html</a></p>
<p>Version 2.0 was released while some big features were still in development (but not 100% ready for the limelight). My favorite upcoming feature (by no coincidence) is something I&#8217;m currently putting together: A user-contributed note system for the user guide.</p>
<p>Everyone who keeps a place in their heart for PHP (as hard as it may be at times) knows how helpful php.net is. It&#8217;s a single place for clear PHP documentation, code examples, and user-contributed notes.</p>
<p>Some would argue that the most helpful parts of the PHP docs are the notes that PHP developers contributed themselves. A long-time request for CodeIgniter has been to add something similar the user guide.</p>
<p>Since late December, I&#8217;ve worked been working on (and have pretty much completed) a full-featured versioned user-contributed notes system for the docs. You can the see the progress in the BitBucket &#8216;user-notes&#8217; branch:  <a target="_blank" href="https://bitbucket.org/ellislab/codeigniter-reactor/src/a6f52cbc8229">https://bitbucket.org/ellislab/codeigniter-reactor/src/a6f52cbc8229</a></p>
<p>The actual application used to host the notes is being developed at: <a target="_blank" href="https://bitbucket.org/katzgrau/ci-userguide-notes">https://bitbucket.org/katzgrau/ci-userguide-notes</a></p>
<p>And of course, some screenshots of notes in action:</p>
<p style="text-align: center;"><a target="_blank" href="http://codefury.net/wp-content/uploads/2011/02/user-note-displayed.png"><img class="size-medium wp-image-341 aligncenter" title="CodeIgniter User Notes" src="http://codefury.net/wp-content/uploads/2011/02/user-note-displayed-300x155.png" alt="" width="300" height="155" /></a></p>
<p>Adding a note looks like a clone of the contribution page at PHP.net:</p>
<p><a target="_blank" href="http://codefury.net/wp-content/uploads/2011/02/user-note-create.png"><img class="aligncenter size-medium wp-image-344" title="Create a CodeIgniter User Note" src="http://codefury.net/wp-content/uploads/2011/02/user-note-create-300x155.png" alt="" width="300" height="155" /></a></p>
<p>You can check out a live instance of a user guide with the new system here (link not guaranteed to work into the future!): <a target="_blank" href="http://ci-notes-exp.katzgrau.com/user_guide/libraries/benchmark.html">http://ci-notes-exp.katzgrau.com/user_guide/libraries/benchmark.html</a></p>
<p>Like I mentioned, the notes are versioned. That means notes can be promoted from older versions to newer versions, and they can be pruned from newer versions as they become obsolete, without affecting the old. Best of all, the user_guide will still come distributed in HTML format with the framework. The notes are pulled in and loaded via some simple Javascript.</p>
<p>I&#8217;ve always thought the CodeIgniter docs were the best among any framework that I&#8217;ve come across. I think this&#8217;ll take them even further.</p>
<p>Look for them at the end of Q1 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2011/02/codeigniter-2-0-released-user-contributed-notes-coming/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CodeIgniter/PHP + IIS + MySQL + MSSQL: It Works!</title>
		<link>http://codefury.net/2011/01/codeigniter-php-iis-mysql-mssql/</link>
		<comments>http://codefury.net/2011/01/codeigniter-php-iis-mysql-mssql/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 13:41:48 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[mssql]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sqlsrv]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=316</guid>
		<description><![CDATA[There are a lot of people out there who call themselves &#8220;LAMP&#8221; developers — short for Linux, Apache, MySQL, PHP. That&#8217;s the standard configuration for production PHP applications. Recently, I ended up having to build a CodeIgniter application on Windows, IIS, Mysql+MS-SQL, and PHP. Sound like there are bound to be issues? You bet, and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2011%2F01%2Fcodeigniter-php-iis-mysql-mssql%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2011%2F01%2Fcodeigniter-php-iis-mysql-mssql%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>There are a lot of people out there who call themselves &#8220;LAMP&#8221; developers — short for Linux, Apache, MySQL, PHP. That&#8217;s the standard configuration for production PHP applications. Recently, I ended up having to build a CodeIgniter application on <strong>W</strong>indows<strong>, I</strong>IS, Mysql+<strong>M</strong>S-SQL, and <strong>P</strong>HP. Sound like there are bound to be issues? You bet, and it especially hurts because now I&#8217;m a real-live WIMP developer.</p>
<p>And what made it even more interesting was that due to constraints, I had to develop the application in Ubuntu and deploy to Windows for production.</p>
<p>Please keep in mind that I didn&#8217;t opt for this setup by choice. The servers to be used were already in place, and well, it just had to be this way. I&#8217;d imagine this unholy mix can be found on server farms somewhere around the seventh or eighth circle of hell.</p>
<p><em><strong>Anyway, the point of this post is to document a few &#8220;gotchas&#8221; that came up along the way.</strong></em> At this point I should say that application is now happily humming along in production. I knew from the start that mixing all of the above would be a headache, but luckily, things worked out without sapping too much time. I should also say this before I start: Thanks to some great work done by others over the past 2 years, this setup was actually possible.</p>
<p><strong>Gotcha #1: PHP and MSSQL on Ubuntu</strong></p>
<p>Thank god this was so easy. In order to use the standard database functions like mssql_connect, mssql_query, etc, all I needed to do within my existing LAMP installation was run:</p>
<pre>$ sudo apt-get install php5-sybase</pre>
<p>And sh-bang, I could connect to SQL Server without an issue. From CodeIgniter, I set the database to use mssql as my driver, and I was home free.</p>
<p><strong>Gotcha #2: PHP and MSSQL on Windows</strong></p>
<p>For years, forums and IRC rooms were filled with hopeless requests to get these two to mix. In 2008, Microsoft wrote a driver to help PHP developers seamlessly connect to SQL Server. For Win-PHP installations, just install this gem:<a href="http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&amp;FamilyID=80e44913-24b4-4113-8807-caae6cf2ca05"> http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&amp;FamilyID=80e44913-24b4-4113-8807-caae6cf2ca05</a> . Also, read up on the docs.</p>
<p>That driver uses a different API then the regular PHP mssql_* functions. In fact, it uses sqlsrv_* functions instead. So CodeIgniter can&#8217;t work with it out of the box. Luckily I found an excellent 2 and 1/2 year-old post by a guy who wrote the CodeIgniter driver to work with the Microsoft drivers. Just download the code, and drop it into system/database/drivers. Read up here: <a href="http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/">http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/</a></p>
<p>One thing you will have to do to make it work with the latest version of CodeIgniter is create a dummy function in sqlsrv_driver.php. Just drop &#8216;function db_set_charset() { }&#8217; somewhere in the class declaration.</p>
<p><em>As a side note, that driver would make a great addition to <a href="http://codefury.net/2010/12/codeigniter-reactor/">CodeIgniter Reactor</a>.</em></p>
<p><strong>Gotcha #3: mssql vs. sqlsrv<br />
</strong></p>
<p>Notice that I had to use different drivers for connecting to SQL Server between Ubuntu and Windows. This is why it&#8217;s handy to use some sort of database abstraction class like the one that comes with CodeIgniter. All I had to do to switch between drivers when I deployed to the new environment was edit the configuration.</p>
<p>Also, query result fields that are fetched using PHP&#8217;s mssql driver come back as strings. The Windows sqlsrv driver gets fancy and hands back field values as objects. Your code won&#8217;t have to change for the most part, but beware that MSSQL &#8216;datetime&#8217; fields come back as native <a href="http://php.net/manual/en/class.datetime.php">PHP DateTime</a> objects using sqlsrv_*, not strings. In the code, I ended up doing something like: <em>if($date instanceof DateTime) return $date-&gt;format(&#8230;); else return $date;</em></p>
<p><em><strong>Edit: </strong>Commenter <a href="http://blogs.msdn.com/b/brian_swan">Brian Swan</a> and Twitter user <a href="http://www.juokaz.com/">Juozas Kaziukėnas</a> have pointed out that the sqlsrv_ PHP driver will take a boolean &#8216;ReturnDatesAsStrings&#8217; option in sqlsrv_connect() that specifies whether datetime fields come back as strings or objects. More info is here: <a href="http://msdn.microsoft.com/en-us/library/ee376928%28v=sql.90%29.aspx">http://msdn.microsoft.com/en-us/library/ee376928%28v=sql.90%29.aspx</a>. Thanks guys!</em></p>
<p><strong>Gotcha #4: File Permissions and Logging</strong></p>
<p>As the author of WPSearch, a Wordress search plugin which does heavy work with the filesystem, I can say that the number one cause of broken installations is that the permissions are too strict. On Windows, files can appear to be 777 when viewing them via FTP, but on the Windows end, they are set as &#8216;Read Only&#8217;, or &#8216;Archive&#8217;. This throws a serious wrench into things.</p>
<p>When I first deployed to the production server, all I would get for responses was a blank page. Worst of all, the log wasn&#8217;t writing anything. After a trace through the CodeIgniter bootstrap, I found that the application died when the logging class was loaded. If your application&#8217;s logging threshold is set to write anything, and the logging fails, the application might just crap-out. This is different behavior than I&#8217;ve seen on linux, where you just won&#8217;t see logs appear in the logging directory, but the overall application still works fine.</p>
<p>Just turn off logging to make sure that empty responses aren&#8217;t the result of file permission errors.</p>
<p><strong>Gotcha #5: No .htaccess Fo&#8217; You!</strong></p>
<p>I hadn&#8217;t known that I needed to drop the final application into an IIS instance from the start. I learned about that 1 day prior to the launch. Before that, I though I&#8217;d be rollin&#8217; on Windows/Apache. Wrong!</p>
<p>IIS doesn&#8217;t use silly .htaccess files, which I had only used for standard URL rewriting/prettified URLs. I was forced to decide between converting the .htaccess to an IIS web.config file, or just ditch the prettified URLs. Since it was a small application, I went with the latter. Here&#8217;s a nice StackOverflow thread discussing a translation though: <a href="http://stackoverflow.com/questions/702526/translating-an-apache-htaccess-file-to-an-iis-web-config">http://stackoverflow.com/questions/702526/translating-an-apache-htaccess-file-to-an-iis-web-config</a></p>
<p><em><strong>Edit:</strong> Juozas had some comments here too: &#8220;@_kennyk_  about .htaccess vs web.config &#8211; you can actually import .htaccess in IIS URL Rewrite section.&#8221;</em></p>
<p><strong>Gotcha #6: 2 Databases, 1 Application</strong></p>
<p>This is more of a CodeIgniter issue. For this application I had to lookup data in a MySQL database, then use some of that information to pull rows from a MSSQL database. The hurdle revolves around having two concurrent database connections open in CodeIgniter.</p>
<p>You can&#8217;t really load the database in traditional CodeIgniter style, like $this-&gt;load-&gt;database(), or by autoloading it. Something like this doesn&#8217;t work:</p>
<pre>$this-&gt;load-&gt;database('mysql-group-name');
# Do Stuff with mysql
$this-&gt;load-&gt;database('mssql-group-name');
# Do Stuff with mssql</pre>
<p>Instead, you have to ask CodeIgniter to hand you back the actual database object with each connection. It&#8217;s a good idea to encapsulate each within the models where you&#8217;re using them. Do something like this:</p>
<pre>class SomeMySQLModel extends Model {
  # the mysql db instance
  private $_db = NULL;

  function SomeMySQLModel() {
    $this-&gt;_db = $this-&gt;load-&gt;database('mysql-group', TRUE);
  }
}</pre>
<pre>class SomeMSSQLModel extends Model {
   # the mssql db instance
   private $_db = NULL;

   function SomeMSSQLModel() {
     $this-&gt;_db = $this-&gt;load-&gt;database('mssql-group', TRUE);
   }
 }</pre>
<p><strong>Gotcha #7: Mysterious lag time</strong></p>
<p>IIS can exhibit some odd behavior regarding response times. When I was initially testing the application on my SliceHost dev server, I was getting pretty speedy responses in about ~100ms (keep in mind that I was connecting to both MSSQL and MySQL across the internet, not locally).</p>
<p>But when I moved to production, requests were taking 6 seconds each. Confused, I thought there must be some sort of bottleneck in the application. I used CodeIgniter&#8217;s profiling and benchmarking classes to investigate. I benchmarked the MySQL and MSSQL connections, queries, and overall application execution time.</p>
<p>The app was reporting that it was finishing responses within 100ms. So where was this strange delay coming from?</p>
<p>I then thought there might be some sort of redirect loop going on. From the shell, I ran:</p>
<pre>$ time curl -v [address]</pre>
<p>And something else became apparent. The full content of the page would come back, but there was a 6 second lag before the connection would finally close. After a little research on the Google, it turns out I&#8217;m not the only one who&#8217;s observed this with PHP and IIS: <a href="http://www.google.com/search?q=iis+php+response+lag">http://www.google.com/search?q=iis+php+response+lag</a></p>
<p>I would like to say I figured out why IIS was being so lame, but the in-house net-admin suggested moving the application to another production server on hand, where the issue mysteriously dissappeared. At that point, everyone was happy, so I didn&#8217;t look into it any further. I <em>did</em> read about some resolutions regarding DNS settings, and skipping name resolutions in the db configurations. That might have been it, but I&#8217;ll never know.</p>
<p><strong>Recap:</strong></p>
<p>Don&#8217;t willingly try this. That being said, everything worked out much better than it could have, and there were relatively easy solutions to the bumps along the way. If you have to put together a project like this, I highly suggest using some sort of database abstraction (or a framework like CodeIgniter), and planning out how you&#8217;ll work out URLs, permissions, and differing environments. Thinking these things over will save you a lot of time, and hopefully leave the stakeholders a whole lot happier.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2011/01/codeigniter-php-iis-mysql-mssql/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>CodeIgniter Reactor? What’s Going On?</title>
		<link>http://codefury.net/2010/12/codeigniter-reactor/</link>
		<comments>http://codefury.net/2010/12/codeigniter-reactor/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 02:31:05 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=296</guid>
		<description><![CDATA[A couple of weeks ago, Derek Jones of EllisLabs announced that the CodeIgniter Core would officially be branched so a community-driven version of the framework could be created. This new branch will be called CodeIgniter Reactor. The plan, which was clarified today, is focused on allowing a select group of CI engineers to actively commit [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2010%2F12%2Fcodeigniter-reactor%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2010%2F12%2Fcodeigniter-reactor%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>A couple of weeks ago, <a href="http://ellislab.com/company/team/derek_jones/">Derek Jones of EllisLabs</a> announced that the <a href="http://codeigniter.com">CodeIgniter</a> Core would officially be branched so a community-driven version of the framework could be created. This new branch will be called <em>CodeIgniter Reactor</em>.</p>
<p>The plan, <a href="http://codeigniter.com/news/codeigniter_in_2011_reactor_core_uservoice/">which was clarified today</a>, is focused on allowing a select group of CI engineers to actively commit new features to the codebase, while taking feature requests via a uservoice forum. Over time, any proven, time-tested features in Reactor will be merged into the Core.</p>
<p>This announcement comes after a two year period of relatively few changes to CodeIgniter — something the community has had mixed feelings about. For some, it meant CodeIgniter would remain a remarkably stable platform to build on in contrast to frameworks like Cake or Kohana. For others, it meant CodeIgniter was probably dead.</p>
<p><strong>So is that why frameworks like Kohana, once a fork of CodeIgniter, exist?</strong></p>
<p>That, and also: A frustrating reality for many in the CodeIgniter community is that although it is the fastest, lightest MVC framework for PHP, it still lacks some important features. Many once-smitten CodeIgniter evangelists grew out of the framework and began looking for something that was more full featured. That is, they wanted an ORM, more libraries, more robust implementations of unit testing and caching, and a style of usage that actually conforms to the definition of MVC.</p>
<p><strong>Why does CodeIgniter still have such a loyal following if more full-featured frameworks are around?</strong></p>
<p>As mentioned, CodeIgniter is considered one of the fastest script-based frameworks available. It takes a “load only what you need” approach — something other platforms definitely don’t do. <a href="http://toys.lerdorf.com/">Rasmus Ledorf</a>, the original author of PHP and skeptic of PHP frameworks in general, has even singled out the framework as something he might actually use.</p>
<p><em>As a side note, while at Yahoo! I’ve had the chance to read into exactly why Rasmus doesn’t like MVC via the internal wiki pages that he wrote himself — and guess what, he’s right. But that’s a topic for another post.</em></p>
<p>The other big (if not <em>HUGE</em>) reason that CodeIgniter has remained popular is the documentation. You cannot find a framework with more clear or concise documentation. Of course, it’s easy to keep the docs current when the framework hasn’t changed for two years!</p>
<p><strong>So what the hell is going to happen with CodeIgniter Reactor?</strong></p>
<p>I’m one of the engineers on the project, and I’ll be clear that CodeIgniter Reactor <em>will</em> pick up where CodeIgniter left off. Although the official roadmap hasn’t been laid out just yet, you’ll find Reactor will still have a high level of dependability and outstanding documentation. <em>If Reactor’s docs fall into dismay, hold me personally responsible. I won’t let it happen.</em></p>
<p>There is a feature request forum for Reactor set up at <a href="http://codeigniter.uservoice.com/">UserVoice</a> — a place where CI users who want to suggest additions can go.</p>
<p>Of course, that doesn’t mean every feature suggestion, whether it’s the popular or not should actually be implemented. The Reactor team will make intelligent decisions about what and what not to change, remaining in line with the original principals of CodeIgniter: Light footprint, low barrier to entry.</p>
<p>If I had to underscore my own objectives in implementing new features, they are <em>speed, efficiency, and power</em>. That is:</p>
<ul>
<li>Does it belong in the framework?</li>
<li>Can this feature be built efficiently?</li>
<li>At the highest level of efficiency, will it be fast?</li>
<li>Is it comparably robust, and powerful in the face of similar features in other frameworks?</li>
</ul>
<p><strong> </strong></p>
<p><strong>A word to the skeptics:</strong></p>
<p>A <a href="http://twitter.com/davidjmemmett/status/10462351392251904">tweet I saw immediately following the Reactor Announcement</a> was “Death by bureaucracy is the fate for CodeIgniter shame … Good riddance, it never matured”. This really embodies the sentiment most users have about <em>other</em> frameworks. It’s arguably the fate that Kohana and Cake have seen.</p>
<p>What I’m saying is: stuff away the cynicism until the first quarter of 2011. You’re going to see a ton a positive changes in the framework, and CodeIgniter users will have plenty to brag about without sacrificing usability and documentation.</p>
<p>There are 6 engineers on the dev team — one who I know very well, and a few others who I’ve met just recently. In all honestly, I’ve been very impressed by everyone, and I couldn’t imagine anything but a bright future for the framework. The other devs are:</p>
<ul>
<li><a href="http://johncrepezzi.com">John Crepezzi</a></li>
<li><a href="http://funkatron.com/">Ed Finkler</a></li>
<li><a title="Great, informative site :)" href="http://www.markhuot.com/">Mark Huot</a></li>
<li><a href="http://kennymeyers.com/">Kenny Meyers</a></li>
<li><a href="http://philsturgeon.co.uk/">Phil Sturgeon</a></li>
</ul>
<p>Six developers can approach the “too many cooks” scenario, but I think you’d also have to recognize that CodeIgniter is supported by volunteers, and a project needs 5 or 6 people in order maintain consistently high activity when they’re generally working on it part-time.</p>
<p><strong>Okay, so now what:</strong></p>
<p>Over the next few weeks, the Reactor team will be getting organized and planning out the future of CodeIgniter. Check back here or at my <a href="http://twitter.com/_kennyk_">Twitter feed</a>, because I’ll definitely post a podcast outlining exactly what the Reactor team plans to do. Also, I tend to lurk around the IRC #codeigniter channel on freenode as _kennyk_ .</p>
<p>If you have any questions, comments, or general skepticism, comment below. I’m all-ears.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/12/codeigniter-reactor/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A Better WordPress Search with WPSearch 2.0.2.0</title>
		<link>http://codefury.net/2010/11/wpsearch-released-lives-change/</link>
		<comments>http://codefury.net/2010/11/wpsearch-released-lives-change/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 02:57:58 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Search Engine Development]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Wordpress Development]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=272</guid>
		<description><![CDATA[I&#8217;m definitely not the type to evangelize something I don&#8217;t think is useful. Ask friends of mine, and they&#8217;ll likely tell you how I went through phases where I endlessly promoted things like Notepad++ for Windows, Netbeans IDE (PHP), Sequel Pro, Gnome-Do, Thinkpads, Macbooks, Toy Story 3, iPod Touches, and Visual Studio &#8217;08. I just [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2010%2F11%2Fwpsearch-released-lives-change%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2010%2F11%2Fwpsearch-released-lives-change%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m definitely not the type to evangelize something I don&#8217;t think is useful. Ask friends of mine, and they&#8217;ll likely tell you how I went through phases where I endlessly promoted things like Notepad++ for Windows, Netbeans IDE (PHP), Sequel Pro, Gnome-Do, Thinkpads, Macbooks, Toy Story 3, iPod Touches, and Visual Studio &#8217;08. I just can&#8217;t help it. When I get excited about something, I have a hard time stfu-ing.</p>
<p>But <strong>holy crap</strong>. Let me tell you — if you think the WordPress default search sucks — as I did 2 years ago, <a href="http://wordpress.org/extend/plugins/wpsearch/">try WPSearch</a>. It&#8217;s (IMO) the second-most-useful plug-in that has ever existed for WordPress. It also has the slickest admin UI I&#8217;ve ever used in WordPress (a big thanks to JQuery and it&#8217;s plug-ins, of course).</p>
<p>I wrote WPSearch, and I 100% recommend it to anyone running something that isn&#8217;t a traditional WordPress blog. Run a recipe catalog? <strong>Use It!</strong> Review engine? <strong>Use it! </strong>Shopping engine? <strong>What the hell are you doing without my plug-in on your site? Your customers can&#8217;t find shit!</strong></p>
<p><strong>Fun scenario:</strong> Let&#8217;s imagine you sold laser printers on your site along with other computer peripherals, and every product page on your site had &#8220;[brand] [model] Printers&#8221; in it&#8217;s title, like &#8220;Dell 1100 Laser Printer&#8221;. If someone searched for &#8220;printers&#8221; with default WordPress search, they wouldn&#8217;t get those products back.</p>
<p>Does that scare you? It should.<a href="http://wordpress.org/extend/plugins/wpsearch/"> Get WPSearch now</a>. And if you don&#8217;t like it, tweet <strong>@_kennyk_</strong> and be brutally honest. I can take it.</p>
<p>Side note #1: When I wrote WPSearch, I was also trying to cash-in big time at a programming contest where the grand prize was a trip to RailsConf and the runner-up would get a set of steak knives (presumably to stab whoever won the grand prize).</p>
<p>Side note #2: Toy Story 3 is an intellectually provocative and introspective masterpiece!</p>
<p>Side note #3: Askimet is #1, but is tragically taken for granted</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/11/wpsearch-released-lives-change/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Best WordPress Search Plug-in: WPSearch 2</title>
		<link>http://codefury.net/2010/10/the-best-wordpress-search-plug-in-wpsearch-2/</link>
		<comments>http://codefury.net/2010/10/the-best-wordpress-search-plug-in-wpsearch-2/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 13:05:38 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Search Engine Development]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Wordpress Development]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=262</guid>
		<description><![CDATA[If you want to read about the background of the WPSearch Search plug-in for WordPress, read below. But if you just want the gist of this post, here it is: WPSearch is the best search plug-in for your WordPress blog. It is a stemming, stop-word blocking, fast, relevant, fulltext search for WordPress. There isn&#8217;t a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2010%2F10%2Fthe-best-wordpress-search-plug-in-wpsearch-2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2010%2F10%2Fthe-best-wordpress-search-plug-in-wpsearch-2%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you want to read about the background of the WPSearch Search plug-in for WordPress, read below. But if you just want the gist of this post, here it is:</p>
<p><strong>WPSearch is the best search plug-in for your WordPress blog</strong>. It is a stemming, stop-word blocking, fast, relevant, fulltext search for WordPress. <em>There isn&#8217;t a single plug-in in the WordPress repository that can do what it does</em>.</p>
<p>You can get it here: <a href="http://wordpress.org/extend/plugins/wpsearch/">http://wordpress.org/extend/plugins/wpsearch/</a> &#8212; or just install it through the WordPress plugin administration backend. Just search for WPSearch.</p>
<p>If you run any sort of monetized blog, you might be losing sales or readership if users can&#8217;t find what they need on your site. <a href="http://www.adotas.com/2010/09/on-site-search-the-other-white-meat/">According to Adotas, 43% of users hit the search box first</a>.</p>
<p><strong>Background:</strong></p>
<p>I&#8217;ll admit that I&#8217;ve been pretty vocal already about WordPress&#8217; lacking search functionality. I&#8217;ve been vocal about it for 2 years, and it was the original impetus to get this blog up and running. It was also the reason that I wrote wpSearch, the original version of WPSearch &#8212; the lucene-based search plug-in for WordPress. wpSearch was the first true fulltext search for WordPress, in my opinion.</p>
<p>But the problem with wpSearch was that it wasn&#8217;t highly engineered. I had written it for a programming contest, and I was on a tight deadline &#8212; and when projects are rushed, the quality of code goes down. And because of that, bugs made their way out of the woodwork over the next two years.</p>
<p>Consumed by college work and my job, I didn&#8217;t have much time to address those issues. In fact, I had declared wpSearch unsupported a year after it was released in 2009.</p>
<p>A year following that, <a href="http://pixelberry.co.nz/">Daniel Hay at Pixelberry in New Zealand</a> had requested that I add the ability of searching within a category for a client of his. That&#8217;s when WPSearch 2 development began.</p>
<p>I wanted to give wpSearch a full rewrite, and correct several mistakes I made with the first version:</p>
<ul>
<li>Rename it from wpSearch to WPSearch</li>
<li>Change the listing name in the WordPress repository to WP Search, so searches for &#8216;search&#8217; would bring it up</li>
<li>Follow and MVC pattern (it&#8217;s a complex plug-in)</li>
<li>Build a configurable search driver framework, so any driver could be written to search and index</li>
<li>Build better logging</li>
<li>Evangelize it to no end (wpSearch was barely promoted)</li>
<li>Give it a UI independent of the default WordPress stylesheets, and also make it stylish</li>
</ul>
<p>The biggest change is the configurable driver part. The free version of WPSearch contains a driver that uses Zend Lucene in the background. Any driver, however, can be written to work with WPSearch. Drivers for SOLR, sphinx, the Google Search Appliance, or name-your-own-search-product could be written.</p>
<p>I did that because PHP is not the best language to write a search engine in. Since Zend_Search_Lucene is the backend driver of the free version, there is an upper-bound of scalability on the plug-in. After all PHP is a scripting language, and I doubt Zend ever really imagined someone would make the ludicrous decision of indexing tens of thousands of posts in PHP. I found the breaking point to be about 20,000 docs. At that point, I ran into memory issues, slow mid-indexing optimizations, and slow first-hit (non-cached) searches.</p>
<p>So the point is that I poured everything I had into WPSearch 2, and I want to tell everyone about it. I did this project under the umbrella of OConf, my start-up, with business partner John Crepezzi. John&#8217;s an ex-engineer at Sun Microsystems, and he spends his days at Patch.com now. He also wrote the backend driver for WPSearch Pro, an alternate driver for WPSearch 2 which can handle up to 500,000 docs.</p>
<p>John and I gave a talk at Wordcamp NYC, where we officially launched WPSearch 2.The topic was on the default WordPress search, and why avoiding a remedy to it can lose you both readers and money. If you run a shopping engine, people can&#8217;t find your products. If you run a news site, readers can&#8217;t find your content.</p>
<p>If you don&#8217;t think people even use the search box &#8212; heads up, the advertising gurus at Adotas say <a href="http://www.adotas.com/2010/09/on-site-search-the-other-white-meat/">43% of users who find your site do</a>.</p>
<p>You can check it out here: <a href="http://wordpress.org/extend/plugins/wpsearch/">http://wordpress.org/extend/plugins/wpsearch/</a> . In it&#8217;s short time in the repository (about 9 days), it&#8217;s already had around 1,000 downloads, and I&#8217;ve had a lot of positive feedback coming in. I also dropped <a href="http://ma.tt/2009/07/acquia-searc/#comments">a comment about it on WordPress founder Matt Mullenweg&#8217;s site, where he mentioned a search product for Drupal</a>. Hopefully he&#8217;ll check it out and let me know what he thinks.</p>
<p>Check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/10/the-best-wordpress-search-plug-in-wpsearch-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Flushing CodeIgniter&#8217;s URI-based Cache (Part I)</title>
		<link>http://codefury.net/2009/12/flushing-codeigniters-uri-based-cache-part-i/</link>
		<comments>http://codefury.net/2009/12/flushing-codeigniters-uri-based-cache-part-i/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 04:49:33 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=152</guid>
		<description><![CDATA[CodeIgniter&#8217;s output caching mechanism &#8212; at least in my opinion &#8212; has limited usefulness. It can be used to cache the final payload sent to the user for a given number of minutes. But sometimes clearing the cache for all pages or a specific page can be useful, especially if keeping the user from seeing [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2009%2F12%2Fflushing-codeigniters-uri-based-cache-part-i%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2009%2F12%2Fflushing-codeigniters-uri-based-cache-part-i%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>CodeIgniter&#8217;s output caching mechanism &#8212; at least in my opinion &#8212; has limited usefulness. It can be used to cache the final payload sent to the user for a given number of minutes. But sometimes clearing the cache for all pages or a specific page can be useful, especially if keeping the user from seeing stale data is important.</p>
<p>This post will discuss what caching is, and how it is used in CodeIgniter. The next post will provide a few helper methods for clearing caches for specific pages (or really, URIs). I think this will make CI&#8217;s caching feature a lot more usable.</p>
<p>In a nutshell, this is how (and why) output caching is typically implemented:</p>
<p>Suppose we have a page at http://mysite.com/stats/website which loads and shows all the statistics about the users on my site, activity, files posted, etc. In other words, a lot of SQL queries (maybe 40 or so) and calculations go into this page. That takes significant time and resources.</p>
<p>Now imagine that this page is particularly popular. Maybe a heavily-read blog or bookmarking service links to your website, and you receive an unexpected burst in traffic. All of those page loads are re-running your calculations and queries, and that is consuming serious memory and CPU cycles. The number of requests your website can serve per-minute is now falling through the floor!</p>
<p>The idea of caching involves using the fact that our page probably doesn&#8217;t need calculate those statistics or run those queries every time. Perhaps gathering all of that data once an hour would suffice.</p>
<p>&#8220;Caching&#8221; involves generating the statistics page like we normally would, but saving a copy of the output we were going to send to the user for a certain amount of time. During that time period, everyone who requests that page will get the same page output that we generated x minutes ago.</p>
<p>After that time period passes, and we receive another page request, we recalculate the stats, and send them to the user. Of course, we&#8217;ll save the newer stats for a given amount of time for subsequent requests.</p>
<p>This basic caching &#8212; &#8220;page caching&#8221; &#8212; is the kind that CodeIgniter offers.</p>
<p>When you are inside a controller, you can tell CodeIgniter that you want to cache any requests to the current URI for <strong>n</strong> minutes. For that time period, you only want to send the output your are about to generate.</p>
<p>This is how it looks:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Stats <span style="color: #000000; font-weight: bold;">extends</span> Controller
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">function</span> website<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// 40 SQL Queries (Maybe a little overboard)</span>
    <span style="color: #666666; font-style: italic;">// Serious, ultra-precise calculations</span>
    <span style="color: #666666; font-style: italic;">// More intensive code that isn't good for fast page loads</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Tell CI you want to cache the output of this page for 10 minutes.</span>
    <span style="color: #666666; font-style: italic;">// This means that for the next 10 minutes, when CodeIgniter receives</span>
    <span style="color: #666666; font-style: italic;">// a request for stats/website, the CI system will not even consult this</span>
    <span style="color: #666666; font-style: italic;">// method or instantiate this controller. It will serve a static page containing</span>
    <span style="color: #666666; font-style: italic;">// the exact content that you output here.</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cache</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'stats/website'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</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>

<p>And that&#8217;s all you have to do! In this example, CodeIgniter&#8217;s output caching works great.</p>
<p>So then, what were the qualms I mentioned earlier?</p>
<p>Suppose we also cache user profile pages, which might be located at a URI similar to http://mysite.com/users/profile/kennyk. For whatever reason, we will assume that caching this page could be very beneficial due to heavy traffic on the site.</p>
<p>If a user profile is cached for 10 minutes, and a user updates his profile in some profile editing area, he will still see the older version of his profile page when he tries to view it. This can be confusing and inconvenient.</p>
<p>Other MVC frameworks (like Rails) handle this issue in a snap by allowing the developer to &#8220;sweep&#8221; caches at will. CodeIgniter does not offer any functionality similar to this.</p>
<p>My next post will document a cache helper I&#8217;ve whipped up to allow CodeIgniter to sweep caches for a given URI. Look out for &#8220;Flushing CodeIgniter&#8217;s URI-based Cache (Part II).&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2009/12/flushing-codeigniters-uri-based-cache-part-i/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Enable Site-Wide Profiling With CodeIgniter</title>
		<link>http://codefury.net/2009/11/enable-site-wide-profiling-with-codeigniter/</link>
		<comments>http://codefury.net/2009/11/enable-site-wide-profiling-with-codeigniter/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 18:35:10 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[site]]></category>
		<category><![CDATA[wide]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=121</guid>
		<description><![CDATA[A very cool part of CodeIgniter is its ability to give you the &#8216;profiling&#8217; information for page loads. That is, if you add: $this-&#62;output-&#62;enable_profiler&#40;true&#41;; In your controller before you load a view, CodeIgniter will give you information regarding how fast the page loaded, how many SQL queries executed, the content of each query, and the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2009%2F11%2Fenable-site-wide-profiling-with-codeigniter%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2009%2F11%2Fenable-site-wide-profiling-with-codeigniter%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>A very cool part of CodeIgniter is its ability to give you the &#8216;profiling&#8217; information for page loads. That is, if you add:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enable_profiler</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In your controller before you load a view, CodeIgniter will give you information regarding how fast the page loaded, how many SQL queries executed, the content of each query, and the running time of each query. This is incredibly useful when you are trying to debug your application, or simply see how quickly things are loading.</p>
<p>There&#8217;s only one problem: To enable profiling, that line of code above must be present. What if you want to profile several pages, or even your whole web application? In that case, you have to start thinking:</p>
<ul>
<li>I could put that line in the constructor of my controller, and then of of that controller&#8217;s methods will be profiled.</li>
<li>I could put that line in each method I want to profile.</li>
</ul>
<p>These methods start to get ugly. And of course, you don&#8217;t want to comment out each profiling line when you don&#8217;t need them.</p>
<p>My method to tackle this problem involves using CodeIgniter&#8217;s Hooks feature to enable or disable profiling for the entire web applications based on a value in the configuration file. In the end, I can turn on profiling for my entire website via a config value by setting it to true or false. This is my method:</p>
<p>1. Enable hooks in your CodeIgniter Application by going to config/config.php end setting the flag to true:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'enable_hooks'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #339933;">;</span></pre></div></div>

<p>2. Create a file in the config directory named <strong>hooks.php</strong> if it does not already exist. Inside it, place:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$hook</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'post_controller_constructor'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                                <span style="color: #0000ff;">'class'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ProfilerEnabler'</span><span style="color: #339933;">,</span>
                                <span style="color: #0000ff;">'function'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'EnableProfiler'</span><span style="color: #339933;">,</span>
                                <span style="color: #0000ff;">'filename'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'hooks.classes.php'</span><span style="color: #339933;">,</span>
                                <span style="color: #0000ff;">'filepath'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'hooks'</span><span style="color: #339933;">,</span>
                                <span style="color: #0000ff;">'params'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
                                <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>3. Create a folder in your application directory named <strong>hooks </strong>(If it does not already exist). Inside it, create a file named <strong>hooks.classes.php</strong>. Inside it, put:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ProfilerEnabler
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">function</span> EnableProfiler<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$CI</span> <span style="color: #339933;">=</span> <span style="color: #339933;">&amp;</span>get_instance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$CI</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enable_profiler</span><span style="color: #009900;">&#40;</span> config_item<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'enable_profiling'</span><span style="color: #009900;">&#41;</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>

<p>4. Finally, add this line to your application&#8217;s main configuration file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'enable_profiling'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span></pre></div></div>

<p>Setting this value to true will enable profiling across your entire website. Now, you can zip through pages, checking the load times of each without any trouble!</p>
<p>Note: I&#8217;ve always thought that an additional way to do this would be to extend the Controller class and enable profiling from there. But this method, I think, has the least impact on existing code.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2009/11/enable-site-wide-profiling-with-codeigniter/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>wpSearch 1.5.0.5 Released With Features, Fixes</title>
		<link>http://codefury.net/2008/08/wpsearch-1505-released-with-features-fixes/</link>
		<comments>http://codefury.net/2008/08/wpsearch-1505-released-with-features-fixes/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 05:09:52 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Search Engine Development]]></category>
		<category><![CDATA[Wordpress Development]]></category>
		<category><![CDATA[1.5.0.5]]></category>
		<category><![CDATA[fix]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wpsearch]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=35</guid>
		<description><![CDATA[After an exhausting week and a half tracking down the source of a mysterious bug in wpSearch, I think I can finally close the book on the &#8220;null result&#8221; issue that had me pouring over the source code. wpSearch 1.5.0.5, the first official release after the 1.5 landmark, brings to the forefront some of the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcodefury.net%2F2008%2F08%2Fwpsearch-1505-released-with-features-fixes%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcodefury.net%2F2008%2F08%2Fwpsearch-1505-released-with-features-fixes%2F&amp;source=_kennyk_&amp;style=normal&amp;space=12&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>After an exhausting week and a half tracking down the source of a mysterious bug in wpSearch, I <strong>think </strong>I can finally close the book on the &#8220;null result&#8221; issue that had me pouring over the source code.</p>
<p>wpSearch 1.5.0.5, the first official release after the <a href="http://codefury.net/2008/07/wpsearch-15-the-fastest-lightest-yet/">1.5 landmark</a>, brings to the forefront some of the features and fixes slated in the last post. wpSearch 1.5 has had the following features implemented:</p>
<ul>
<li>Comment Searching</li>
<li>A behind-the-scenes event logger for easily figuring out user issues</li>
<li>An upgrade to the underlying Lucene Search</li>
<li>An upgrade to the underlying StandardAnalyzer (used for relevancy)</li>
</ul>
<p>And these fixes:</p>
<ul>
<li>No more null results after a post is edited</li>
<li>Foreign character support (or simply indexing content with &#8216;UTF-8&#8242; encoding</li>
<li>Memory issues for content-heavy posts</li>
</ul>
<p>wpSearch 1.5.0.5 is a rock-solid release that is starting to make a name for itself in the WordPress world. The new &#8216;Phone Home&#8217; feature in wpSearch allows users to report their copy of wpSearch. A few of the blogs with wpSearch currently in use are listed here:</p>
<ul>
<li><a href="http://buildingtheergonomicguitar.com/">Building The Ergonomic Guitar</a></li>
<li><a href="http://www.computerbob.com/">ComputerBob</a></li>
<li><a href="http://savoringkentucky.com/wordpress">Savoring Kentucky</a></li>
</ul>
<p>Patrick Cushing at the <a href="http://EnterVenture.com">EnterVenture </a>blog wrote a very detailed comparision of the default WordPress search&#8217;s relevancy vs. wpSearch&#8217;s. This article ended up at <a href="http://digg.com/software/wpSearch_could_be_the_WordPress_search_you_ve_been_waiting_f">digg</a>.</p>
<p>Of course, as far as wpSearch has come in its short lifespan, there exists a set of users that deserve credit for pointing out issues and keeping me informed of bugs, needed features, etc.. So, in no particular order, I would like to thank:</p>
<ul>
<li>ComputerBob, at <a href="http://ComputerBob.com">ComputerBob.com</a> for pointing out the first instance of the empty result issue. He has thoroughly documented his usage with wpSearch at his blog, in a fair and balanced fashion. Furthermore, he has sent his index data back with detailed comments when most users would simply give up on wpSearch. Thanks ComputerBob.</li>
<li><a href="http://buildingtheergonomicguitar.com/">Robert Irizarry</a>, who has kept the wpSearch thread at the WordPress repository stuffed with feature ideas and issue notices.</li>
<li><a href="http://itsogay.com">Olivier</a>, who&#8217;s 6000 posts provided the first failed scalability test for wpSearch. His pointing out of this issue led to a change to allow for greater scalability &#8212; in other words, wpSearch 1.5 was tested successfully up to 7,000 posts. Great dedication to detailing these issues has helped wpSearch greatly.</li>
<li><a href="http://www.fellbeisser.net/news">Karl Heigl</a>, who first mentioned the fact the wpSearch was not handling German accents, and subsequently all foreign (to the U.S.) characters. This also ended up affecting Olivier. This bug was fixed in 1.5.0.5. Thanks Karl!</li>
<li>A user named Brian, said, &#8220;Thanks for the update.  If you need any other information or even help testing, I’d be happy to assist. Just let me know.  &#8221; Thanks for your support Brian.</li>
<li>And to all those who have donated to this project so far!</li>
</ul>
<p>So, wpSearch 1.5.0.5 wouldn&#8217;t be at it&#8217;s current status if it weren&#8217;t for those supporting it.</p>
<p>Features coming up for <a href="http://codefury.net/projects/wpSearch/">wpSearch</a> include result highlighting, contextual snippets, and a progress meter for index building.  I encourage everyone who is reading this but hasn&#8217;t installed wpSearch yet to try it out, and <a href="http://codefury.net/projects/wpsearch/wpsearch-screenshots/">see the awesome blog search that you&#8217;ve been missing.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2008/08/wpsearch-1505-released-with-features-fixes/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
	</channel>
</rss>

