<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Tony Bibbs » PHP</title>
	
	<link>http://www.tonybibbs.com</link>
	<description>Family, Outdoors and Technology</description>
	<lastBuildDate>Wed, 23 Mar 2011 15:42:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/TonyBibbsOnPhp" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="tonybibbsonphp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Comparing Propel and Doctrine</title>
		<link>http://www.tonybibbs.com/2010/02/comparing-propel-and-doctrine/</link>
		<comments>http://www.tonybibbs.com/2010/02/comparing-propel-and-doctrine/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 20:40:18 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Propel]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/?p=329</guid>
		<description><![CDATA[I&#8217;ve recently decided to make the switch to Doctrine as the ORM of choice for any new PHP projects we work on. I didn&#8217;t make this decision lightly as, until now, I have been a long time user and advocate of Propel having given talks on it at PHP conferences and even a webinar or two. So why the change? That&#8217;s really not significant, what is significant is I think I can give a very quick punchlist of things about each that other PHP&#8217;er might find useful when evaluating them for themselves. Propel Pros &#8211; First, let&#8217;s be clear I&#8217;m not talking about the pros of using an ORM. I&#8217;m talking about the good things that this ORM implementation brings to the table. Those are: Hydration Speed &#8211; You can argue you should never retrieve hydrated PHP objects from query if you don&#8217;t plan on taking some sort of save or delete action on it. Yes, that&#8217;s true from a performance standpoint, however, if you are building a site where performance simply isn&#8217;t a concern then you&#8217;ll be pleased to know Propel can hydrate a set of objects quickly enough to be used in building a view (i.e. a data [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently decided to make the switch to <a href="http://www.doctrine-project.org">Doctrine</a> as the ORM of choice for any new PHP projects we work on.  I didn&#8217;t make this decision lightly as, until now, I have been a long time user and advocate of <a href="http://propel.phpdb.org">Propel</a> having given talks on it at PHP conferences and even a webinar or two.  So why the change?  That&#8217;s really not significant, what is significant is I think I can give a very quick punchlist of things about each that other PHP&#8217;er might find useful when evaluating them for themselves.</p>
<p><b>Propel</b></p>
<p><b>Pros</b> &#8211; First, let&#8217;s be clear I&#8217;m not talking about the pros of using an ORM. I&#8217;m talking about the good things that this ORM implementation brings to the table. Those are:</p>
<ul>
<li>Hydration Speed &#8211; You can argue you should never retrieve hydrated PHP objects from query if you don&#8217;t plan on taking some sort of save or delete action on it.  Yes, that&#8217;s true from a performance standpoint, however, if you are building a site where performance simply isn&#8217;t a concern then you&#8217;ll be pleased to know Propel can hydrate a set of objects quickly enough to be used in building a view (i.e. a data grid of some sort).</li>
<li>Classic Getters/Setters &#8211; You get these methods stubbed out in the base classes that Propel generates and you can override them easily.  I should note Doctrine can do similar sorts of things but not in a conventional way.</li>
<li>Support &#8211; The Propel mailing lists and IRC channel on freenode are pretty active, thought, not near as active as Doctrine&#8217;s.</li>
</ul>
<p><b>Cons</b></p>
<ul>
<li>Dependency hell &#8211; Propel has improved this but it&#8217;s still not perfect.  Back in the early days, before PDO, you needed Propel&#8217;s generator, <a href="http://phing.info">Phing</a> and <a href="http://creole.phpdb.org">Creole</a>.  Now you just need the generator and Phing. Phing is very much like Java&#8217;s Ant build tool.  While I understand and get why they use Phing, it adds a layer of complexity that makes it a barrier to new users.  Propel&#8217;s generator isn&#8217;t as bad as it is just a set of Phing targets to do Propel&#8217;s bidding.  If you come from .NET or Java using Phing won&#8217;t be a big deal but if you aren&#8217;t familiar with Ant or nAnt then Phing will come with a learning curve.</li>
<li>Criteria &#8211; Propel&#8217;s way to help ensure portable queries are built is via their Criteria object.  While I get the need for it, not having a explicit way to run native SQL short of getting a PDO connection and doing all the work that way is a short coming.  In fact, I despise Criteria so much I never use it, mainly because it doesn&#8217;t take too much work to hit a situation that Criteria either can&#8217;t handle well or make the code so complicated it&#8217;s not worth it.</li>
<li>No 5.3 namespace support &#8211; Let&#8217;s face it, we are all tired of Really_Long_Class_Names ala PEAR, Zend Framework, et. al.</li>
<li>Community &#8211; This is probably hard to blame on any one person but for a long time no work was done on Propel.  There was a change in project leads which took a long time and the development efforts took a while to get going.  I&#8217;m happy to say the team is active again, but a lot of ground was lost during the downtime.</li>
</ul>
<p><b>Doctrine</b></p>
<p><b>Pros</b></p>
<ul>
<li>No other dependencies.  Doing builds is easy as creating a simple PHP command line file and running it.  No Phing, no other external property files.</li>
<li>Magic finders &#8211; I love this.  Say you have a user table with a user_name field that has a unique index on it.  Retrieving this is as simple as
<pre>Doctrine::getTable('User')->findOneByUserName('janedoe');</pre>
<p>. Propel would require a few more lines setting up a Criteria object and running it.</li>
<li>Named Queries &#8211; This is something I pitched to the Propel development team quite a long time ago that always got a luke warm reception from the community.  I ended up implementing my own named query implementation which worked well enough that I never used Criteria.  With Doctrine you just get it out of the box:
<pre>
$this->addNamedQuery(
    'someQueryName',
    \Doctrine_Query::create()
        ->select('*')
        ->from('User u')
        ->where(user_name = ? AND 'password = ?')
);
</pre>
<p>Now I&#8217;m not totally in love with that syntax, it&#8217;s not much better than Criteria, honestly, however I go through that pain once and then I can just say:</p>
<pre>
$user = \Doctrine::getTable('User')->find('someQueryName', array('janedoe',SHA1($password)));
</pre>
<p>It&#8217;s also worth noting you can also use named queries to issue raw SQL, though, it will only return the raw recordset. Some of you are probably asking WTF? Named Queries?  Read up on them, decide for yourself if they are for you&#8230;all I can say is after having used an implementation for years I&#8217;m sold on it (maybe that can be a future blog post).
</li>
<li>
Documentation &#8211; Their documentation is top-notch.  Only improvement that is needed is comment support to the manuals.
</li>
<li>
Community &#8211; Let&#8217;s face it. Doctrine has gained some traction and all you need to do is follow the mailing lists, IRC and other community resources to see they simply get it.  Their partnership with Zend Framework is a shining example of good strides in this area.</li>
</ul>
<p><b>Cons</b></p>
<ul>
<li>Hydration Override &#8211; This one had me scratching my head the first time I noticed it.  By default, if you fetch an object by the same primary key twice you don&#8217;t get two different copies, you get a pointer to the most recent version.  On the surface that makes sense but there are a number of reasons I don&#8217;t like this as the default setting.  Luckily you can turn this off through a configuration setting when you initialize Doctrine.</li>
<li>Hydration Speed &#8211; This is my biggest complaints with Doctrine.  If you run a query that pulls a parent/child relationship (i.e. a customer and their orders) this take a lot of time with Doctrine&#8217;s hydration method.  The complexity is the circular references you can get.  I don&#8217;t know why Propel handles this so much better but the impact is you can&#8217;t use Doctrine&#8217;s hydrated objects in you views.  The way around this, I&#8217;ll call the Doctrine Way, is to have them hydrated as arrays.  You still get the parent&#8217;s children, you just aren&#8217;t working with a native PHP object.  When you think about it, it make sense, though I still prefer having a choice. The performance hit you take, even on simple queries, makes the array hydration mandatory if you are pulling more than one or two records from the database.</li>
<li>No 5.3 namespace support &#8211; It too doesn&#8217;t support namespaces yet.</li>
</ul>
<p>This isn&#8217;t meant to be a comprehensive review of either system, rather, a punchlist of noteable things.  I don&#8217;t feel this blog post is near comprehensive enough to base your decision on, rather, it can be used in addition to your findings.  I&#8217;d love to hear the other pros and cons from either camps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2010/02/comparing-propel-and-doctrine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Moving On</title>
		<link>http://www.tonybibbs.com/2009/12/moving-on/</link>
		<comments>http://www.tonybibbs.com/2009/12/moving-on/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 14:38:10 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[Geeklog]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/?p=285</guid>
		<description><![CDATA[<p>My guess is this will largely go un-noticed but I felt a formal blog post was in order for announcing my decision to stop contributing to AptitudeCMS and Geeklog.]]></description>
			<content:encoded><![CDATA[<p>My guess is this will largely go un-noticed but I felt a formal blog post was in order for announcing my decision to stop contributing to AptitudeCMS and Geeklog.</p>
<p>
I owe quite a bit to <a href="http://www.geeklog.net">Geeklog</a>&#8230;after installing Linux and PHP for the first time over 12 years ago I ran across Geeklog, learned a thing or two about open source development and started <a href="http://www.iowaoutdoors.org">Iowa Outdoors</a> (which I&#8217;ve since sold).  Not long after that I was fortunate enough to serve as the project lead for Geeklog before handing it off to the current lead, Dirk Haun.  Back then, there weren&#8217;t many viable options in the now overcrowded PHP CMS market.  Sadly, I&#8217;ve watched Geeklog&#8217;s popularity slowly decline to its current state.  That said, I have a few constructive things to say to the Geeklog community and the PHP community at large.</p>
<p>
First to the Geeklog community.  You&#8217;ve run into rough times.  WordPress, Joomla, Drupal and company really are the champions in this space.  Without doing more digging than I care to, I know Geeklog is far behind in any of the hard metrics that really matter (code commits, # of active developers, etc).  Just a hint of proof is had by comparing <a href="http://www.ohloh.net/p/geeklog">Geeklog&#8217;s Ohloh stats</a> with <a href="http://www.ohloh.net/p/wordpress">this</a>, <a href="http://www.ohloh.net/p/joomla">this</a> and <a href="http://www.ohloh.net/p/drupal">this</a>.  Then there those things you can&#8217;t quite quantify, the passion of the community and the level of innovation happening.  Right now I feel the Geeklog community is pretty stagnant.  Some of this is likely to be blamed on the <a href="http://www.glfusion.org/">fork of Geeklog</a> (whose <a href="http://www.ohloh.net/p/glfusion">Ohloh stats</a> don&#8217;t speak well either).  Fact is if you combine both glFusion and Geeklog&#8217;s numbers together it still paints a pretty bad picture.  You could argue they don&#8217;t need to aspire to be like WordPress, Joomla and Drupal which is fine but what I think has gotten lost in all of this nobody has consciously said if that&#8217;s the game they want to play and, if not, what differentiates Geeklog from the rest?  In the meantime, the set of features added over the past year or two suggest, in fact, they are playing catch-up to some of the features found in those other systems.  That&#8217;s not bad, but my point is Geeklog seems to lack a tangible goal. I guess that is part of the nature of open source&#8230;the perpetual, organic, itching of scratches but I still feel open source projects need to have long term visions far beyond the next commit, next point release and even next major release. With that said here&#8217;s some suggestions for Geeklog&#8217;s community in no particular order:</p>
<ul>
<li>Change your name &#8211; I attempted to address this with <a href="http://www.aptitudecms.org">AptitudeCMS</a> and failed but something has to be done.  I&#8217;m not sure if there is a precedent for a name change in a well established open source project but it has to happen for Geeklog.  To me it is branding 101.  For anybody outside of a blogger or hobbyist, it&#8217;s hard to take the Geeklog brand seriously.  Pointy haired managers scoff at such a name (I&#8217;ve seen it). Sure you risk confusing or alienating people but I feel Geeklog, as a brand, is hard to sell.  That said, even without a name change the remaining points are crucial.</li>
<li>Change your image &#8211; The Geeklog homepage screams mid-1990&#8242;s era design.  It&#8217;s the first impression we give users.  Even if you don&#8217;t want to compete directly with the bigger kids on the block, you can&#8217;t argue that <a href="http://www.joomla.org/">Joomla</a>, <a href="http://wordpress.org/">WordPress</a> and even the <a href="http://www.glfusion.org/">Geeklog fork</a> looks better.  It&#8217;s the first impression a user gets.  I think improving the Geeklog homepage will lead to more interest.  Once captivated, I have now doubt the codebase speaks for itself but, for now, the Geeklog homepage is forgettable for new users.</li>
<li>Get social &#8211; Geeklog is no where to be found on Twitter, Facebook, etc.  The missed opportunities here are, frankly, staggering.  The PHP community (as well as Drupal, Joomla, etc) all have a strong presence in these areas and I have no doubt the Geeklog community could benefit by joining the conversation.</li>
<li>Blog &#8211; Let&#8217;s face it, there isn&#8217;t much in the way of active Geeklog developers.  The ones there really need to blog about what&#8217;s going on behind the scenes.  What are you working on?  What&#8217;s a challenge you are facing? Any good commits lately?  This in part gets back to the goal setting discussion but it is more todo with giving the community a glimpse of what is going on.</li>
<li>Find a partner &#8211; Ok, this is probably one of the more controversial points and one that is often dodged in open source discussions but behind nearly all successful open source projects is an organization.  Sometimes it is not-for-profits but many times it is a private company or two.  Right now there isn&#8217;t a single Geeklog developer paid to work full time or even half-time on the core of the system.  Geeklog&#8217;s current codebase, in my opinion, has to be worth that investment.  I think part of the problem here has to do with the name, image and branding issues I brought up. That said, I know of a lot of organizations making selfish use of Geeklog without giving anything back.  No bugs, no code, no testing, no translations nada.  Zilch.  Now before the hardcore OSS supporters flame me, I&#8217;m not suggesting the project be effectively run by a company or an organization, rather, there should be enough of a community still where they can contribute developer hours to the project.  I believe strongly the project itself needs to remain organic able to change with the needs of those who lead&#8230;but that some investment by industry is needed.  Who will stand up?</li>
</ul>
<p>
Now to the PHP community at large.  As I look at AptitudeCMS, I see a body of work that started before there were any other PHP frameworks around.  I started with an MVC implementation.  I incorporated a simple template engine.  Later added an ORM.  Much of this happened over many employers and well before anybody uttered Zend Framework for the first time.  AptitudeCMS as a project is a failure in large part because it was never really released as a &#8220;formal&#8221; project until well after current PHP framework space became cluttered.  Fine, it is what it is.  However, to see this stuff rot and be used only when I have a new project come up seems silly.  I&#8217;m pleading, for my own sanity, don&#8217;t let this code go to waste.  Feel free to dissect it, borrow anything you find useful and laugh at any bad code you dig up.  Some areas of focus:</p>
<ul>
<li>MVCnPHP &#8211; It&#8217;s a viable alternative to Zend Framework&#8217;s MVC implementation.  It&#8217;s small, configureless and doesn&#8217;t present file contention issues common with ZF controllers.  I&#8217;m sure a Zender can point out ways around this but most ZF projects I&#8217;ve seen have all the logic in the controller which seems really wrong to me and is a bit painful when you have multiple developers working in the same controller.  Sure SVN, etc can handle the merge but you end up with a lot of merges.  MVCnPHP is much more atomic, view logic goes in a simple, small view class.  Command logic goes in a similar command class.  The controller is only responsible for routing requests between views and commands.  An upside to this is MVCnPHP also has basic support for tainted variables.  For the unaware, it&#8217;s a simple feature that notifies developers with exceptions when an unsanitized GET or POST variable is used.</li>
<li>Filtering &#8211; I built a filter class on top of Zend Framework that can easily be added to MVCnPHP views and commands.  Without much work it could also be incorporated into Zend Framework MVC implementations.  Look first <a href="http://www.aptitudecms.org/wiki/page/ACMSFIEO/">here</a> then see the &#8220;cool code&#8221; in the <a href="http://www.aptitudecms.org/trac/browser/AptitudeCMS/trunk/plugins/kernel/system/Filter.php">Filter class</a> which is nothing more than a class that passes calls thru to Zend&#8217;s library and then the <a href="http://www.aptitudecms.org/trac/browser/AptitudeCMS/trunk/plugins/kernel/system/views/ViewAbstract.php#L1010">abstract view that uses it</a>. I doubt the code will tickle you as is but I think conceptually it has merit for someone out there.</li>
<li>ORM->Form and Form->ORM &#8211; Because we use Propel we were able to dream up a way where we could hand a view an object and have it pre-fill from that object without us having to explicitly set the form field values.  Similarly, in our commands we found a handy way of creating the same ORM objects from the submitted form without having to explicitly map and set the ORM object&#8217;s values.  This was a huge time saver.  I think with a little work this code could be modified for Doctrine. Here&#8217;s how we map <a href="http://www.aptitudecms.org/trac/browser/AptitudeCMS/trunk/plugins/kernel/system/commands/CommandAbstract.php#L303">a form submission to a set of object(s)</a> and here is <a href="http://www.aptitudecms.org/trac/browser/AptitudeCMS/trunk/plugins/kernel/system/pear/apteno/mvcnphp/ViewFlexyAbstract.php#L738">mapping a object to the form</a></li>
</ul>
<p>
One thing I want to warn the community at large about is I&#8217;m seeing what feels to me like a trend in PHP to conform.  You could argue that this very blog post is me, in a way admitting defeat and conforming, but I want to state the obvious that you always have a choice.  It seems like many people are choosing to use part of a framework they have already installed instead of challenging whether or not it is the best tool for the job.  Just because a filter class is included in Zend Framework doesn&#8217;t mean you have to use it.  Just because ezComponents has a workflow component doesn&#8217;t mean you must employ it. Fact is AptitudeCMS includes Zend Framework, has some PEAR libraries and even some things like MVCnPHP.  You can argue bloat, file sizes, which is valid but I&#8217;m confident you can still cherry pick the best parts of a framework to give you something you can work with long term.  I&#8217;ve used Flexy instead of Smarty, MVCnPHP instead of Zend Framework and Propel instead of Doctrine.  Some could see those as one bad decision after another but it&#8217;s simply the result of a cherry picking exercise I did long ago.  Today I&#8217;d likely make different decisions but I can tell you I wouldn&#8217;t put all my eggs in one basket.  Nor should you.</p>
<p>
This blog entry, a self admission to failure, hopefully didn&#8217;t upset anybody along the way.  To be clear I&#8217;m the only one who failed here.  Maybe &#8220;fail&#8221; is too harsh a word as I&#8217;m quite happy to make this transition but I want to be clear to Dirk Haun, the Geeklog Project and those of you whom I&#8217;ve brushed IDE&#8217;s with are all people I very much respect.  I hate &#8220;losing&#8221; and this feels like a loss and will always feel that way.  If anybody makes use of any of these suggestions please pass that along in an email to me.  It will take a bit of the sting off.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2009/12/moving-on/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MVCnPHP v0.3.0 Released</title>
		<link>http://www.tonybibbs.com/2009/04/MVCnPHP-v0.3.0-Released/</link>
		<comments>http://www.tonybibbs.com/2009/04/MVCnPHP-v0.3.0-Released/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 14:09:04 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2009/04/MVCnPHP-v0.3.0-Released/</guid>
		<description><![CDATA[<p>Two weeks ago <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPProject">MVCnPHP</a> v0.3.0 was released into the wild.  This update really addresses only two things:</p>
<ol>
    <li>CSRF Protection - If your views use the built in support for Flexy (via the class BaseViewFlexy) then your forms will automatically have a Cross Site Request Forgery token added to the form as a hidden field along with having two cookies set to check the validity of that CSRF token.  The CSRF support is enabled by default which means all MVCnPHP commands that extend BaseCommand will automatically check the token for you.</li>
    <li>We've added the use of the __DIR__ magic PHP variable in the requirement statements.  Opcode caches, particularly <a href="http://www.php.net/apc">APC</a> optimize better when require's are used with absolute paths.</li>
</ol>
<p>As always we encourage you to <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPInstallation">download and install MVCnPHP</a>.  For faster notification on MVCnPHP news and releases be sure to follow <a href="http://www.twitter.com/aptenolc">AptenoLC</a> on <a href="http://www.twitter.com">Twitter</a></p>]]></description>
			<content:encoded><![CDATA[<p>Two weeks ago <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPProject">MVCnPHP</a> v0.3.0 was released into the wild.  This update really addresses only two things:</p>
<ol>
<li>CSRF Protection &#8211; If your views use the built in support for Flexy (via the class BaseViewFlexy) then your forms will automatically have a Cross Site Request Forgery token added to the form as a hidden field along with having two cookies set to check the validity of that CSRF token.  The CSRF support is enabled by default which means all MVCnPHP commands that extend BaseCommand will automatically check the token for you.</li>
<li>We&#8217;ve added the use of the __DIR__ magic PHP variable in the requirement statements.  Opcode caches, particularly <a href="http://www.php.net/apc">APC</a> optimize better when require&#8217;s are used with absolute paths.</li>
</ol>
<p>As always we encourage you to <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPInstallation">download and install MVCnPHP</a>.  For faster notification on MVCnPHP news and releases be sure to follow <a href="http://www.twitter.com/aptenolc">AptenoLC</a> on <a href="http://www.twitter.com">Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2009/04/MVCnPHP-v0.3.0-Released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webinar on Propel sponsored by php|architect</title>
		<link>http://www.tonybibbs.com/2009/03/Propel-Webinar/</link>
		<comments>http://www.tonybibbs.com/2009/03/Propel-Webinar/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 07:33:35 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2009/03/Propel-Webinar/</guid>
		<description><![CDATA[This is just a friendly reminder that this Friday, March 27th from 12pm-1pm CST I will be giving a webinar on using <a href="http://propel.phpdb.org">Propel</a>, an <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">object relational mapper (ORM)</a>.  This webinar is just <a href="http://tek.mtacon.com/c/s/free-webcast-series">one of a series</a> being sponsored by <a href="http://phparch.com">php&#124;architect</a>.  The webinar will focus on the basics of installing and using Propel as well as one or two more advanced topics.  If you are interested why not <a href="https://www2.gotomeeting.com/register/986890053">register now</a>!]]></description>
			<content:encoded><![CDATA[<p>This is just a friendly reminder that this Friday, March 27th from 12pm-1pm CST I will be giving a webinar on using <a href="http://propel.phpdb.org">Propel</a>, an <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">object relational mapper (ORM)</a>.  This webinar is just <a href="http://tek.mtacon.com/c/s/free-webcast-series">one of a series</a> being sponsored by <a href="http://phparch.com">php|architect</a>.  The webinar will focus on the basics of installing and using Propel as well as one or two more advanced topics.  If you are interested why not <a href="https://www2.gotomeeting.com/register/986890053">register now</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2009/03/Propel-Webinar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVCnPHP</title>
		<link>http://www.tonybibbs.com/2009/03/MVCnPHP-Announcement/</link>
		<comments>http://www.tonybibbs.com/2009/03/MVCnPHP-Announcement/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 06:19:51 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2009/03/MVCnPHP-Announcement/</guid>
		<description><![CDATA[I will start this blog entry by saying I like <a href="http://framework.zend.com">Zend Framework</a>.  I really do.  However, the part of ZF I don't use is the MVC implementation.  No, it's not bad.  Actually it's a good implementation that is the product of a lot of hard work by Zenders and non-Zenders alike.  I use bits and pieces of ZF in my PHP projects and, admittedly, Zend's MVC implementation never made the cut.  Why? 
<p>
I started using my first MVC implementation, Phrame,  back around 2002 long before ZF. I was quickly turned off by Phrame's Stuts-ish familiarity (no, I don't hate on Struts either).  The crux of my problem was the need to edit a bunch of files just to implement one page in my web application.  So started <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPProject">MVCnPHP</a>. That need to itch a scratch produced an MVC implementation that made it's way into my 9-to-5.  Over the next 7 years or so I did attempt to release MVCnPHP into the wild but never really polished it off.  Today I'm happy to announce that has changed.
<p>
Before I get into MVCnPHP let me circle back around to ZF.  Why didn't I adopt it's MVC implementation when it was released?  I considered it but the issue simply came down to my biased view of the design differences.  In fact, I was motivated to release MVCnPHP because of a project I recently inherited that uses the Zend MVC implementation.  The biggest difference between the ZF MVC implementation and MVCnPHP is MVCnPHP is meant to allow you to isolate views and commands into their own files and simply drop them into a directory then having your controller immediately aware of them.  I admit this quality of MVCnPHP isn't unique in the world of MVC implementations but this whole experience motivated me to really start working on polishing the code and documenting how to use it.  Today I'm happy to announce my first release of those efforts.
<p>
So to cut the fluff, here's a few things to get you started on MVCnPHP:
<ol>
<li>I know learning a new MVC implementation may appear time so to help you evaluate it you can see it in action with <a href="http://mvcnphp-demo.apteno.net/">this sample application</a> that not only excersizes most the features of MVCnPHP, it gives you quick access to the code behind the scenes.</li>
<li>After that why not <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPInstallation">download MVCnPHP</a>.  We have versions that support PHP 5.2.x and well as a release that support PHP 5.3 namespaces.</li>
<li>Once installed all you need to do use read the <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPGuide">MVCnPHP User Guide</a>. The guide is still a work in progress but it does cover most of what you need to get started.</li>
</ol>
<p>
I can barely contain my personal excitement for getting this out. MVCnPHP represents a library that brings the benefits of a model-view-controller implementation in a package that is small, yet packed full of features with no limits for being extended. I hope you all agree.]]></description>
			<content:encoded><![CDATA[<p>I will start this blog entry by saying I like <a href="http://framework.zend.com">Zend Framework</a>.  I really do.  However, the part of ZF I don&#8217;t use is the MVC implementation.  No, it&#8217;s not bad.  Actually it&#8217;s a good implementation that is the product of a lot of hard work by Zenders and non-Zenders alike.  I use bits and pieces of ZF in my PHP projects and, admittedly, Zend&#8217;s MVC implementation never made the cut.  Why?
<p>
I started using my first MVC implementation, Phrame,  back around 2002 long before ZF. I was quickly turned off by Phrame&#8217;s Stuts-ish familiarity (no, I don&#8217;t hate on Struts either).  The crux of my problem was the need to edit a bunch of files just to implement one page in my web application.  So started <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPProject">MVCnPHP</a>. That need to itch a scratch produced an MVC implementation that made it&#8217;s way into my 9-to-5.  Over the next 7 years or so I did attempt to release MVCnPHP into the wild but never really polished it off.  Today I&#8217;m happy to announce that has changed.
<p>
Before I get into MVCnPHP let me circle back around to ZF.  Why didn&#8217;t I adopt it&#8217;s MVC implementation when it was released?  I considered it but the issue simply came down to my biased view of the design differences.  In fact, I was motivated to release MVCnPHP because of a project I recently inherited that uses the Zend MVC implementation.  The biggest difference between the ZF MVC implementation and MVCnPHP is MVCnPHP is meant to allow you to isolate views and commands into their own files and simply drop them into a directory then having your controller immediately aware of them.  I admit this quality of MVCnPHP isn&#8217;t unique in the world of MVC implementations but this whole experience motivated me to really start working on polishing the code and documenting how to use it.  Today I&#8217;m happy to announce my first release of those efforts.
<p>
So to cut the fluff, here&#8217;s a few things to get you started on MVCnPHP:
<ol>
<li>I know learning a new MVC implementation may appear time so to help you evaluate it you can see it in action with <a href="http://mvcnphp-demo.apteno.net/">this sample application</a> that not only excersizes most the features of MVCnPHP, it gives you quick access to the code behind the scenes.</li>
<li>After that why not <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPInstallation">download MVCnPHP</a>.  We have versions that support PHP 5.2.x and well as a release that support PHP 5.3 namespaces.</li>
<li>Once installed all you need to do use read the <a href="http://www.apteno.net/AptitudeCMS/trac/wiki/MVCnPHPGuide">MVCnPHP User Guide</a>. The guide is still a work in progress but it does cover most of what you need to get started.</li>
</ol>
<p>
I can barely contain my personal excitement for getting this out. MVCnPHP represents a library that brings the benefits of a model-view-controller implementation in a package that is small, yet packed full of features with no limits for being extended. I hope you all agree.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2009/03/MVCnPHP-Announcement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP 5.2, Mac OS X Leopard and Oracle</title>
		<link>http://www.tonybibbs.com/2009/01/php-oracle-leopard/</link>
		<comments>http://www.tonybibbs.com/2009/01/php-oracle-leopard/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 10:30:58 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2009/01/php-oracle-leopard/</guid>
		<description><![CDATA[I wanted to give a heads-up to all the PHP, Mac and Oracle fans that I just had <a href="http://www.oracle.com/technology/pub/articles/bibbs-php-leopard.html">an article published on the Oracle Technology Network (OTN)</a>.  It's been in the works for months but has only just recently been published.  I have to give Christopher Jones a lot of credit for being patient wtih me.  The end result was an article that was fairly easy to write but was a bit of a pain. What you see in the final version is how to setup PHP, Apache and the Oracle Instant Client on a Macbook running Leopard.  The most unfortunate part of all this is I was unable to get all the moving parts working on stock version of Apache.  Instead I had to roll with a version of Apache I compiled from source.  For those of you interested in using Oracle the article walks you through the installation process pretty well.  It should also be noted I did confirm the same instructions worked flawlessly using the last PHP 5.3 alpha release.   To the skilled people in the PHP Community, if someone does figure out how to get this working with the stock version of Apache I would love to hear how you did it because that'd be ideal for most of us Mac users.  Comments aren't possible on the OTN version so feel free to add comments here.
]]></description>
			<content:encoded><![CDATA[<p>I wanted to give a heads-up to all the PHP, Mac and Oracle fans that I just had <a href="http://www.oracle.com/technology/pub/articles/bibbs-php-leopard.html">an article published on the Oracle Technology Network (OTN)</a>.  It&#8217;s been in the works for months but has only just recently been published.  I have to give Christopher Jones a lot of credit for being patient wtih me.  The end result was an article that was fairly easy to write but was a bit of a pain. What you see in the final version is how to setup PHP, Apache and the Oracle Instant Client on a Macbook running Leopard.  The most unfortunate part of all this is I was unable to get all the moving parts working on stock version of Apache.  Instead I had to roll with a version of Apache I compiled from source.  For those of you interested in using Oracle the article walks you through the installation process pretty well.  It should also be noted I did confirm the same instructions worked flawlessly using the last PHP 5.3 alpha release.   To the skilled people in the PHP Community, if someone does figure out how to get this working with the stock version of Apache I would love to hear how you did it because that&#8217;d be ideal for most of us Mac users.  Comments aren&#8217;t possible on the OTN version so feel free to add comments here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2009/01/php-oracle-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Security Demo</title>
		<link>http://www.tonybibbs.com/2008/10/Web-Security-Demo/</link>
		<comments>http://www.tonybibbs.com/2008/10/Web-Security-Demo/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 14:58:58 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/10/Web-Security-Demo/</guid>
		<description><![CDATA[<p>Yesterday, on an invitation from our <a href="http://secureonline.iowa.gov/about_iso/index.html">Information Security Office (ISO)</a>, I had the pleasure of giving a talk on about injection flaws, Cross Site Scripting (CSS) and Cross Site Request Forgeries (CSRF).  That talk had a surprisingly large turnout and crowd participation was good.  Anyway, I took my <a href="http://www.slideshare.net/tonybibbs/cross-site-request-forgery">old talk on CSRF</a> and expanded it to include a very simple PHP script (roughly 60 lines of code) that had 2 SQL injection flaws, 2 XSS flaws and a CSRF flaw to boot.  I demo'd the flaws (sample input included) and I provided another script that shows some of the fixes you can make to sure it.  I've made the slides you see below along with my sample code and the MySQL database available in <a href="http://www.tonybibbs.com/WebSecurity.zip">this ZIP file</a>.  For anybody with a working PHP/MySQL setup it would take seconds to stand up and you have something you can play with to see how you can take my simple hacks and turn them into something more serious.  Please add a comment below if you find any problems or have any questions.</p>
<p>&#160;</p>
<p>&#160;</p>
<center>
<div id="__ss_650164" style="width: 425px; text-align: left;"><a title="Web Security Overview and Demo" href="http://www.slideshare.net/tonybibbs/web-security-overview-and-demo-presentation?type=powerpoint" style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;">Web Security Overview and Demo</a><object height="355" width="425" style="margin: 0px;">
<param value="http://static.slideshare.net/swf/ssplayer2.swf?doc=websecurity-1223671860798344-9&#38;stripped_title=web-security-overview-and-demo-presentation" name="movie" />
<param value="true" name="allowFullScreen" />
<param value="always" name="allowScriptAccess" /><embed height="355" width="425" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=websecurity-1223671860798344-9&#38;stripped_title=web-security-overview-and-demo-presentation"></embed></object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a title="View Web Security Overview and Demo on SlideShare" href="http://www.slideshare.net/tonybibbs/web-security-overview-and-demo-presentation?type=powerpoint" style="text-decoration: underline;">presentation</a> or <a href="http://www.slideshare.net/upload?type=powerpoint" style="text-decoration: underline;">Upload</a> your own. (tags: <a href="http://slideshare.net/tag/xss" style="text-decoration: underline;">xss</a> <a href="http://slideshare.net/tag/sql" style="text-decoration: underline;">sql</a>)</div>
</div>
</center>
<p>&#160;</p>]]></description>
			<content:encoded><![CDATA[<p>Yesterday, on an invitation from our <a href="http://secureonline.iowa.gov/about_iso/index.html">Information Security Office (ISO)</a>, I had the pleasure of giving a talk on about injection flaws, Cross Site Scripting (CSS) and Cross Site Request Forgeries (CSRF).  That talk had a surprisingly large turnout and crowd participation was good.  Anyway, I took my <a href="http://www.slideshare.net/tonybibbs/cross-site-request-forgery">old talk on CSRF</a> and expanded it to include a very simple PHP script (roughly 60 lines of code) that had 2 SQL injection flaws, 2 XSS flaws and a CSRF flaw to boot.  I demo&#8217;d the flaws (sample input included) and I provided another script that shows some of the fixes you can make to sure it.  I&#8217;ve made the slides you see below along with my sample code and the MySQL database available in <a href="http://www.tonybibbs.com/WebSecurity.zip">this ZIP file</a>.  For anybody with a working PHP/MySQL setup it would take seconds to stand up and you have something you can play with to see how you can take my simple hacks and turn them into something more serious.  Please add a comment below if you find any problems or have any questions.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><center>
<div id="__ss_650164" style="width: 425px; text-align: left;"><a title="Web Security Overview and Demo" href="http://www.slideshare.net/tonybibbs/web-security-overview-and-demo-presentation?type=powerpoint" style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;">Web Security Overview and Demo</a><object height="355" width="425" style="margin: 0px;"><param value="http://static.slideshare.net/swf/ssplayer2.swf?doc=websecurity-1223671860798344-9&amp;stripped_title=web-security-overview-and-demo-presentation" name="movie" /><param value="true" name="allowFullScreen" /><param value="always" name="allowScriptAccess" /><embed height="355" width="425" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=websecurity-1223671860798344-9&amp;stripped_title=web-security-overview-and-demo-presentation"></embed></object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a title="View Web Security Overview and Demo on SlideShare" href="http://www.slideshare.net/tonybibbs/web-security-overview-and-demo-presentation?type=powerpoint" style="text-decoration: underline;">presentation</a> or <a href="http://www.slideshare.net/upload?type=powerpoint" style="text-decoration: underline;">Upload</a> your own. (tags: <a href="http://slideshare.net/tag/xss" style="text-decoration: underline;">xss</a> <a href="http://slideshare.net/tag/sql" style="text-decoration: underline;">sql</a>)</div>
</div>
<p></center>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/10/Web-Security-Demo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP 5.3 on Mac OS X 10.5</title>
		<link>http://www.tonybibbs.com/2008/07/PHP-5_3-on-10.5/</link>
		<comments>http://www.tonybibbs.com/2008/07/PHP-5_3-on-10.5/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 10:45:28 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/07/PHP-5_3-on-10.5/</guid>
		<description><![CDATA[Being the recent (and appreciative) recipient of a MacBook I've been getting all the usual development tools installed.  Everything went pretty much as expected until I got to where I wanted to compile <a href="http://www.php.net">PHP5</a>.  Not just any flavor of PHP5 but a snapshot of PHP 5.3.  While this focuses on 5.3 you'd have to do the same song and dance for the PHP 5.2 source.  Why?
<p>
If there is anything you should gleam from this article for future reference, Leopard comes with a 64bit Apache installation. Thus if I go into the PHP 5.3 source and tried, say:
<pre>
#>./configure --with-png --with-tiff --with-jpeg &#092;
--with-gd --enable-soap --with-apxs2 
</pre>
<p>
It my configure, may even compile but when you install and restart Apache you'd get errors about the PHP module being of the wrong architecture.  I confirmed this using the "file" command.  After that I started down the path of "well, let's just compile to 64 bit".  I did find references that suggest trying to add <i>CFLAGS="-arch x86_64"</i> to your configure statement but that didn't work either.  You might be able to get this working if you dink with it enough, however, I was in "get it working" mode.  I did find <a href="http://www.entropy.ch/blog/Mac+OS+X/2007/10/30/Leopard-Four-Way-Universal-Binaries.html">this blog post</a> by Marc Liyanage which gives more details into what is going on.  Turns out this 64-bit problem is much bigger than just PHP because I was unable to get the fink libraries for stuff like libpng, etc to compile to 64bit.  Now maybe you can do this by downloading the individual packages and compiling them one-by-one but I'm far too lazy for that.
<p>
The fix?  Run Apache in 32-bit mode.  Not knowing anything about Mac and that some binaries are compiled to support multiple architectures I was hanging out in #apache on irc.freenode.net trying to figure out the best way to compile Apache under OS X.  At the same time I posted to <a href="http://forums.macosxhints.com/showthread.php?t=92413">macosxhints.com</a> and got a very simple, elegant answer that didn't require me to download and recompile Apache:
<pre>
sudo cp /usr/sbin/httpd /usr/sbin/httpd-fat
sudo lipo /usr/sbin/httpd -thin i386 -output /usr/sbin/httpd
</pre>
After that using my standard ./configure worked just fine and I now have PHP 5.3a1 working beautifully.  That said, I'd love to hear from anybody that has managed to get PHP 5.3 (and required libraries) compiled using the 64-bit Apache.]]></description>
			<content:encoded><![CDATA[<p>Being the recent (and appreciative) recipient of a MacBook I&#8217;ve been getting all the usual development tools installed.  Everything went pretty much as expected until I got to where I wanted to compile <a href="http://www.php.net">PHP5</a>.  Not just any flavor of PHP5 but a snapshot of PHP 5.3.  While this focuses on 5.3 you&#8217;d have to do the same song and dance for the PHP 5.2 source.  Why?
<p>
If there is anything you should gleam from this article for future reference, Leopard comes with a 64bit Apache installation. Thus if I go into the PHP 5.3 source and tried, say:
<pre>
#>./configure --with-png --with-tiff --with-jpeg &#092;
--with-gd --enable-soap --with-apxs2
</pre>
<p>
It my configure, may even compile but when you install and restart Apache you&#8217;d get errors about the PHP module being of the wrong architecture.  I confirmed this using the &#8220;file&#8221; command.  After that I started down the path of &#8220;well, let&#8217;s just compile to 64 bit&#8221;.  I did find references that suggest trying to add <i>CFLAGS=&#8221;-arch x86_64&#8243;</i> to your configure statement but that didn&#8217;t work either.  You might be able to get this working if you dink with it enough, however, I was in &#8220;get it working&#8221; mode.  I did find <a href="http://www.entropy.ch/blog/Mac+OS+X/2007/10/30/Leopard-Four-Way-Universal-Binaries.html">this blog post</a> by Marc Liyanage which gives more details into what is going on.  Turns out this 64-bit problem is much bigger than just PHP because I was unable to get the fink libraries for stuff like libpng, etc to compile to 64bit.  Now maybe you can do this by downloading the individual packages and compiling them one-by-one but I&#8217;m far too lazy for that.
<p>
The fix?  Run Apache in 32-bit mode.  Not knowing anything about Mac and that some binaries are compiled to support multiple architectures I was hanging out in #apache on irc.freenode.net trying to figure out the best way to compile Apache under OS X.  At the same time I posted to <a href="http://forums.macosxhints.com/showthread.php?t=92413">macosxhints.com</a> and got a very simple, elegant answer that didn&#8217;t require me to download and recompile Apache:
<pre>
sudo cp /usr/sbin/httpd /usr/sbin/httpd-fat
sudo lipo /usr/sbin/httpd -thin i386 -output /usr/sbin/httpd
</pre>
<p>After that using my standard ./configure worked just fine and I now have PHP 5.3a1 working beautifully.  That said, I&#8217;d love to hear from anybody that has managed to get PHP 5.3 (and required libraries) compiled using the 64-bit Apache.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/07/PHP-5_3-on-10.5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book Review: Pro PHP</title>
		<link>http://www.tonybibbs.com/2008/06/Book-Review-Pro-PHP/</link>
		<comments>http://www.tonybibbs.com/2008/06/Book-Review-Pro-PHP/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 08:02:00 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/06/Book-Review-Pro-PHP/</guid>
		<description><![CDATA[On my flight to the <a href="http://www.dcphpconference.com">DC PHP Conference</a> in Washington D.C. I had a chance to read a copy of  <a href="http://www.amazon.com/Pro-PHP-Patterns-Frameworks-Testing/dp/1590598199">Pro PHP: Patterns, Frameworks, Testing and More</a> written by Kevin McArthur.  I've never written a book, I clearly don't have a first hand appreciation for the amount of work that undoubtedly goes on under the hood.  Given that I will try to be as constructive with this review as possible.
]]></description>
			<content:encoded><![CDATA[<p>On my flight to the <a href="http://www.dcphpconference.com">DC PHP Conference</a> in Washington D.C. I had a chance to read a copy of  <a href="http://www.amazon.com/Pro-PHP-Patterns-Frameworks-Testing/dp/1590598199">Pro PHP: Patterns, Frameworks, Testing and More</a> written by Kevin McArthur.  I&#8217;ve never written a book, I clearly don&#8217;t have a first hand appreciation for the amount of work that undoubtedly goes on under the hood.  Given that I will try to be as constructive with this review as possible.<br />
First I think it&#8217;s important to cover the valuable aspects of the book as that will really drive your decision whether the book is worth a read.  If you are new to object oriented programming and basic design patterns you will get a fairly good introduction of how to do both in PHP.  Part 1, <i>OOP and Patterns</i>, covers things like abstract classes, interfaces, exception handling and a couple of design patterns.  The list of valuable design patterns in this section of the books is far from exhaustive so I&#8217;d strongly encourage you to supplement what is in this book with a book dedicated to patterns (as well as anti-patterns).  One of the best chapters in Part 1 is on Exceptions and I was specifically glad to see Kevin articulate when *not* to use exceptions as it is my experience they are often over used and used improperly.  Sort of the square peg in a round hole in Part 1 was a section on what&#8217;s new in PHP6 which, in my opinion, is a bit premature and it should be noted that some of the features listed in PHP6, specifically the support of namespaces, may actually show up sooner than advertised (PHP rumor mill suggests namespaces may make it into version 5.3 which is further rumored to be out around the first of next year).  Because this Part of the book is five chapters yet only 52 pages don&#8217;t expect a ton of detail on object oriented programming and design patterns, though, you will get a decent introduction.
<p>
The order of where things showed up in this book was a problem for me.  Part 2 is on Testing and Documentation while Part 4 is dedicated to the Model-View-Controller (MVC) design pattern.  At the very least Part 4 should follow Part 1&#8242;s discussion on design patterns and, better yet, all of Part 4 should have been merged with Part 1.  That said, I was pretty happy with the talk on testing and documentation.  Kevin does a good job talking through the use of <a href="http://www.phpdoc.org/">PHPDoc</a> and <a href="http://www.phpunit.de/">PHPUnit</a> both of which should be in any PHP developer&#8217;s toolbox.  Part 2 also has a good discussion on Reflection which, back to the organization of the book, could have probably been a better fit in the discussion of object oriented programming, though, he did have a lengthy section on parsing reflection-based documentation data.  Kevin did a great job covering the topic of reflection but I was a bit surprised to see no mention of how using reflection can negatively impact performance of your PHP application.  Which brings me to my biggest criticism of the book.
<p>
With a title like &#8220;Pro PHP&#8221; I&#8217;d expect a few chapters dedicated to performance, scalability and security.  While I&#8217;m a huge fan of object oriented programming and <a href="http://www.tonybibbs.com/article.php/DCPHP-Slides">know a bit about the value software frameworks</a> they often work counter to scalability and performance.  This book had no mention of opcode caching, no discussion on application caching, database caching and the use of shared memory (RAM).  Maybe that is intended to be another book in and of itself?  Nonetheless, having a chapter or two on security is something that is needed if we want to <a href="http://www.internetnews.com/dev-news/article.php/3631831">fix the internet</a>.  Indeed application security is the subject of many books so I wouldn&#8217;t expect a book on &#8220;Pro PHP&#8221; to be exhaustive but today&#8217;s hackers are trending toward looking for applications holes instead of networking holes because a) they are usually easier to exploit and b) there are a lot of applications looking to be exploited.  XSS, CSRF, SQL Injection, etc are all things developers need to be conscious of when writing code (regardless of language) and ignoring security is this book seems to be a bit irresponsible.  I know, I know&#8230;tough words and, again, you can only effectively cover so much in one book but security definitely should have made the cut.
<p>
Part 3 covered the <a href="http://www.php.net/manual/en/book.spl.php">The Standard PHP Library (SPL)</a>.  This quite possibly was one of the strongest points of the book.  SPL&#8217;s top features are iterators of all sorts, file and directory handling and advanced array handling.  Kevin covers all this and more in great detail.  I was surprised to learn how many different types of iterators supported by SPL and I would recommend this entire book based on how well SPL was covered.
<p>
Part 4 of Pro PHP does a good job covering the most essential parts of the <a href="http://framework.zend.com">Zend Framework</a> particularly they MVC implementation, logging and access control.  In the world of PHP frameworks Zend is becoming more of a household name but I&#8217;d simply add that there are a lot of PHP frameworks out there.  While the author is clearly a fan of the Zend Framework and does a good job showcasing some of it&#8217;s strengths please leave knowing they aren&#8217;t they only game in town.
<p>
AJAX/JSON and Web Services via SOAP are covered by Part 5 of the book.  AJAX and JSON in PHP can also be it&#8217;s own book given all the AJAX libraries out there.  Kevin does a great job giving a quick overview of AJAX and talks a bit on how to use it with the Zend Framework.  This will only wet your appetite on the subject but I felt it was a pretty good start.  The following chapters focused exclusively on Web Services and SOAP.  PHP5 has solid support for SOAP minus some interoperability issues and Kevin covers this well.  As a shameless plug I&#8217;d also point anybody doing SOAP-based web services in PHP to check out the <a href="http://www.tonybibbs.com/article.php/PHP-SOAP-Toolkit">PHP SOAP Toolket (PST)</a>  which works around some of the interop issues.  Additionally I&#8217;d also point you to <a href="http://www.apteno.net/code/wsdl.php">this utility</a> that gives you all the features of PST without having to install a thing.  I digress&#8230;back to the book.  One thing I feel that PHP is really good at is support for REST-based services which is largely ignored by this book.  I think in a book like this you can only effectively cover one of either SOAP and REST, however, I would have liked to see REST at least mentioned and a quick comparison of when you might use one versus the other.
<p>
This book has also been reviewed by <a href="http://www.google.com/search?q=Pro+PHP+pattens+frameworks&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=com.ubuntu:en-US:official&amp;client=firefox-a">a number of other talented people</a> so please feel free to factor their opinions in with mine to see if this is a book for you.  I honestly do feel this book has a place on your bookshelf particularly for those just diving in more advanced PHP development.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/06/Book-Review-Pro-PHP/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP SOAP Toolkit</title>
		<link>http://www.tonybibbs.com/2008/06/PHP-SOAP-Toolkit/</link>
		<comments>http://www.tonybibbs.com/2008/06/PHP-SOAP-Toolkit/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 13:40:19 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/06/PHP-SOAP-Toolkit/</guid>
		<description><![CDATA[Michael Tutty, a friend and co-worker, gave the below talk at the <a href="http://www.dcphpconference.com">DC PHP Conference</a> .  PHP SOAP Toolkit is a handy way to fill-in some of the "missing" pieces of SOAP support in PHP that make implementing both SOAP services and clients in a way that is inter-operable with other languages like .NET and Java.  If you are interested in getting your feet wet with PHP and SOAP particularly with contract-first type of development you can take your <a href="http://en.wikipedia.org/wiki/WSDL">WSDL</a> on over <a href="http://www.apteno.net/code/wsdl.php">here</a> where you can quickly turn it into a downloadable PHP SOAP client that supports code completion.
<p>
<center>
<div style="width:425px;text-align:left" id="__ss_445096"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=soaptoolkitdcphp-1212522528655431-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=soaptoolkitdcphp-1212522528655431-8" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/mtutty/soap-toolkit-dcphp-445096?src=embed" title="View Soap Toolkit Dcphp on SlideShare">View Full Size</a></div></div>
</center>]]></description>
			<content:encoded><![CDATA[<p>Michael Tutty, a friend and co-worker, gave the below talk at the <a href="http://www.dcphpconference.com">DC PHP Conference</a> .  PHP SOAP Toolkit is a handy way to fill-in some of the &#8220;missing&#8221; pieces of SOAP support in PHP that make implementing both SOAP services and clients in a way that is inter-operable with other languages like .NET and Java.  If you are interested in getting your feet wet with PHP and SOAP particularly with contract-first type of development you can take your <a href="http://en.wikipedia.org/wiki/WSDL">WSDL</a> on over <a href="http://www.apteno.net/code/wsdl.php">here</a> where you can quickly turn it into a downloadable PHP SOAP client that supports code completion.
<p>
<center>
<div style="width:425px;text-align:left" id="__ss_445096"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=soaptoolkitdcphp-1212522528655431-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=soaptoolkitdcphp-1212522528655431-8" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/mtutty/soap-toolkit-dcphp-445096?src=embed" title="View Soap Toolkit Dcphp on SlideShare">View Full Size</a></div>
</div>
<p></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/06/PHP-SOAP-Toolkit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DCPHP Slides</title>
		<link>http://www.tonybibbs.com/2008/06/DCPHP-Slides/</link>
		<comments>http://www.tonybibbs.com/2008/06/DCPHP-Slides/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 13:42:00 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/06/DCPHP-Slides/</guid>
		<description><![CDATA[Thanks for all who showed up to my talk at the <a href="http://www.dcphpconference.com">DC PHP Conference</a> on "Fed Up of Framework Hype?".  The slides are below and I'm sure some will ask about MVCnPHP which can be downloaded <a href="http://pear.geeklog.net/index.php?package=MVCnPHP&#038;downloads">here</a>.  I know MVCnPHP isn't quite documented as much as I'd like...please ask questions OR wait as I will likely have a blog post about how to get started with it.
<p>
<center>
<div style="width:425px;text-align:left" id="__ss_441376"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=fedupofframeworkhypedcphp-1212380238526133-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=fedupofframeworkhypedcphp-1212380238526133-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/tonybibbs/fed-up-of-framework-hype-dcphp?src=embed" title="View Fed Up Of Framework Hype Dcphp on SlideShare">View Fullsize</a></div></div></center>]]></description>
			<content:encoded><![CDATA[<p>Thanks for all who showed up to my talk at the <a href="http://www.dcphpconference.com">DC PHP Conference</a> on &#8220;Fed Up of Framework Hype?&#8221;.  The slides are below and I&#8217;m sure some will ask about MVCnPHP which can be downloaded <a href="http://pear.geeklog.net/index.php?package=MVCnPHP&#038;downloads">here</a>.  I know MVCnPHP isn&#8217;t quite documented as much as I&#8217;d like&#8230;please ask questions OR wait as I will likely have a blog post about how to get started with it.
<p>
<center>
<div style="width:425px;text-align:left" id="__ss_441376"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=fedupofframeworkhypedcphp-1212380238526133-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=fedupofframeworkhypedcphp-1212380238526133-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/tonybibbs/fed-up-of-framework-hype-dcphp?src=embed" title="View Fed Up Of Framework Hype Dcphp on SlideShare">View Fullsize</a></div>
</div>
<p></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/06/DCPHP-Slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cutting Use of Zend_Log in Half</title>
		<link>http://www.tonybibbs.com/2008/05/Cutting-Use-of-Zend_Log-in-Half/</link>
		<comments>http://www.tonybibbs.com/2008/05/Cutting-Use-of-Zend_Log-in-Half/#comments</comments>
		<pubDate>Fri, 30 May 2008 09:03:00 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/05/Cutting-Use-of-Zend_Log-in-Half/</guid>
		<description><![CDATA[As part of the framework we use at work, we borrow what we feel are the best components out there and logging is a key part of that.  Logging should be simple to setup, easy to use and should minimize work on the developer.  After all, you are going to do a lot of logging, right?  We use Zend_Log exclusively and while I like it when coupled with Zend_Registry you've always got the following two lines of code:

<pre>
    // at the beginning of our application (in a singleton or in 
    // index.php at the very least)
    &#36;logger = new Zend_Log(&#36;writer);
    &#36;registry-&#62;set(?logger? , &#36;logger);

    // Every time you log you have these two lines.
    &#36;logger = Zend_Registry::get(?logger?);
    &#36;logger-&#62;log(&#36;errorMessage,1);
</pre>

Not bad, not bad at all.  In fact Zend_Registry is a handy little class.  But why call Zend_Registry::get() explicitly over and over if you don't have to?  I mean wouldn't it be nice if you could simply do:

<pre>
MyLog::log('SomeMessage', Zend_Log::DEBUG);
</pre>

That's right, let's log things statically and let all the magic happen behind the scenes.  We'll do just that with a small bit of code and best of all you won't even need Zend_Registry (again, great class but why use it if you don't need it).  How?  Well you need to use something that acts like Zend_Registry but allows us to log messages statically.  To do that we'll create a new class called MyLog and the first thing is the allow the application (or any plugins) to register their loggers (click read more):
&#160;
]]></description>
			<content:encoded><![CDATA[<p>As part of the framework we use at work, we borrow what we feel are the best components out there and logging is a key part of that.  Logging should be simple to setup, easy to use and should minimize work on the developer.  After all, you are going to do a lot of logging, right?  We use Zend_Log exclusively and while I like it when coupled with Zend_Registry you&#8217;ve always got the following two lines of code:</p>
<pre>
    // at the beginning of our application (in a singleton or in
    // index.php at the very least)
    &#36;logger = new Zend_Log(&#36;writer);
    &#36;registry-&gt;set(?logger? , &#36;logger);

    // Every time you log you have these two lines.
    &#36;logger = Zend_Registry::get(?logger?);
    &#36;logger-&gt;log(&#36;errorMessage,1);
</pre>
<p>Not bad, not bad at all.  In fact Zend_Registry is a handy little class.  But why call Zend_Registry::get() explicitly over and over if you don&#8217;t have to?  I mean wouldn&#8217;t it be nice if you could simply do:</p>
<pre>
MyLog::log('SomeMessage', Zend_Log::DEBUG);
</pre>
<p>That&#8217;s right, let&#8217;s log things statically and let all the magic happen behind the scenes.  We&#8217;ll do just that with a small bit of code and best of all you won&#8217;t even need Zend_Registry (again, great class but why use it if you don&#8217;t need it).  How?  Well you need to use something that acts like Zend_Registry but allows us to log messages statically.  To do that we&#8217;ll create a new class called MyLog and the first thing is the allow the application (or any plugins) to register their loggers (click read more):<br />
&nbsp;
<pre>
public static function registerLogger(&#36;loggerName, &#36;zendWriter = '',
    &#36;isDefault = false)
{
    if (!isset(self::&#36;instances[&#36;loggerName])) {
        self::&#36;instances[&#36;loggerName] = new Zend_Log(&#36;zendWriter);
    }

    // If we weren't told this is the default logger yet none exists then force it
    if (!self::getDefaultLoggerName() AND !&#36;isDefault) &#36;isDefault = true;
        if (&#36;isDefault) {
            if (isset(self::&#36;defaultLogger)) {
                throw new Exception('Default logger is already defined');
            }
            self::&#36;defaultLogger = &#36;loggerName;
        }
    }
</pre>
<p>The &#36;loggerName is a logical name given to the logger you are registering.  This must be unique.  &#36;zendWriter is one of the many Zend_Writer children you can use.  Finally &#36;isDefault indicates if the logger given will serve as the default logger.  This will allow us to use shorter notation in our application.  Ok, once you have this you can register all your loggers:
<pre>
// You only ever do these once
MyLog::registerLogger('kernel', new Zend_Log_Writer_Stream(getOption('logFile')), true);
MyLog::registerLogger('somePlugin', new Zend_Log_Writer_Stream(getOption('path_logs') .
    'SomePlugin.log'));
MyLog::registerLogger('propel', new Zend_Log_Writer_Stream(getOption('path_logs') .
    'Propel.log'));
</pre>
<p>This then allow us to log a message with a <i>single</i> line with any of the following
<pre>
// Log to the default 'kernel' logger with only an informational message.
// Default log level is Zend_Log::INFO
MyLog::log('Kernel starting up');
// Log to plugin's log
MyLog::log('Plugin failed to initialize', Zend_Log::ERR, 'somePlugin');
</pre>
<p>While the above is nice we can improve by providing simple pass through functions for each Zend_Log log level:
<pre>
// Same log to the kernel from above but shorter
MyLog::info('Kernel starting up');
// Log to plugin log like above but shorter
MyLog::err('Plugin failed to initialize', 'somePlugin');
</pre>
<p>If you like all this logging goodness you simply need to grab <a href="http://www.apteno.net/aptitude/trac/browser/system/Log.php">this file</a> along with <a href="http://framework.zend.com/manual/en/zend.log.html">Zend_Log</a> and you are on your way.  Please note the requires at the beginning of the class I&#8217;m providing.  It is using a method called getOption() which you will either need to implement or replace it with relative pathing.  We do it this way because we&#8217;ve optimized our application to use APC which likes a) require instead of require_once and b) absolute paths over relative paths.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/05/Cutting-Use-of-Zend_Log-in-Half/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Government in the Web 2.0 World</title>
		<link>http://www.tonybibbs.com/2008/05/Government-in-the-Web-2.0-World/</link>
		<comments>http://www.tonybibbs.com/2008/05/Government-in-the-Web-2.0-World/#comments</comments>
		<pubDate>Wed, 28 May 2008 15:35:00 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/05/Government-in-the-Web-2.0-World/</guid>
		<description><![CDATA[In a rare moment when <a href="http://www.twitter.com">Twitter</a> was up <a href="http://www.jansch.nl/2008/05/26/phptek-2008-day-3-and-wrap-up/">Ivo Jansch</a> put me on to one of his recaps of <a href="http://tek.phparch.com/">php&#124;tek</a> and I was particularly interested in a presentation by <a href="http://www.terrychay.com">Terry Chay</a>.  If you haven't heard Terry talk there are two things you will leave with:
<ol>
<li>Your quota for the f-bomb.  I know it may sound unprofessional but he does manage to use it to draw attention to the things that really deserve it.  Truth told, though, he does simply enjoy cussing.</li>
<li>A bunch of web programming goodness particularly around web development and PHP</li>
</ol>

In Ivo's recap one thing that stood out for me was his declaration that when developing an application it is important to consider Stability, Scalability, Speed and Security and handling them in that order.  Those four S's aren't anything new to me but the assertion that they had to be in a specific order was and it is one I couldn't disagree with more (for the right reason's I promise).  So why do I disagree?  
<p>
In truth I only partially disagree.  If your job is more one with an eye toward engineering the next great, viral application then he's absolutely right.  <a href="http://www.twitter.com">Twitter</a> is learning this the hard way, whereas Digg, Facebook, Yahoo! and others successfully figured this out.  Then there is me, the government IT worker not focused on any one site, rather, building a large number of smaller sites.  Now you could argue that states like California, Florida, Texas, etc have enough of a population base to justify the same Chay philosophy here but generally my experience is that for government the order really ought to be Stability, Security, Speed and Scalability.  Why?
]]></description>
			<content:encoded><![CDATA[<p>In a rare moment when <a href="http://www.twitter.com">Twitter</a> was up <a href="http://www.jansch.nl/2008/05/26/phptek-2008-day-3-and-wrap-up/">Ivo Jansch</a> put me on to one of his recaps of <a href="http://tek.phparch.com/">php|tek</a> and I was particularly interested in a presentation by <a href="http://www.terrychay.com">Terry Chay</a>.  If you haven&#8217;t heard Terry talk there are two things you will leave with:
<ol>
<li>Your quota for the f-bomb.  I know it may sound unprofessional but he does manage to use it to draw attention to the things that really deserve it.  Truth told, though, he does simply enjoy cussing.</li>
<li>A bunch of web programming goodness particularly around web development and PHP</li>
</ol>
<p>In Ivo&#8217;s recap one thing that stood out for me was his declaration that when developing an application it is important to consider Stability, Scalability, Speed and Security and handling them in that order.  Those four S&#8217;s aren&#8217;t anything new to me but the assertion that they had to be in a specific order was and it is one I couldn&#8217;t disagree with more (for the right reason&#8217;s I promise).  So why do I disagree?
<p>
In truth I only partially disagree.  If your job is more one with an eye toward engineering the next great, viral application then he&#8217;s absolutely right.  <a href="http://www.twitter.com">Twitter</a> is learning this the hard way, whereas Digg, Facebook, Yahoo! and others successfully figured this out.  Then there is me, the government IT worker not focused on any one site, rather, building a large number of smaller sites.  Now you could argue that states like California, Florida, Texas, etc have enough of a population base to justify the same Chay philosophy here but generally my experience is that for government the order really ought to be Stability, Security, Speed and Scalability.  Why?
<ol>
<li><b>Stability</b> &#8211; Let&#8217;s face it, if the application isn&#8217;t stable the other three S&#8217;s don&#8217;t matter.  Using my own original <a href="http://phpdoc.info/chayism/">Chayism</a> a secure, fast and scalable piece of sh*t is nothing more than that.  An over-engineered piece of sh*t.  Terry and I seem to agree here.</li>
<li><b>Security</b> &#8211; In government, securing the data of citizens and businesses is paramount.  That&#8217;s not to suggest it isn&#8217;t for the more Web 2.0, virual, social networking type sites but nearly every government system I&#8217;ve touched has had a strong focus on security.  It&#8217;s not just the usual stuff like SQL injections, XSS and CSRF but also the notion of feature-based security.  By that I mean we apply our MVC model to only expose certain features to the public internet.  A common example of this is to limit administrative features for use on our Intranet.  Other considerations that move the security issue up the priority chain in government include watchdog groups and media outlets that thrive on good government scandals and mishaps.  In Terry&#8217;s defense (not that he needs it) one of the arguments I could see him giving is that it&#8217;s pretty trivial to secure a stable, scalable and fast application.</li>
<li><b>Speed</b> &#8211; After stability and security Speed is next in line.  Not to further stereotype a state with plenty already out there, Iowa&#8217;s sheer population suggests that the need to massively scale an application is going to be a rare issue.  Serving as many requests per second, however, does come in to play.  A great example why this is so is the <a href="http://www.iowasexoffender.com">Iowa Sex Offender Registry</a>.  From time-to-time some high profile sex offender cases have been covered on various media outlets across the state and this can cause short periods of high volume traffic.  Making the code run as fast as possible allows us to meet these rare spikes.  If we were unable to do this reliably we&#8217;d then have to turn to our last S&#8230;Scalability</li>
<li><b>Scalability</b> &#8211; Again, don&#8217;t get me wrong, I can see where scalability has it&#8217;s place and I have heard talks on both trivial and more complicated ways to achieve this whether it be database replication, sharding a database, implementing memcached, etc.  In fact we even use a few of these techniques in our Java environment which is the only platform we current support to scale horizontally.  To PHP&#8217;s credit, for Iowa&#8217;s needs it performs well enough out of the box we often avoid having to put much thought into scalability. The big gain here is we spend less time on engineering concerns and more time focusing on customer requirements and trying to commoditize software delivery.</li>
</ol>
<p>
All that said, there is a lot to learn from people like Terry as I don&#8217;t doubt that some day an application will come across my IDE that will require me to rethink the order of Stability, Security, Speed and Scalability.  One thing that can be learned is that no matter what application you are working on, the analysis process and resulting requirements had better make it clear what that order should be.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/05/Government-in-the-Web-2.0-World/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Join me at the 2008 DC PHP Conference</title>
		<link>http://www.tonybibbs.com/2008/04/Join-me-at-the-2008-DC-PHP-Conference/</link>
		<comments>http://www.tonybibbs.com/2008/04/Join-me-at-the-2008-DC-PHP-Conference/#comments</comments>
		<pubDate>Tue, 29 Apr 2008 10:45:00 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/04/Join-me-at-the-2008-DC-PHP-Conference/</guid>
		<description><![CDATA[<img width="138" height="100" align="right" src="http://www.tonybibbs.com/images/articles/Join-me-at-the-2008-DC-PHP-Conference_1.jpg" alt="">A couple of weeks ago the folks at the <a href="http://www.dcphpconference.com">DC PHP Conference</a> announced the <a href="http://www.dcphpconference.com/?q=node/87">speakers for the 2008 installment</a> of the conference held at George Washington University and yours truly was selected as one of the speakers.  We're talking PHP celebs like <a href="http://shiflett.org">Chris Shiflett</a>, <a href="http://blogs.oracle.com/opal/">Chris Jones</a>, <a href="http://www.sklar.com/page/section/home">David Sklar</a>, <a href="http://www.calevans.com/">Cal Evans</a>, <a href="http://eliw.wordpress.com/">Eli White</a>, <a href="http://caseysoftware.com/blog">Keith Casey</a> and <a>Ben Ramsey</a> as well as PHP companies like <a href="http://www.zend.com">Zend</a>, <a href="http://www.digg.com">Digg</a>, <a href="http://www.oracle.com">Oracle</a> and <a href="http://www.ning.com">Ning</a> just to name a few.
<p>
Despite the fact the Internet continually provides us new ways to collapse the world and brush elbows with like-minded people I still get a bit perplexed that anybody finds it interesting when I talk about PHP (or anything for that matter).  That aside, I do have a talk I'm giving called "Fed up of Framework Hype?".  Sound familiar? For those of you that occasionally browse these pages you may recall <a href="http://www.tonybibbs.com/article.php/PHPFrameworkHype">a prior post on the subject</a>.  Given there was a bit of interest in that post I turned it into a talk for this conference.  Click "read more" to see the full abstract of the talk and be sure to <a href="https://www.kbconferences.com/registration/dcphp08">register for the conference</a> which runs June 2-4!]]></description>
			<content:encoded><![CDATA[<p><img width="138" height="100" align="right" src="http://www.tonybibbs.com/images/articles/Join-me-at-the-2008-DC-PHP-Conference_1.jpg" alt="">A couple of weeks ago the folks at the <a href="http://www.dcphpconference.com">DC PHP Conference</a> announced the <a href="http://www.dcphpconference.com/?q=node/87">speakers for the 2008 installment</a> of the conference held at George Washington University and yours truly was selected as one of the speakers.  We&#8217;re talking PHP celebs like <a href="http://shiflett.org">Chris Shiflett</a>, <a href="http://blogs.oracle.com/opal/">Chris Jones</a>, <a href="http://www.sklar.com/page/section/home">David Sklar</a>, <a href="http://www.calevans.com/">Cal Evans</a>, <a href="http://eliw.wordpress.com/">Eli White</a>, <a href="http://caseysoftware.com/blog">Keith Casey</a> and <a>Ben Ramsey</a> as well as PHP companies like <a href="http://www.zend.com">Zend</a>, <a href="http://www.digg.com">Digg</a>, <a href="http://www.oracle.com">Oracle</a> and <a href="http://www.ning.com">Ning</a> just to name a few.
<p>
Despite the fact the Internet continually provides us new ways to collapse the world and brush elbows with like-minded people I still get a bit perplexed that anybody finds it interesting when I talk about PHP (or anything for that matter).  That aside, I do have a talk I&#8217;m giving called &#8220;Fed up of Framework Hype?&#8221;.  Sound familiar? For those of you that occasionally browse these pages you may recall <a href="http://www.tonybibbs.com/article.php/PHPFrameworkHype">a prior post on the subject</a>.  Given there was a bit of interest in that post I turned it into a talk for this conference.  Click &#8220;read more&#8221; to see the full abstract of the talk and be sure to <a href="https://www.kbconferences.com/registration/dcphp08">register for the conference</a> which runs June 2-4!<b>Abstract for: Fed up of Framework Hype</b>
<p>
How good can any PHP framework be when it seems a new framework is dropping on the daily?   It’s not just PHP…you’ve got Rails, Spring, Django and don’t waste your time Googlin’ on the subject…there isn’t enough time in the day to read up on all that crap.  Shame on us architects. Why?  With all the talk about the baddest, new framework out there we never take the time to articulate their value (if any).  So here it is, one guy&#8217;s view on frameworks and the real value they have for you.
<p>
See, nobody wants to talk the fact that frameworks have a bunch of empty rhetoric around them. Their value is often discussed in terms of coolness and ease of use. If you are talking to a manager-type, balding, high strung, concerned about their budget you will quickly learn they could care less. They’re focused on the bottom line (where you should be focused).
<p>
This talk will focus on how to evaluate a framework and when not to use one.  Yes, that’s right…I said it.  You may not even need a framework!  But should you need one we’ll talk about framework pre-requisites, why establishing goals for your framework is important, the key components of a good framework and how to help your organization get the most out of which ever framework you choose.
<p>
Don’t like frameworks?  In this short talk it may be hard to convince you they can be good but I do know why many hardcore PHP-ers think they suck and we can talk about how to make a frameworks suck less, maybe even get you to like one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/04/Join-me-at-the-2008-DC-PHP-Conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protection Against Cross Site Request Forgery (CSRF)</title>
		<link>http://www.tonybibbs.com/2008/04/Protection-Against-CSRF/</link>
		<comments>http://www.tonybibbs.com/2008/04/Protection-Against-CSRF/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 15:01:00 +0000</pubDate>
		<dc:creator>Tony</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybibbs.com/2008/04/Protection-Against-CSRF/</guid>
		<description><![CDATA[In working on the <a href="http://gl2.tonybibbs.com">Geeklog 2</a> codebase, much of work forms the basis for stuff I do at <a href="http://das.ite.iowa.gov">work</a>, I finally figured it was time to add handling for CSRF to the codebase in a way that forces it's use without the developer having to explicitly do anything.  In my experience security has, sadly, become one of the last things on the mind of PHP developers (kudos to you numerous exceptions out there) so finding a way to help the developers protect their application from CSRF in a way that avoids them from having to explicitly consider and handle it themselves was key.  However, to better illustrate my needs let's discuss a few high level requirements, shall we?
<ol>
<li>CSRF solution must apply to any and all forms in the system.<li>
<li>CSRF solution must work even in the case where the page served has multiple forms</li>
<li>CSRF solution must work for both GET and POST</li>
<li>CSRF solution must be applied to all forms without the developer having to make any explicit method calls to CSRF-related functions.</li>
</ol>
The solution?  I've basically adapted what <a href="http://shifflett.org">Chris Shifflet</a> proposed in <a href="http://shiflett.org/articles/cross-site-request-forgeries">this blog entry</a> from a few years ago.  For the lazy, his solution involves including a token in each form and then putting the token value and the time the token was created into the user session.  Upon submission of the form, the form value is then checked with the session value and then the time the token was used is compared to some sane time-to-live (TTL) value.  Having this solution in mind I then added a few more details to the requirements above:
<ol>
<li>The security token must be autogenerated and inserted into each form</li>
<li>Each command (we operate in an MVC model) must have the ability to specify where it expects the token to be (e.g. POST or GET).  The default value for this must be in the &#36;_POST (in fact I question if using GET at all makes any sense).</li>
<li>The solution must not check for the token in the &#36;_REQUEST</li>
<li>The solution must allow each command to set the TTL for the token.</li>
<li>Should no TTL be explicitly given, the system must use the default of 3 minutes</li>
</ol>
(click 'read more' for the solution)]]></description>
			<content:encoded><![CDATA[<p>In working on the <a href="http://gl2.tonybibbs.com">Geeklog 2</a> codebase, much of work forms the basis for stuff I do at <a href="http://das.ite.iowa.gov">work</a>, I finally figured it was time to add handling for CSRF to the codebase in a way that forces it&#8217;s use without the developer having to explicitly do anything.  In my experience security has, sadly, become one of the last things on the mind of PHP developers (kudos to you numerous exceptions out there) so finding a way to help the developers protect their application from CSRF in a way that avoids them from having to explicitly consider and handle it themselves was key.  However, to better illustrate my needs let&#8217;s discuss a few high level requirements, shall we?
<ol>
<li>CSRF solution must apply to any and all forms in the system.
<li>
<li>CSRF solution must work even in the case where the page served has multiple forms</li>
<li>CSRF solution must work for both GET and POST</li>
<li>CSRF solution must be applied to all forms without the developer having to make any explicit method calls to CSRF-related functions.</li>
</ol>
<p>The solution?  I&#8217;ve basically adapted what <a href="http://shifflett.org">Chris Shifflet</a> proposed in <a href="http://shiflett.org/articles/cross-site-request-forgeries">this blog entry</a> from a few years ago.  For the lazy, his solution involves including a token in each form and then putting the token value and the time the token was created into the user session.  Upon submission of the form, the form value is then checked with the session value and then the time the token was used is compared to some sane time-to-live (TTL) value.  Having this solution in mind I then added a few more details to the requirements above:
<ol>
<li>The security token must be autogenerated and inserted into each form</li>
<li>Each command (we operate in an MVC model) must have the ability to specify where it expects the token to be (e.g. POST or GET).  The default value for this must be in the &#36;_POST (in fact I question if using GET at all makes any sense).</li>
<li>The solution must not check for the token in the &#36;_REQUEST</li>
<li>The solution must allow each command to set the TTL for the token.</li>
<li>Should no TTL be explicitly given, the system must use the default of 3 minutes</li>
</ol>
<p>(click &#8216;read more&#8217; for the solution)Ok, so armed with those requirements here is how the implementation went.  Not unlike most MVC implementations we have a class representing a view (or a single page within the system).  We have a few abstract classes in our codebase but the one of most importanc is BaseViewFlexy.php.  The class in this page uses <a href="http://www.google.com/url?sa=t&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fpear.php.net%2Fpackage%2FHTML_Template_Flexy&amp;ei=GUkSSPaPCpTeigHekNGbDw&amp;usg=AFQjCNFaIPmKuSk3WibeEa-dh8ju7lnxzQ&amp;sig2=X5U0HhgEv3siQd8WDB2J5Q">the Flexy template engine</a>.  In this class there is a compile() method that takes the given Flexy template and compiles it into PHP code.  This is the point where we want to insert our security token and the best way to do this was to create our own Flexy compiler that does this work with the following method:
<pre><code>
protected function injectSecurityToken(&#36;content)
{
    &#36;content = str_ireplace('&lt;/form&gt;',
        '&lt;input type="hidden" name="glSecurityToken" /&gt;&lt;/form&gt;',
    	&#36;content);
    return &#36;content;
}
</code></pre>
<p>If you notice above I don&#8217;t actually inject the value.  Remember that we have bootstrapped the Flexy compile process so the above code ends up in the compiled Flexy template which, again, is PHP code.  Now we need to insert the value for the token when we do our normal Flexy variable substitution.  To do this our BaseViewFlexy.php file has a compile() method:
<pre><code>
public function compile(&#36;templateToCompile)
{
    // Compile the flexy template using our custom compiler
    &#36;this-&gt;flexyHandle-&gt;compile(&#36;templateToCompile);
    &#36;this-&gt;flexyElements = &#36;this-&gt;flexyHandle-&gt;getElements();

    // Use Flexy to inject token (if needed)
    if (in_array('glSecurityToken',array_keys(&#36;this-&gt;flexyElements))) {
    	&#36;this-&gt;flexyElements&#91;'glSecurityToken'&#93;-&gt;setValue(&#36;this-&gt;getSecurityToken());
    }
}
</code></pre>
<p>You&#8217;ll notice the call to getSecurityToken() above.  That is the method where we generate the token, set the token and token creation time in the session:</p>
<pre><code>
protected function getSecurityToken()
{
    &#36;token = md5(uniqid(rand(), TRUE));
    &#36;_SESSION&#91;'glSecurityToken'&#93; = &#36;token;
    &#36;_SESSION&#91;'glSecurityTokenTime'&#93; = time();
    return &#36;token;
}
</code></pre>
<p>Ok, so to this point we have insert the HTML hidden field that will hold the security token into our compiled Flexy template and we have set the appropriate value for the token and added the token and token creation time to the session. Because we did all this by overriding methods Flexy uses natively we have guaranteed this code will be executed for every form without the developer having to explicitly call anything.  Now we need to do the checks upon submission of the form itself.
<p>
In our MVC implementation as with our View we have the notion of a command.  Specifically we have an abstract class in BaseCommandUser.php that is aware of the user session already.  All we need to do is add the security check for the token to it&#8217;s constructor:
<pre><code>
public function __construct(&#36;urlArgs = null)
{
    &#36;this-&gt;user = unserialize(&#36;_SESSION&#91;getOption('user_session_var')&#93;);

    if (&#36;this-&gt;getUserRequired() AND (&#36;this-&gt;user-&gt;getUserId() == 2)) {
       // NOTE this makes use of the global forward feature in MVCnPHP
       throw new Exception('doForward:login');
    }

    if (!&#36;this-&gt;authorizedToRun()) {
        throw new Exception('You do not have sufficient privileges to perform this action.
            Please note that all attempts to illegally perform actions are logged');
    }

    // We may have data submitted to us.  Check the security token
    &#36;this-&gt;doSecurityTokenCheck();

    parent::__construct(&#36;urlArgs);
}
</code></pre>
<p>As you can see above we call doSecurityTokenCheck() which will throw an exception if it should fail.  There are two reasons for failure 1) the token in the form doesn&#8217;t match the one in the session and 2) the token has expired:</p>
<pre><code>
    protected function doSecurityTokenCheck(&#36;inputArray = self::INPUT_POST)
    {
    	if (!&#36;this-&gt;doSecurityTokenChecks) return;

    	&#36;arrayToCheck = array();

    	if (&#36;inputArray == self::INPUT_POST) {
    		&#36;arrayToCheck = &amp;&#36;_POST;
    	} else {
    		if (&#36;inputArray == self::INPUT_GET) {
    			&#36;arrayToCheck = &amp;&#36;_GET;
    		}
    	}

    	// If we didn't get a token in the session before now set one
        if (!isset(&#36;_SESSION&#91;'glSecurityToken'&#93;)) {
			&#36;_SESSION&#91;'glSecurityToken'&#93; = md5(uniqid(rand(), TRUE));
        }

        if (&#36;arrayToCheck&#91;'glSecurityToken'&#93; == &#36;_SESSION&#91;'glSecurityToken'&#93;) {
        	// Valid token.  Validate age (if needed)
        	&#36;tokenAge = time() - &#36;_SESSION&#91;'glSecurityTokenTime'&#93;;
        	if (is_null(&#36;this-&gt;securityTokenTTL)) &#36;this-&gt;setSecurityTokenTTL();
        	if (!(&#36;tokenAge &lt;= &#36;this-&gt;securityTokenTTL)) {
        		throw new Exception('The form you submitted has expired.  Please go back and try again');
        	}
        } else {
        	Geeklog_Log::log('Cross site forgery request (CSFR) detected', Zend_Log::CRIT);
        	throw new Exception('Cross site forgery request (CSFR) detected.  Please note all
        		such attempts are logged.');
        }
        return;
    }
</code></pre>
<p>As you can see from above you can set the class member doSecurityTokenChecks to avoid doing these checks at all (i.e. in the case of a view with no form fields).  There is also a class member, securityTokenTTL, which can be set on a command-by-command basis.  For sanity sake we default to 3 minutes.
<p>
That&#8217;s it!  I don&#8217;t pretend this is perfect code but it does work and is in line with Chris Shiflett&#8217;s approach which I liked.  With a little bit of work we were able to build in protections against CSRF, which I don&#8217;t claim to be 100% complete but do make such attacks considerably harder, and it is done in a way that secures all forms without the developer having to explicitly call anything.  A true win-win in my opinion!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybibbs.com/2008/04/Protection-Against-CSRF/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

