<?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>Casey A. McLaughlin</title>
	<atom:link href="http://www.caseymclaughlin.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.caseymclaughlin.com</link>
	<description>Online Portfolio</description>
	<lastBuildDate>Mon, 08 Mar 2010 21:38:28 +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>Gone is Gone: The Case Against &#8220;Delete&#8221;</title>
		<link>http://www.caseymclaughlin.com/2010/03/gone-is-gone-the-case-against-delete/</link>
		<comments>http://www.caseymclaughlin.com/2010/03/gone-is-gone-the-case-against-delete/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 21:35:36 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=195</guid>
		<description><![CDATA[I love, love, love getting rid of crap.  Maybe that&#8217;s why I like to read Unclutterer, or think that the 100 Things Challenge is such a great idea.  In real-life, I&#8217;m a minimalist, but when it comes to programming web apps, I&#8217;ve become a digital pack-rat.
I don&#8217;t care if my database grows into a giant data-monster, ready [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2010/03/a_bomb2.jpg"><img class="size-thumbnail wp-image-201 alignright" title="The Effects of Deleting Data" src="http://www.caseymclaughlin.com/wp-content/uploads/2010/03/a_bomb2-150x150.jpg" alt="The Effects of Deleting Data" width="150" height="150" /></a>I love, love, love getting rid of crap.  Maybe that&#8217;s why I like to read <a title="Unclutterer Blog - People who think up my ally" href="http://unclutterer.com/">Unclutterer</a>, or think that the <a title="100 Things Challenge - Great Concept!" href="http://www.guynameddave.com/100-thing-challenge.html">100 Things Challenge</a> is such a great idea.  In real-life, I&#8217;m a minimalist, but when it comes to programming web apps, I&#8217;ve become a digital pack-rat.</p>
<p>I don&#8217;t care if my database grows into a giant data-monster, ready to ravage my server&#8217;s hard disk and slow queries down to a crawl; I&#8217;ll deal with it.  The key here is to not allow any important history of data to get lost.</p>
<p><img title="More..." src="http://www.caseymclaughlin.com/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span id="more-195"></span></p>
<h2>Why Deleting is Bad</h2>
<p>Here&#8217;s an example, to get us started:</p>
<p>Let&#8217;s say you have a simple online store, and you&#8217;re selling <a title="The Definition of Importance" href="http://stupid.com">important consumer items</a> to important people.  You have a database that keeps track of your customers, your products, and your transactions.  It may look something like this:</p>
<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2010/03/simple-db.png"><img title="Database Example" src="http://www.caseymclaughlin.com/wp-content/uploads/2010/03/simple-db.png" alt="Database Example" width="625" height="136" /></a>So, you&#8217;ve been in business for a while, and you have a bunch of customers in the system, quite a few products, and a lengthy transaction history.  Recently, you&#8217;ve decided to stop selling your <a title="An Important Asset for every Household" href="http://www.stupid.com/fun/D-MOLD.html">Jell-O Brain Mold</a> and you&#8217;re ready to remove it from your online store.  Common sense says that you would go to your database, find the record referring to your product, and delete it.</p>
<p>But wait!  If you do this, then the entire history of transactions linked to those products become orphaned (the<em>products_id</em> field will point to a non-existent record).  So, if you want to go back in at a future date to see the history of how many of those items that you sold, you will be in trouble.  You haven&#8217;t just deleted the item from your website per se, you&#8217;ve actually deleted the record of the item ever existing in the first place.</p>
<p>And, you don&#8217;t want to do that.</p>
<h2>Flag It!</h2>
<p>The useful alternative would be to add a flag to the data, so that instead of deleting the record, you could mark it as inactive.  This way, it wouldn&#8217;t appear on your website, but it would still exist in the database for future reference.</p>
<p>Your tables will now look something like:</p>
<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2010/03/simple-db-2.png"><img title="DB with Flags" src="http://www.caseymclaughlin.com/wp-content/uploads/2010/03/simple-db-2.png" alt="DB with Flags" width="625" height="151" /></a>Now you can tell your application to only show the products with `active` = &#8220;TRUE&#8221; on your website, but refer to products with `active` = &#8220;FALSE&#8221; when viewing older transaction histories.</p>
<p>This works pretty well, and if you program your User Interface correctly, your website users should never actually be deleting records; instead they should be marking them inactive so they &#8220;go away&#8221; but never truly die.</p>
<h2>Audit History</h2>
<p>Okay, now it gets a bit more complex.  In some cases, you don&#8217;t just want to mark a record &#8220;active&#8221; or &#8220;inactive&#8221; (that is, give it the ability to have two states), you also want to keep a complete revision history of that record, including what change was made, who made it, and when.  This way you can see what a record looked like at a particular moment in time.</p>
<p>This is not a new concept.  Think about your bank account.  It&#8217;s pretty much a bunch of numbers stored in a database somewhere.  Do you think that your checking account balance is simply a single field in a single record stored in a database?  Heck no!  Every single debit and credit is stored as a separate transaction, showing a complete history of changes to the account.</p>
<p>There are many ways to accomplish this, really, and for me to put up a tutorial, would be to <a title="Stack Overflow Thread on the Subject" href="http://stackoverflow.com/questions/323065/how-to-version-control-a-record-in-a-database">reinvent </a><a title="Arnold's (complex) solution" href="http://www.adaniels.nl/articles/versioning-mysql-data/">the</a> <a title="Another Tutorial for MS SQL" href="http://www.codeproject.com/KB/architecture/LisRecordVersioning.aspx">wheel</a>.  The key is to think about which data you want to have complete histories on, and which data is not expendable.  Design your application around these constraints.</p>
<h2>Sometimes you Just Have to Kill It</h2>
<p>I wrote an application that contains patient records.  When an administrator clicks &#8220;Delete&#8221;, the patient doesn&#8217;t really go away; all of the information remains in the database.  Sometimes, however, we <strong>must </strong>delete the record permanently. Usually this is because a patient opts out of the program and requests to be removed from the study.  I use a special word for this kind of delete: <strong>Purge</strong>.</p>
<p>But, before the record is purged, the user has to click a checkbox, and go through two <strong>&#8220;Are You Sure?&#8221;</strong> screens informing him or her that not only will the patient record be deleted, but also the complete history of that record, and all data associated with it.  I try to have the application show the data in question on the screen the user has to click yes to.</p>
<p>&#8230;well, that&#8217;s enough for now.  Hope you&#8217;re thinking about data consistency, so you too can become a digital pack rat.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2010/03/gone-is-gone-the-case-against-delete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Backups and Disaster Recovery Kit</title>
		<link>http://www.caseymclaughlin.com/2010/01/backups-and-disaster-recovery-kit/</link>
		<comments>http://www.caseymclaughlin.com/2010/01/backups-and-disaster-recovery-kit/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 16:21:00 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[IT Management]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[basics]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=186</guid>
		<description><![CDATA[In this post, I chastise you, the reader, for presumably not backing up your department's data, and share how to create a portable DR kit.]]></description>
			<content:encoded><![CDATA[<p><a href="../wp-content/uploads/2010/01/bear-survival-kit.jpg"><img class="alignright" title="bear-survival-kit" src="../wp-content/uploads/2010/01/bear-survival-kit-150x150.jpg" alt="Be Prepared!" width="150" height="150" /></a>It&#8217;s the perfect time to think about it.  With <a title="..and the subsequent media frenzy" href="http://en.wikipedia.org/wiki/2010_Haiti_earthquake">disaster</a> on everybody&#8217;s mind, and this being the season of resolutions, it&#8217;s time to think about your disaster recovery strategy.</p>
<p>Recently, a major department right here at FSU <a title="News article about the loss" href="http://cci.fsu.edu/news/?p=6580">suffered catastrophic loss</a> to their servers, with scant means of quick recovery.  Their site was down literally for weeks as staff from all over the University scrambled to assist them in recreating the critical pieces.  They lost of <em>a lot</em> of time and money.</p>
<p>I&#8217;m absolutely sure they&#8217;ll be super-prepared next time, but <span style="text-decoration: underline;"><em>you</em></span> don&#8217;t have to wait until something tragic happens to be prepared!</p>
<h3><span id="more-186"></span>Disaster Recovery Enterprise Planning = Big Words (Scary!)</h3>
<p>When I was an IT Manager n00b, I thought that planning for disasters was intimidating and complicated.  I thought it took a team of folks working around the clock, military-style, to prepare for incidents.  I was encouraged to believe this by colleagues constantly talking in <a title="Yeah... stuff like this" href="http://spedr.com/5rduk">business-speak</a>, conference sessions talking about <a title="Just like this." href="http://spedr.com/2v7ul">things like &#8220;DR evaluation metrics&#8221;</a>, and by <a title="Big Ugly Book" href="http://spedr.com/1frzy">big</a> <a title="What's the picture on the front of the book supposed to indicate?" href="http://spedr.com/3y867">ugly</a> <a title="More books" href="http://spedr.com/3wig0">books</a> that take days to even read through.</p>
<p>In the meantime, while I was being intimidated by all this &#8220;enterprise&#8221; stuff, we went without reliable backups.  We would have been <em>Scre-ewed</em> if something happened.</p>
<h3>1. Embracing Common Sense</h3>
<p>Okay, just ignore all that business-speak.  Let&#8217;s start with the basics:  If you&#8217;re not backing up your data, put down the <a title="Big Ugly Book" href="http://spedr.com/1frzy">big</a> <a title="What's the picture on the front of the book supposed to indicate?" href="http://spedr.com/3y867">ugly</a> <a title="More books" href="http://spedr.com/3wig0">DR books</a> <em>right now</em> and go setup a backup.</p>
<p>No, seriously, do it <span style="text-decoration: underline;">right now</span>.</p>
<p>This does not have to be complicated.  Go find an external hard drive, then find out where your data is on your computers or servers.  Plug the hard-drive into the back of the computers and copy the folders with your data.  Do this every day, and you have a basic disaster recovery strategy!</p>
<blockquote><p><em>Pro Tip: </em>If you&#8217;re using Windows, I&#8217;m a big fan of using <a title="Seriously awesome freeware." href="http://www.codesector.com/teracopy.php">Teracopy</a> when I have to copy lots of data at a time.</p></blockquote>
<p>You get bonus if you copy the data to two hard-drives and take one off-site every day.  Now your data is in two geographic locations on three devices.</p>
<p>See? Easy.  Now that you&#8217;re off and running, you can make your life even easier by automating your backups.  If you&#8217;re not excited about doing a bunch of geeky tech stuff to get your automated backups working, go convince your boss to spend a few bucks a month on <a title="Mozy Pro Goodness" href="http://mozy.com/pro">cheap</a>, <a title="I Drive is good, too" href="http://www.idrive.com/">easy-to-setup</a> <a title="SOS Backup Services" href="http://www.sosonlinebackup.com/">online backup services</a>.  If he doesn&#8217;t want to spend the money, you can scare him with <a title="Coding Horror: Backup Awareness Day" href="http://spedr.com/5nizg">many</a> <a title="Company Fail" href="http://spedr.com/4jg32">horrifying</a> <a title="Marketing site, but still true" href="http://spedr.com/4niov">stories</a> of data loss on the Internet.</p>
<h3>2. Being Prepared</h3>
<p>Next Step: Just sit down in a quiet place for a few minutes and think about the things that could go wrong:</p>
<ul>
<li>&#8220;My server could suffer a catastrophic hardware failure&#8221;</li>
<li>&#8220;My backup data could be corrupt&#8221;</li>
<li>&#8220;The building could burn down&#8221;</li>
<li>&#8220;We could get robbed&#8221;</li>
<li>&#8220;An employee could go apeshit and format the C: drive of the server&#8221;</li>
<li><em>etc..</em></li>
</ul>
<p>Now consider which three or four of those scenarios are most likely to happen in your department. You&#8217;ve just considered your risks.  Now, for each one of those scenarios, think about (a) what you can easily do to guard against them and (b) what you would have to do to recover from them:</p>
<ul>
<li>Buy a second, backup server (or set an old computer aside to act as server temporarily in case of disaster).</li>
<li>Keep two backup copies instead of one and periodically test opening files on the backup.</li>
<li>Take backups offsite so that the data doesn&#8217;t burn down with the rest of the building.</li>
<li>Lock the servers in a room without windows.</li>
<li>Keep backups (already done), and make sure employees don&#8217;t have too much access to the server.</li>
<li><em>etc..</em></li>
</ul>
<p>If you write all of this stuff down somewhere and tell your boss about it, you have a basic DR plan!  Go have a beer.</p>
<h3>3. Building Your Kit</h3>
<p>Now that you are creating backups and thinking about our risks/responses, it&#8217;s time to build your <strong>Disaster Recovery Kit!</strong> Put this kit somewhere out of harm&#8217;s way, and have it handy in case you need it.  Here&#8217;s mine:</p>
<ol>
<li><strong>A camcorder bag</strong> &#8212; I like this, because it&#8217;s easy to carry and has a lot of compartments for all the stuff below:</li>
<li><strong>Operating System Boot discs </strong>&#8211; In my case, Ubuntu Server 8.04</li>
<li><strong>GParted Boot disc</strong> &#8212; For formatting and partitioning systems on-the-fly.</li>
<li><strong>Cables </strong>&#8211; Standard power cable and USB cable.</li>
<li><strong>Backup hard drives</strong> &#8212; Two.  They are my offsite copies of all our data.  I rotate them and keep them encrypted.</li>
<li><strong>Flash light </strong>&#8211; Small and compact, for poking around inside computers or navigating server rooms in the dark</li>
<li><strong>Thumb drive</strong> &#8212; Includes a backup of my server setup procedures/changelogs, systems passwords (in KeePass), and a bunch of portable apps.  Updated weekly.</li>
<li><strong>Printed copy of contact information for key stakeholders</strong> &#8212; My IT colleagues, clients, and my boss, so I can keep them updated.</li>
<li> <strong>Geek tool kit</strong> &#8211;  <a title="Belkin Basic Toolkit" href="http://spedr.com/3mv8z">Something like this</a>.  Includes screwdrivers, etc.</li>
<li><strong>External SATA Hard Disk Reader </strong>&#8211; Something<a title="StarTech USB SATA adapter" href="http://spedr.com/46suc"> small and compact</a>.  In case I need to rip a hard drive from a computer and get the data off quickly.</li>
<li><strong>A big sheet of paper that says <span style="color: #800000;">&#8220;<em>Don&#8217;t Panic</em>&#8220;</span></strong></li>
<li><strong>Music CD</strong> with high-energy power music on it.</li>
<li><strong>Energy supplement</strong> &#8212; Or a flask of whiskey, depending on how you roll.</li>
<li><strong>&#8220;Getting started&#8221; guide </strong>&#8211; A piece of paper, right on top, that explains briefly how to use the kit.</li>
<li><strong>Checklist</strong> &#8212; With all of these items on it, and with weekly DR Kit maintenance procedures.</li>
</ol>
<p>There, now I can sleep at night much better.  What&#8217;s in your DR Toolkit?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2010/01/backups-and-disaster-recovery-kit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated my Projects!</title>
		<link>http://www.caseymclaughlin.com/2009/12/updated-my-projects/</link>
		<comments>http://www.caseymclaughlin.com/2009/12/updated-my-projects/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 22:51:08 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[this site]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=153</guid>
		<description><![CDATA[I've updated my CodeIgniter projects listed on this site finally!]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/lazy.gif"><img class="alignright size-thumbnail wp-image-155" title="lazy" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/lazy-150x150.gif" alt="Lazy funny picture" width="150" height="150" /></a>As a Christmas Holiday present to those of you that are using my CodeIgniter tools, <em>CI-UserTracking</em> and <em>GeSHi for CI</em>, I did something very philanthropic: I updated them and tested them on the latest version of CodeIgniter.</p>
<p>Oh, and I also fixed the links&#8230;</p>
<p>..and I put them in their very own Google Code pages, so you can peruse the source code, download from Google servers, and leave comments and tickets for yours truly.</p>
<p>AND.. as your Hanukkah/New Years/Participation gift, I also have added a brand new CodeIgniter project that I&#8217;m working on called <em><a title="CI Headstart Google Code Page" href="http://code.google.com/p/ciheadstart/">CI Headstar</a>t</em> with all kinds of helpers, libraries, and other goodies to help speed up development even more.  Roll on over to the <a title="The Code Page -- It's new too! Yay." href="http://www.caseymclaughlin.com/code/">Code page</a> to check it all out.</p>
<p>Now that Christmas break is upon us, and I since I work for a University that gives employees like a bazillion days off each December, I hope to clean these up even more and provide some quality documentation.</p>
<p>Happy Holidays from me to you,</p>
<p><img class="size-medium wp-image-154 alignnone" title="My Signature" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/My-Signature-300x82.gif" alt="Casey McLaughlin (signature)" width="300" height="82" /></p>
<p>PS &gt;&gt; If anybody is interested in contributing code to these projects, <a title="Contact Form -- I swear it goes straight to my Gmail!" href="http://www.caseymclaughlin.com/contact/">let me know</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/12/updated-my-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Biting the Distributed Development Bullet</title>
		<link>http://www.caseymclaughlin.com/2009/12/make-codeigniter-svn-friendly/</link>
		<comments>http://www.caseymclaughlin.com/2009/12/make-codeigniter-svn-friendly/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 20:15:46 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=129</guid>
		<description><![CDATA[You're a dummy for not using version control.  If I can do it, anybody can.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/programmer.jpg"><img class="alignright size-thumbnail wp-image-131" title="programmer" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/programmer-150x150.jpg" alt="Will Code for Food" width="150" height="150" /></a>Like most development n00bs, after I started using version control, I never looked back.  And <a title="Stack Overflow Thread" href="http://spedr.com/k1z1">neither should you</a>.</p>
<p>It required me to change the whole way that my office operated, though.  See, the way that we were doing things before seemed so simple; we just edited files and shouted at each other if we collided in our editing.  As it turns out, this was a bad thing, and there have been better alternatives around way longer than I&#8217;ve even been in this business.</p>
<p>But like most crotchety, over-egotistical developer-types it took a while for me to come around.  Here&#8217;s a brief history of my flirtations and eventual commitment to version control.</p>
<h3><span id="more-129"></span>Our Blissful, Youthful Ignorance</h3>
<p>This wasn&#8217;t really that long ago&#8230;</p>
<div id="attachment_139" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/Workflow-SSH.png"><img class="size-medium wp-image-139" title="The Old Workflow" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/Workflow-SSH-300x237.png" alt="The old, SSH-based Workflow" width="300" height="237" /></a><p class="wp-caption-text">1..2..3... Easy Peasy Japanesey.. and stupid.</p></div>
<p>We would all work directly on the files directly on our development server.  We would sit down, SSH into the server using our favorite editor and code away, never thinking of change management, reverting back to old versions, or who would be responsible for what.  Conflict resolution seemed easy&#8230; if I was editing a file named<em> welcome.php</em>, I would simply shout across the room, &#8220;Hey Mike&#8211;don&#8217;t work on <em>welcome.php</em> right now, or I&#8217;ll have to beat you!&#8221;.</p>
<p>Our revision control system consisted of me creating and storing weekly backups of the entire database and file system.  If we made a change that killed the system, we&#8217;d simply either lose that week&#8217;s work or spend hours debugging it.  It was all gloriously simple.</p>
<h3>Version Control Puberty &#8212; The Angsty Years</h3>
<p>One day, I decided to implement Subversion, mainly because other developers were sneering at me and telling me I was a dummy.  And while I didn&#8217;t want to be a dummy, the whole thing seemed overly complicated.  Why would I want to increase complication when everything was working so simple?  I also had some fundamental issues with this new version control idea:</p>
<ul>
<li>First off, everybody has to have to get their own copy of the entire file set.  Bad!  Doom! Insecure! I have to trust my developers with the codebase? ::Gasp::</li>
<li>Secondly, what do you mean that developers can&#8217;t see their changes on the server immediately upon commit without some hacked hook system?  This means they&#8217;ll have to run <a title="Wikipedia LAMP" href="http://en.wikipedia.org/wiki/LAMP_%28software_bundle%29">LAMP</a> on their local boxes, too!  Geez.. now we have to have local dev environment setup procedures, too..</li>
<li>Finally, SVN requires management of its own.  You know.. backing up, securing access, and generally managing.  More overhead and more complication!</li>
</ul>
<p>Grudgingly, in order to remove the &#8220;dummy&#8221; label from my operations, I implemented Subversion.  It was difficult at first to understand how it would fit easily into our procedures, but with some <a title="Subversion Book - Basic Work Cycle (a very helpful chapter)" href="http://svnbook.red-bean.com/en/1.5/svn.tour.cycle.html">very helpful free online material</a>, we started using it.</p>
<p>And sure, I <em>did</em> have to write procedures for setting up local dev environments AND install a subversion clients AND manage a <a title="Hands Down, VisualSVN is the easist-to-use SVN Server for Windows" href="http://www.visualsvn.com/server/">repository server</a>, but you know what?</p>
<p>All of that stuff was way worth it.</p>
<h3>All Grown-up Now</h3>
<p>Let me repeat that: whatever frustrations version control causes, they are all worth it.</p>
<p>After being SVN disciples for a while now, our development procedures have matured.  Here&#8217;s how we do things:</p>
<div id="attachment_137" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/Workflow-SVN.png"><img class="size-medium wp-image-137" title="SVN Workflow" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/12/Workflow-SVN-300x242.png" alt="The way we do things now" width="300" height="242" /></a><p class="wp-caption-text">The way we do things now.. Much better!</p></div>
<p>I&#8217;ve since tried other VCS systems like <a title="Mercurial Homepage" href="http://mercurial.selenic.com/">Mercurial</a>, <a title="Git Homepage" href="http://git-scm.com/">Git</a>, and <a title="Bazaar Homepage" href="http://bazaar.canonical.com/en/">Bazaar</a>, but have not found any compelling reason to switch.   Either way, using version control has saved our sorry butts on more than one occasion and has made life easier in about 1,001 ways.</p>
<p>As a bonus, it has also forced us to use better procedures and generate better development documentation, which is amazing, because we&#8217;re pretty lazy.  Now if only we could find a tool to better force us to behave when it comes to unit testing&#8230;</p>
<p>Well, that&#8217;s my story.  If I&#8217;ve inspired you to use VCS, hooray!  <a title="Awesome SVN Primer I found on the front page of Google search" href="http://www.snipe.net/2009/03/getting-started-with-subversion/">Here&#8217;s a helpful place to get started</a>.  If not, you&#8217;re a dummy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/12/make-codeigniter-svn-friendly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixed GeSHI for CodeIgniter Link</title>
		<link>http://www.caseymclaughlin.com/2009/09/fixed-geshi-for-codeigniter-link/</link>
		<comments>http://www.caseymclaughlin.com/2009/09/fixed-geshi-for-codeigniter-link/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 16:11:54 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[geshi]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[this site]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=119</guid>
		<description><![CDATA[Thanks all who notified me that the GesHi for CodeIgniter download link was serving up a big, ugly 404 page.  I plan on releasing a new version soon, but in the meantime, I&#8217;ve fixed the link.
Any questions, comments, or suggestions are always welcome.  Also, if anybody has tried this plugin on CI 1.7.2, let me [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2009/09/funny-car-repairs-engine.jpg"><img class="alignright size-thumbnail wp-image-121" title="funny-car-repairs-engine" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/09/funny-car-repairs-engine-150x150.jpg" alt="funny-car-repairs-engine" width="150" height="150" /></a>Thanks all who notified me that the GesHi for CodeIgniter download link was serving up a big, ugly <strong>404</strong> page.  I plan on releasing a new version soon, but in the meantime, I&#8217;ve fixed the link.</p>
<p>Any questions, comments, or suggestions are always welcome.  Also, if anybody has tried this plugin on CI 1.7.2, let me know how it works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/09/fixed-geshi-for-codeigniter-link/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Teaching PHP: Course Curriculum</title>
		<link>http://www.caseymclaughlin.com/2009/08/teaching-php-course-curriculum/</link>
		<comments>http://www.caseymclaughlin.com/2009/08/teaching-php-course-curriculum/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 20:11:31 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[IT Management]]></category>
		<category><![CDATA[curriculum]]></category>
		<category><![CDATA[instruction]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[teaching]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=108</guid>
		<description><![CDATA[The problem, succinctly stated, is: How do you best organize 14 weeks of study to teach PHP to a group of motivated College students?]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caseymclaughlin.com/wp-content/uploads/2009/08/php-sauce.jpg"><img class="alignright size-full wp-image-110" title="php-sauce" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/08/php-sauce.jpg" alt="php-sauce" width="139" height="150" /></a>The problem, succinctly stated, is: <strong>How do you best organize 14 weeks of study to teach PHP to a group of motivated College students?</strong></p>
<p>I know they must be pretty motivated, because they&#8217;re signing up for the class despite the fact that it starts at 8 am.</p>
<p>This Fall, I will  be teaching a course in Web Application Development at FSU.  The topic will be server-side scripting, and the focus will be PHP.  Since I&#8217;ve taught this course before, developing the curriculum won&#8217;t take months, but I am nevertheless spending a fair amount of time updating and tweaking for the next go-around.</p>
<p><span id="more-108"></span></p>
<p>A quick <a title="Google Search for &quot;Teaching PHP&quot;" href="http://spedr.com/xyd0">Google Search for &#8220;Teaching PHP&#8221;</a> brings up only a few relevant links, most message board discussions.  &#8220;Server Side Scripting Curriculum&#8221; doesn&#8217;t return much either.  Likewise, <a title="WaSP Web Standards Project" href="http://interact.webstandards.org/">WaSP</a> have not yet published their recommended server-side scripting course recommendations.</p>
<p>So, I&#8217;ve had to come up with a lot of the course unilaterally.  The learning objectives are as follows:</p>
<p>By the end of the course, students will understand:</p>
<ul>
<li>Basic programming skills</li>
<li>Web application development principles</li>
<li>How to find and use PHP resources on the Internet</li>
<li>How to manage tasks, bugs, and revision control mechanisms for web projects</li>
</ul>
<p>By the completion of this course, students will be able to:</p>
<ul>
<li>Program and deploy simple scripts in PHP</li>
<li>Process web-based input and output in PHP</li>
<li>Build multi-file PHP applications</li>
<li>Connect PHP applications to a database</li>
<li>Design a simple dynamic website using PHP, MySQL, HTML, and CSS</li>
</ul>
<p>After a few iterations of course development, here are the topics I have planned to discuss, in order, thus far:</p>
<ul>
<li>The current &#8220;State of the Internet&#8221;</li>
<li>How the technology works &#8211; Web servers and clients</li>
<li>Eclipse setup and good  practices for personal workflow</li>
<li>PHP basics &#8211; Syntax, variables, arrays, functions, iterators, etc.</li>
<li>Form processing (GET/POST)</li>
<li>Database integration</li>
<li>Multi-file application organization</li>
<li>Classes and objects</li>
<li>MVC frameworks</li>
<li>Revision control and associated workflow</li>
<li>Basic management: Ticket and bug tracking</li>
<li>Web Services &#8211; SOAP and RPC</li>
<li>XML integration</li>
<li>Comprehensive application organization</li>
</ul>
<p>That&#8217;s <em>a lot</em> of information.  Fortunately the students will have object-oriented experience AND database experience.  So, we should be able to leap off the cliff quickly and into the world of iterators, encapsulation, and inheritance.</p>
<p>I&#8217;ll post the week-by-week calendar when I finalize it, which necessity dictates will be very soon.  Feel free to grab it and use it for your own courses, or <a title="Contact Me Form" href="http://www.caseymclaughlin.com/contact/">tell me</a> what I can improve on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/08/teaching-php-course-curriculum/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CodeIgniter Preflight Checker</title>
		<link>http://www.caseymclaughlin.com/2009/06/codeigniter-preflight-checker/</link>
		<comments>http://www.caseymclaughlin.com/2009/06/codeigniter-preflight-checker/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 18:16:07 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[portability]]></category>
		<category><![CDATA[portable]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=84</guid>
		<description><![CDATA[This post builds on last week's discussion of how to make an application portable by demonstrating how to implement a "pre-flight" check before your application runs.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/mike_miley/2996159793/"><img class="alignright size-thumbnail wp-image-86" title="preflight_check" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/06/preflight_check-150x150.jpg" alt="preflight_check" width="150" height="150" /></a>In <a title="Last Post: Making PHP Applications Portable" href="http://www.caseymclaughlin.com/2009/06/making-php-applications-portable/">my last post</a>, I discussed do&#8217;s and don&#8217;ts for making a PHP application portable.  This week, I will show you how to create a preflight checker in the <a title="CodeIgniter Homepage" href="http://www.codeigniter.com">CodeIgniter PHP framework</a> to ensure that an environment will support your application.</p>
<p><span id="more-84"></span></p>
<p><em>Note: This article assumes that you already have a working CodeIgniter application setup.  If you are interested in getting started with CodeIgniter, there are some <a title="CodeIgniter Video Tutorials" href="http://codeigniter.com/tutorials/">really</a> <a title="CodeIgniter Official User Guide" href="http://codeigniter.com/user_guide/">great</a> <a title="Net Tuts &quot;Getting started with CodeIgniter&quot; Article" href="http://net.tutsplus.com/videos/screencasts/easy-development-with-codeigniter/">tutorials </a>on the web.  If you&#8217;re not using CodeIgniter, skip to the &#8220;What to Check&#8221; section below for a general idea of how to apply this to PHP apps in general.</em></p>
<h2>Setting up the Hook</h2>
<p>The best way to setup a preflight checker is to create a hook.  Make sure that you <a title="CodeIgniter Hooks Documentation" href="http://codeigniter.com/user_guide/general/hooks.html">enable hooks</a> in your main configuration file before getting started.  We&#8217;ll be setting up a pre-system hook, so add the following code to your <em>application/config/hooks.php</em> file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/*Preflight Check Hook*/</span>
<span style="color: #000088;">$hook</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'pre_system'</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;">''</span><span style="color: #339933;">,</span>
<span style="color: #0000ff;">'function'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'preflight_check'</span><span style="color: #339933;">,</span>
<span style="color: #0000ff;">'filename'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'preflight_check_hook.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: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This will tell CodeIgniter to run this hook every time the system starts.  As you can infer from the above code, we&#8217;ll now have to create a file in the <em>application/hooks/</em> folder (if it doesn&#8217;t exist, create it) named <strong>preflight_check_hook.php</strong> and add a function to that file named <strong>preflight_check()</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Preflight Check checks all of the prerequistes before the first
 * pageview for each session.
 *
 * If a problem is found, the program halts execution.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> preflight_check<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;">//all your checks go here</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we&#8217;re ready to add checks so we can test the server environment.</p>
<h2>What to Check</h2>
<p>Technically, you can check whatever you want here, but I tend to check the things that are likely to be different from one server environment to the next.  Some of the more important ones are:</p>
<ul>
<li>Whether the version of PHP or CodeIgniter is new enough to support your application.  You can check this by using the <em>phpversion()</em> function</li>
<li>Necessary PHP Extensions installed?  You can check this by using the <em>function_exists()</em> function.</li>
<li>PHP.INI variables set correctly?  You can check this by using the <em>ini_get()<strong> </strong></em>function.</li>
<li>Whether certain folders are really writable on the server or not</li>
<li>Whether files exist or not.</li>
</ul>
<p>Of course, you can check for most anything you want to in the preflight check, and even try to tweak the environment a little using <em>ini_set()</em>.  What you <span style="text-decoration: underline;">can&#8217;t</span> do is access most of the functionality in CodeIgniter, since this hook will run before most of your libraries are loaded.  There are a few useful CodeIgniter variables and functions that you will have access to, though:</p>
<ul>
<li><em>show_error()</em> &#8212; For printing out errors (non CodeIgniter users should use the <em>die()</em> function)</li>
<li><em>is_really_writable()</em> &#8212; For testing if a file is writable or not (non CodeIgniter users should use the <em>is_readable()</em> function)</li>
<li><em>$application_folder </em>and <em>$system_folder</em></li>
</ul>
<p>Rather than bore you with lengthy explanations of each type of check, it will be easier to simply show you an example of how I typically do it.  Below is an example preflight check hook that I ripped almost verbatim from one of my applications:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> preflight_check<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$application_folder</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$system_folder</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Ensure proper version of PHP</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000ff;">'5.1'</span><span style="color: #009900;">&#41;</span>
	  show_error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;This application requires at least PHP 5.1 to run properly!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Ensure SQLITE extension is installed</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mysql_connect'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	  show_error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;The sqlite PHP extension is required to run this application!  Refer to &lt;a href=&quot;</span>http<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//us.php.net/manual/en/book.sqlite.php&quot;&gt;the PHP documentation for this extension&lt;/a&gt; for more information.&quot;);</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Ensure GD2 is is installed</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;gd_info&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		show_error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;The PHP GD2 image library is required to run this software.  Check with your server administrator or hosting provider, or &lt;a title=&quot;</span>Installation Instructions <span style="color: #b1b100;">for</span> GD2<span style="color: #339933;">&gt;</span>refer to the PHP documentation <span style="color: #b1b100;">for</span> installation instructions<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;.&amp;</span>quot<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 	<span style="color: #666666; font-style: italic;">//Check if the system cache directory is writable 	if ( ! is_really_writable($system_folder . &quot; href=&quot;http://us2.php.net/manual/en/intro.image.php&quot;&gt;&lt;/a&gt;&lt;a title=&quot;JSON extension installation instructions&quot; href=&quot;http://us3.php.net/manual/en/book.json.php&quot;&gt;manually install it&lt;/a&gt;.)&quot;);</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Check memory limit and attempt to set it to what this application needs</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_bytes<span style="color: #009900;">&#40;</span><span style="color: #990000;">ini_get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'php_value memory_limit'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">33554432</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: #339933;">!</span> <span style="color: #990000;">ini_set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'php_value_memory_limit'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'32m'</span><span style="color: #009900;">&#41;</span>
			show_error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;The memory limit in your PHP.INI file must be set to at least 32 megabytes (32m).&quot;</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>You can copy this code into your <em>application/hooks/preflight_check_hook.php</em> and try it out.  Basically, it will halt execution (via the <em>show_error()</em> function) and show an error on the screen that alerts the user to something not being setup correctly if any one of these checks fails.</p>
<h2>What&#8217;s the Advantage over just letting the program fail on its own?</h2>
<p>Technically, nothing; your preflight checker will check things that would normally cause your application to fail at some point in the execution anyway.  This is simply a way for you to alert your admins/developers/users that they need to fix their environment right off the bat.  Plus it&#8217;s more graceful and clean than PHP error messages.</p>
<p>Practically, however, this may save a lot of headaches, especially if you distribute the application or expect people to download a copy onto their own desktops for development.  Oh, and if your users/developers/admins have PHP error reporting turned off on their system, then a carefully coded preflight checker will save them from getting a mysterious blank screen when the environment doesn&#8217;t match the requirements.</p>
<h2>Keeping this thing from running for every page view</h2>
<p>You probably won&#8217;t want this script to run every time a  page is loaded on your site, especially if the script includes file operations, lest your server take a performance hit.  Typically, you will want to run this preflight checker only once per session.  By adding a few lines of code to the top and bottom of this function, you can make it run only once per session (unless it fails).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> preflight_check<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;">//See if this has already been run during the current session</span>
	<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'preflight_check_pass'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'preflight_check_pass'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'pass'</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$application_folder</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$system_folder</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Ensure proper version of PHP</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">phpversion</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000ff;">'5.1'</span><span style="color: #009900;">&#41;</span>
	  show_error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;This application requires at least PHP 5.1 to run properly!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// All of the</span>
	<span style="color: #666666; font-style: italic;">// rest of your checks</span>
	<span style="color: #666666; font-style: italic;">// go in here...</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Woo hoo.. the check passed!</span>
	<span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'preflight_check_pass'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'pass'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You&#8217;ll notice that this example uses PHP&#8217;s built-in session system rather than CodeIgniter&#8217;s session library.  This is because CodeIgniter&#8217;s will not have been loaded yet when this hook runs, and because we&#8217;re not storing any particularly sensitive information in this session, so we don&#8217;t have to take advantage of CI&#8217;s advanced session security features.</p>
<p>Well, that&#8217;s about it for now.  If you have any comments or see any issues with the examples in today&#8217;s post, feel free to share by leaving a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/06/codeigniter-preflight-checker/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making PHP Applications Portable</title>
		<link>http://www.caseymclaughlin.com/2009/06/making-php-applications-portable/</link>
		<comments>http://www.caseymclaughlin.com/2009/06/making-php-applications-portable/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 19:27:27 +0000</pubDate>
		<dc:creator>McLaughlin Casey</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[portability]]></category>
		<category><![CDATA[portable]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=56</guid>
		<description><![CDATA[This post is the first in a two-part series explaining the virtues of portability when designing PHP applications, and provides a checklist of do's and don'ts (mostly don'ts) for ensuring that your application will run in any PHP server environment.]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-62" title="portable_computer_guy" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/06/portable_computer_guy.jpg" alt="portable_computer_guy" width="225" height="158" />&#8220;Portable&#8221; means that your application is able to run on any PHP webserver with minimal fuss.</p>
<p>Ensuring portability is an absolute must for programs that are packaged and distributed for public consumption, like Wordpress or MediaWiki.  But, you should aim for portability in all of your applications.  The ideal is a one or two-step installation process and only two or three system requirements:  1. <em>Webserver (IIS/Apache/etc)</em>, 2. <em>PHP v5.X+</em>, 3. <em>MySQL 4+</em>.</p>
<p><span id="more-56"></span></p>
<h2>Why Make it Portable?</h2>
<p>For one, it keeps things simple.  The concept of portability meshes well with the <a title="Keep It Simple, Stupid." href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> concept that I value so highly.</p>
<p>Secondly, it makes deploying your application to a new server simple if the need ever arises.</p>
<p>Thirdly, it enables you to easily distribute your package to the world if that is your intention.  I, for one, simply hate installing web applications on my server with long lists of prerequisites and a lengthy install process, especially if one of those steps is to install <em>another</em> set of libraries (e.g. from PEAR) before installing the application itself.</p>
<p>Finally, portability makes distributed development easier.  Many applications are developed on Windows but run on Linux.  Portable applications eliminate the headaches involved in trying to get the to two environments (development &amp; production) to match.</p>
<h2>How to Make Your Application Portable</h2>
<p>A truly portable application will work out-of-the-box, and require minimal configuration.  It will also automatically check the environment for specific configuration or prerequisites that <em>do </em>happen to be required.  Below are five things to try and avoid, and one thing to try and do to ensure your application is portable:</p>
<h3>1. Don&#8217;t rely on exotic PHP extensions</h3>
<p>I&#8217;m talking about extensions that are not bundled with PHP or found pre-installed on most hosting providers.  If you do require a specific PHP extension that is not bundled with PHP, you should check for the existence of the extension at the beginning of the program&#8217;s execution.</p>
<p>For example, many of my applications require JSON libraries, which some versions of PHP5 do not include, so I check for the existence of the <em>json_encode</em> function when the application first runs.</p>
<h3>2. Don&#8217;t rely on separate installation of PEAR Libraries</h3>
<p>Don&#8217;t get me wrong; PEAR is great.  But, you shouldn&#8217;t predicate the successful execution of your application on your users installing external libraries.  Most PEAR libraries are dependent on other PEAR libraries, and require the user to figure out and install multiple packages.  Your application should not require this pre-setup, and it should run with all of the required libraries and classes included.</p>
<h3>3. Don&#8217;t rely on command-line configuration</h3>
<p>If you want your application to be truly portable, you have to cater to the crowd who has only FTP access to their servers.  Yes, these folks are few-and-far-between, but coding with them in mind ensures that your application setup procedure is as simple as possible.  This means that your installation instructions should be completely void of anything that says <em>&#8220;login to the command line and run xyz command&#8221;</em>.</p>
<p>Definitely don&#8217;t rely on the user to have administrative privileges on the server.  This means to try to avoide the necessity for external software or packages (although this is unavoidable sometimes).</p>
<h3>4. Don&#8217;t rely on the program to be run on a specific operating system</h3>
<p>This one is  a stretch for some people, but truly portable applications can run on Windows, Linux, or MAC servers without fuss.  I make all my applications portable enough to run on any OS  simply because we use SVN for development, which requires my developers to download fully working copies of the project to their desktops.  Since my developers use Windows &amp; Mac, and my servers run Linux, my applications have to be cross-platform compatible.</p>
<h3>5. Don&#8217;t rely on PHP.INI customizations</h3>
<p>A lot of PHP applications I have tried won&#8217;t work with magic quotes (or vice versa), or won&#8217;t work without the user increasing the amount of memory or upload file size  for PHP.   Before making these nice-to-have&#8217;s required, ask yourself if you can find a different way to solve the problem.</p>
<p>For situations where it is unavoidable to ensure that a specific directive is set, your application should automatically attempt to override the default PHP.INI customization via <em>ini_set() </em>and then inform the user in <span style="text-decoration: underline;">plain English</span> that the ini value needs to be changed.</p>
<h3>6. <span style="text-decoration: underline;">Do</span> include a mechanism in the application to test for required prerequisites at the very start of execution (or as part of the installation process)</h3>
<p>Rather than have your application spit out a generic PHP error message when it comes across an environment setting that it doesn&#8217;t like, you should include a function that performs a &#8220;pre-flight checklist&#8221; at the beginning of runtime for each session, or at least the very first time your application is run.</p>
<p>Next week, I will show you how to do exactly this by creating a hook in <a title="CodeIgniter Homepage" href="http://codeigniter.com">CodeIgniter</a> that thoroughly tests the environment, and informs the user how to remedy issues.</p>
<h6>For Further Reading, I recommend:</h6>
<ul>
<li><a title="&quot;Writing Portable PHP Code&quot; article" href="http://www.phpwact.org/php/writing_portable_php_code">Writing Portable PHP Code</a> from <a title="Web Application Toolkit" href="http://www.phpwact.org">PHPwact.org</a></li>
<li><a title="&quot;Making Your PHP Code Portable&quot; Article" href="http://www.mtdev.com/2002/09/make-your-php-code-portable">Making Your PHP Code Portable</a> from <a title="mtDev" href="http://mtdev.com">mtdev.com</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/06/making-php-applications-portable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello World!</title>
		<link>http://www.caseymclaughlin.com/2009/06/hello-world/</link>
		<comments>http://www.caseymclaughlin.com/2009/06/hello-world/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 15:54:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[blog tips]]></category>
		<category><![CDATA[hello]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[introduction]]></category>
		<category><![CDATA[welcome]]></category>

		<guid isPermaLink="false">http://www.caseymclaughlin.com/?p=1</guid>
		<description><![CDATA[After a long hiatus, I reacquaint myself with my good old friend, the Blog.  Plus, I share some tips for good blogging that I found from that supreme authority, The Internet.]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-25" title="horse-in-car" src="http://www.caseymclaughlin.com/wp-content/uploads/2009/06/horse-in-car.png" alt="horse-in-car" width="190" height="141" />Well, I&#8217;m back.</p>
<p>It&#8217;s been exactly two years, six months, 1 day, and 12 minutes since I last published a post on my website.  You could say that I <span style="text-decoration: line-through;">took a vacation from blogging</span> got a real job, so coming back to the activity of blogging feels like running into an old friend that I&#8217;ve hardly talked to in years.  Do you feel the tension?!  Recently, my sister asked me to dig up some old blog posts, and you know what?  Reading my old posts, I remembered just how much fun it is to write.</p>
<p><span id="more-1"></span></p>
<p>The problem is that my writing skills have grown rusty, since I have spent the past eight years in a &#8220;business&#8221; environment writing:</p>
<ul>
<li>mostly bullet</li>
<li>statements directed</li>
<li>at managers and deans</li>
<li>who &#8220;don&#8217;t have time&#8221; to</li>
<li>appreciate literary wit&#8230;</li>
</ul>
<p>&#8230;so I&#8217;ve been trolling the Internet looking for good tips for blogging.  Here&#8217;s a smattering of what I&#8217;ve found:</p>
<h3>1. Offer the Reader Something</h3>
<p>So, I can tell you right now that this post will offer you <strong>absolutely no rewarding value</strong>.  There it is.  In fact, I wrote it just in order to have something besides the Wordpress default post to start off with.  So, now that we have gotten that out of the way, the next tip I found was:</p>
<h3>2. Include Bulleted Point Lists</h3>
<p>Done!  See my bulleted list above.  Actually, I&#8217;m a pro at this.  One thing I&#8217;ve learned over the past few years is that nobody in my department has an inclination for reading.  Especially not emails.  Especially not from me.  So, I&#8217;ve learned to avoid complete thoughts, because writing bullets is just way more effective.  But anyhow, I also read that you should&#8230;</p>
<h3>3. Make Headlines Snappy</h3>
<p>What could be better than &#8220;Hello World!&#8221;  And, I&#8217;ve included a nice &#8220;hello&#8221;-themed picture to go along with it.</p>
<h3>4. Write with Passion</h3>
<p>You can&#8217;t see me right now, but believe me, I am writing with much passion and vigor.  The reason for this is that I have had at least eight cups of coffee in the past three hours.  My right eye is pulsating like crazy and my hands are like paint shakers.  But, as <a title="I'm referring to paragraph 5 of the Wikipedia article, if you are curious" href="http://en.wikipedia.org/wiki/Paul_Erd%C5%91s">Paul Erdős</a> has taught us, without amphetamines, there can be no creativity.</p>
<h3>5. Publish Often</h3>
<p>Well, if you consider every two years to be &#8220;often&#8221;, strictly speaking, then I am good.</p>
<p>Seriously, I do plan to put a lot of useful stuff here.  The problem most people have with blogging is thinking up good content to share.  Some people spend weeks tinkering with their blog&#8217;s design and playing with plugins but then forget to, y&#8217;know, write something.  I, on the other hand, have a laundry-list of topics queued up to be posted here.  So, now that we&#8217;ve cut the tension and gotten introductions out of the way, I look forward to reacquainting myself with my blog.</p>
<p>It&#8217;s been a long time, old friend.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caseymclaughlin.com/2009/06/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
