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

<channel>
	<title>Jonah's Thoughts</title>
	<atom:link href="http://php-thoughts.cubedwater.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://php-thoughts.cubedwater.com</link>
	<description>On PHP and things related</description>
	<lastBuildDate>Mon, 21 Jun 2010 01:38:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Sticky Behavior</title>
		<link>http://php-thoughts.cubedwater.com/2010/sticky-behavior/</link>
		<comments>http://php-thoughts.cubedwater.com/2010/sticky-behavior/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 19:22:13 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=262</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />This is a sticky behavior.  It will cause the models it is attached to to remember the user&#8217;s last inputted value.  In other words, the last value the user selected will be the default value the next time around the user fills out the form
It&#8217;s not perfectly reusable unless you follow the same [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>This is a sticky behavior.  It will cause the models it is attached to to remember the user&#8217;s last inputted value.  In other words, the last value the user selected will be the default value the next time around the user fills out the form</p>
<p>It&#8217;s not perfectly reusable unless you follow the same naming standards as I do, so you may need to modify one or two lines of code (like the relation)</p>
<p>It designed for a multi-user application where users have their own stickies</p>
<p>Table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="kw1">IF</span> <span class="kw1">NOT</span> <span class="kw1">EXISTS</span> <span class="st0">`sticky`</span> <span class="br0">&#40;</span>
  <span class="st0">`user_id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="st0">`name`</span> varchar<span class="br0">&#40;</span><span class="nu0">255</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="st0">`lastValue`</span> varchar<span class="br0">&#40;</span><span class="nu0">255</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span><span class="st0">`user_id`</span><span class="sy0">,</span><span class="st0">`name`</span><span class="br0">&#41;</span>
<span class="br0">&#41;</span>;</pre></div></div>

<p>Sticky Model</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="kw2">class</span> Sticky <span class="kw2">extends</span> CActiveRecord
<span class="br0">&#123;</span>
	<span class="co4">/**
	 * The followings are the available columns in table 'sticky':
	 * @var integer $user_id
	 * @var string $name
	 * @var string $lastValue
	 */</span>
&nbsp;
	<span class="co4">/**
	 * Returns the static model of the specified AR class.
	 * @return CActiveRecord the static model class
	 */</span>
	<span class="kw2">public</span> <span class="kw3">static</span> <span class="kw2">function</span> model<span class="br0">&#40;</span><span class="re0">$className</span><span class="sy0">=</span><span class="kw2">__CLASS__</span><span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="kw1">return</span> parent<span class="sy0">::</span><span class="me2">model</span><span class="br0">&#40;</span><span class="re0">$className</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
&nbsp;
	<span class="co4">/**
	 * @return string the associated database table name
	 */</span>
	<span class="kw2">public</span> <span class="kw2">function</span> tableName<span class="br0">&#40;</span><span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="kw1">return</span> <span class="st_h">'sticky'</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
&nbsp;
	<span class="co4">/**
	* @param int $user_id
	* @param string $name
	* @return Sticky (may be a new record if none found in database)
	*/</span>
	<span class="kw2">public</span> <span class="kw3">static</span> <span class="kw2">function</span> getSticky<span class="br0">&#40;</span><span class="re0">$user_id</span><span class="sy0">,</span> <span class="re0">$name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="re0">$stickyAR</span> <span class="sy0">=</span> <span class="kw2">self</span><span class="sy0">::</span><span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findByPk</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'user_id'</span><span class="sy0">=&gt;</span><span class="re0">$user_id</span><span class="sy0">,</span> <span class="st_h">'name'</span><span class="sy0">=&gt;</span><span class="re0">$name</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$stickyAR</span><span class="sy0">===</span><span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="re0">$stickyAR</span> <span class="sy0">=</span> <span class="kw2">new</span> Sticky<span class="sy0">;</span>
			<span class="re0">$stickyAR</span><span class="sy0">-&gt;</span><span class="me1">user_id</span> <span class="sy0">=</span> <span class="re0">$user_id</span><span class="sy0">;</span>
			<span class="re0">$stickyAR</span><span class="sy0">-&gt;</span><span class="me1">name</span> <span class="sy0">=</span> <span class="re0">$name</span><span class="sy0">;</span>
		<span class="br0">&#125;</span>
		<span class="kw1">return</span> <span class="re0">$stickyAR</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
&nbsp;
&nbsp;
	<span class="co4">/**
	 * THIS IS NOT NEEDED (but hey I'm going to leave it)
	 * @return array relational rules.
	 */</span>
	<span class="kw2">public</span> <span class="kw2">function</span> relations<span class="br0">&#40;</span><span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'user'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">::</span><span class="me2">BELONGS_TO</span><span class="sy0">,</span> <span class="st_h">'User'</span><span class="sy0">,</span> <span class="st_h">'user_id'</span><span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Behavior</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="kw2">class</span> StickyBehavior <span class="kw2">extends</span> CActiveRecordBehavior
<span class="br0">&#123;</span>
	<span class="co4">/**
	* @var array array('stickyAttribute1', 'stickyAttribute2', ..)
	*/</span>
	<span class="kw2">public</span> <span class="re0">$stickies</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	protected <span class="re0">$stickyARS</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	<span class="co4">/**
	* May need to modify
	* Gets the user id of the sticky.  Each user has his own stickies
	*/</span>
	protected <span class="kw2">function</span> getUserId<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">return</span> Yii<span class="sy0">::</span><span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">user</span><span class="sy0">-&gt;</span><span class="me1">id</span><span class="sy0">;</span>	
	<span class="br0">&#125;</span>
&nbsp;
	<span class="co4">/**
	* Handles filling attributes with stickies
	* Only executes on NEW records
	*/</span>
	<span class="kw2">public</span> <span class="kw2">function</span> afterConstruct<span class="br0">&#40;</span><span class="re0">$event</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">stickies</span> <span class="kw1">as</span> <span class="re0">$stickyAttribute</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="re0">$stickyName</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getStickyName</span><span class="br0">&#40;</span><span class="re0">$stickyAttribute</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="re0">$stickyAR</span> <span class="sy0">=</span> Sticky<span class="sy0">::</span><span class="me2">getSticky</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getUserId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$stickyName</span><span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$stickyAR</span><span class="sy0">-&gt;</span><span class="me1">getIsNewRecord</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
				<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">owner</span><span class="sy0">-&gt;</span><span class="re0">$stickyAttribute</span> <span class="sy0">=</span> <span class="re0">$stickyAR</span><span class="sy0">-&gt;</span><span class="me1">lastValue</span><span class="sy0">;</span>
&nbsp;
			<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">stickyARS</span><span class="br0">&#91;</span><span class="re0">$stickyAttribute</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re0">$stickyAR</span><span class="sy0">;</span>
		<span class="br0">&#125;</span>
	<span class="br0">&#125;</span>
&nbsp;
	<span class="co4">/**
	* Updates the sticky value
	* Only does this for NEW RECORDS.  This seemed to make more sense to me,
	* but other people may want to change this
	*/</span>
	<span class="kw2">public</span> <span class="kw2">function</span> afterSave<span class="br0">&#40;</span><span class="re0">$event</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">owner</span><span class="sy0">-&gt;</span><span class="me1">getIsNewRecord</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">return</span><span class="sy0">;</span>
		<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">stickies</span> <span class="kw1">as</span> <span class="re0">$stickyAttribute</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="re0">$stickyAR</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">stickyARS</span><span class="br0">&#91;</span><span class="re0">$stickyAttribute</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
			<span class="re0">$stickyAR</span><span class="sy0">-&gt;</span><span class="me1">lastValue</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">owner</span><span class="sy0">-&gt;</span><span class="re0">$stickyAttribute</span><span class="sy0">;</span>
			<span class="re0">$stickyAR</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
		<span class="br0">&#125;</span>
	<span class="br0">&#125;</span>
&nbsp;
	<span class="co4">/**
	* Gets the sticky name as stored in the database (prefixes attribute name with the model name)
	* 
	* @param string stickyAttribute
	*/</span>
	protected <span class="kw2">function</span> getStickyName<span class="br0">&#40;</span><span class="re0">$stickyAttribute</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">return</span> <span class="kw3">get_class</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">owner</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st_h">'.'</span><span class="sy0">.</span><span class="re0">$stickyAttribute</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Example of attachment to model</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
	<span class="kw2">public</span> <span class="kw2">function</span> behaviors<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'sticky'</span><span class="sy0">=&gt;</span>array<span class="br0">&#40;</span>
				<span class="st_h">'class'</span><span class="sy0">=&gt;</span><span class="st_h">'application.models.StickyBehavior'</span><span class="sy0">,</span>
				<span class="st_h">'stickies'</span><span class="sy0">=&gt;</span>array<span class="br0">&#40;</span><span class="st_h">'gym_id'</span><span class="br0">&#41;</span><span class="sy0">,</span>
			<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span></pre></div></div>

<p>There is also a <a href="http://www.yiiframework.com/forum/index.php?/topic/8225-stick-behavior/">forum thread</a></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2010/sticky-behavior/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternative to the beforeAction() event</title>
		<link>http://php-thoughts.cubedwater.com/2010/alternative-to-the-beforeaction-event/</link>
		<comments>http://php-thoughts.cubedwater.com/2010/alternative-to-the-beforeaction-event/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 01:35:27 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[beforeAction()]]></category>
		<category><![CDATA[events]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=245</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />I often see that when someone needs something executed on every page request before anything else is executed, they usually put it in the controller beforeAction() method.  Things you might want executed on every page request might be, for example (so you know what I&#8217;m talking about):

Handling the layout
Cleaning all GET and POST parameters [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>I often see that when someone needs something executed on every page request before anything else is executed, they usually put it in the controller <a href="http://www.yiiframework.com/doc/api/CController#beforeAction-detail">beforeAction()</a> method.  Things you might want executed on every page request might be, for example (so you know what I&#8217;m talking about):</p>
<ul>
<li>Handling the layout</li>
<li>Cleaning all GET and POST parameters (I don&#8217;t like to do this but some people do)</li>
<li>Language handling</li>
</ul>
<p>I&#8217;ve seen people do this with CakePHP as well as with Yii.  I find that <em>beforeAction()</em> is actually not an optimal place to put this sort of code.  Imagine you put code for all of the examples I gave above plus three more in the <em>beforeAction()</em> method.  You might image that the <em>beforeAction()</em> method would become cluttered and hard to read.  I prefer lower coupling than this.  We want these scripts split up into logical places.  And guess what?  With Yii this is easy.  Application Components!</p>
<p>Let me write an example.  Lets say we need to figure out what layout to display to the user on each request.  We would like to execute some logic for this before the controller action is called.  We do <em>not</em> use <em>beforeFilter()</em>.  We instead create an application component.  An application component is simply a class that extends CApplicationComponent.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="kw2">class</span> LayoutHandler <span class="kw2">extends</span> CApplicationComponent <span class="br0">&#123;</span>
&nbsp;
	<span class="kw2">public</span> <span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		parent<span class="sy0">::</span><span class="me2">init</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
		<span class="co1">//Put code here.</span>
&nbsp;
	<span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Now everything in the <em>init()</em> method will be executed when this application component is instantiated.  So now, we just need to get it to instantiate on every request, before the action is executed.  This is done in the application configuration using the <em><a href="http://www.yiiframework.com/doc/api/CModule#preload-detail">preload</a></em> property.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="co1">// This is the main Web application configuration. Any writable</span>
<span class="co1">// CWebApplication properties can be configured here.</span>
<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
	<span class="st_h">'basePath'</span><span class="sy0">=&gt;</span>dirname<span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span><span class="sy0">.</span>DIRECTORY_SEPARATOR<span class="sy0">.</span><span class="st_h">'..'</span><span class="sy0">,</span>
&nbsp;
	<span class="co1">// The 'layoutHandler' component will pre-load</span>
	<span class="st_h">'preload'</span><span class="sy0">=&gt;</span>array<span class="br0">&#40;</span><span class="st_h">'layoutHandler'</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp;
	<span class="co1">// application components</span>
	<span class="st_h">'components'</span><span class="sy0">=&gt;</span>array<span class="br0">&#40;</span>
		<span class="st_h">'layoutHandler'</span><span class="sy0">=&gt;</span>array<span class="br0">&#40;</span>
			<span class="st_h">'class'</span><span class="sy0">=&gt;</span><span class="st_h">'path.to.LayoutHandler'</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
	<span class="br0">&#41;</span><span class="sy0">,</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Now there are two main things I have done here:</p>
<ol>
<li>Defined the <em>LayoutHandler </em>class as an application component in the <em>components</em> property</li>
<li>Set the <em>layoutHandler</em> to <em>preload</em> with the preload property</li>
</ol>
<p>You may find that this method is much more organized than simply stuffing code in <em>CController::beforeAction()</em>.  It also leaves your code more modular.</p>
<p>Note that now you can even access the <em>LayoutHandler </em>class anywhere within your app via <em>Yii::app()->layoutHandler</em>.  Not useful in this example, but this is often very handy.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2010/alternative-to-the-beforeaction-event/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Table prefixes</title>
		<link>http://php-thoughts.cubedwater.com/2009/table-prefixes/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/table-prefixes/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 22:43:33 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[active records]]></category>
		<category><![CDATA[tables]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=227</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />One question I hear many people ask around the Yii forum is how to use table prefixes with ActiveRecord.  I believe the best way to solve this problem is to extend CActiveRecord::tableName().  Now you can either extend this method in every active record class you would like to use a prefix manually, or [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>One question I hear many people ask around the Yii forum is how to use table prefixes with ActiveRecord.  I believe the best way to solve this problem is to extend <a href="http://www.yiiframework.com/doc/api/CActiveRecord#tableName-detail">CActiveRecord::tableName()</a>.  Now you can either extend this method in every active record class you would like to use a prefix manually, or you can create a new active record class that supports this functionality, and then have all your other active record classes extend this new class.  This is what I mean:</p>
<p>Normally your active record classes would have the following inheritance:<br />
<code>[...] -> CModel -> CActiveRecord -> YourARModels</code></p>
<p>Instead, you may create a new active record class with custom functionality that you want all your active record classes to have, such as the table prefix functionality.  So the inheritance would look like this:<br />
<code>[...] -> CModel -> CActiveRecord -> ActiveRecord -> YourARModels</code></p>
<p>To do this simply create a ActiveRecord class and save it in a directory that is set to auto-load classes on demand (probably <em>/protected/models</em> or <em>/protected/components</em> should work).  It could look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="kw2">class</span> ActiveRecord <span class="kw2">extends</span> CActiveRecord
<span class="br0">&#123;</span>
	<span class="kw2">public</span> <span class="re0">$tablePrefix</span> <span class="sy0">=</span> <span class="st_h">'myPrefix_'</span><span class="sy0">;</span>
&nbsp;
	<span class="kw2">public</span> <span class="kw2">function</span> tableName<span class="br0">&#40;</span><span class="br0">&#41;</span>
	<span class="br0">&#123;</span>
		<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">tablePrefix</span><span class="sy0">.</span>parent<span class="sy0">::</span><span class="me2">tableName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Then you would have all your active record classes simply extend <em>ActiveRecord</em> instead of <em>CActiveRecord</em>.  If you do not want a single active record to have a prefix, you can set the <em>$tablePrefix</em> attribute to an empty string in that active record.</p>
<p>You may of course add other useful functionalities that you would like your active record models to share in this class.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/table-prefixes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CDbExpression</title>
		<link>http://php-thoughts.cubedwater.com/2009/cdbexpression/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/cdbexpression/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 01:10:12 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=159</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />Ever want to set an attribute in Active Record with a MySQL function?  For instance, often times you need to set an attribute to the well known MySQL function &#8220;NOW()&#8221;.  Most people first attempt this in the following way:

&#60;?php
$model-&#62;createdDate = 'NOW()';

The above, however, will most definitely not work.  Why not?  Because [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>Ever want to set an attribute in Active Record with a MySQL function?  For instance, often times you need to set an attribute to the well known MySQL function &#8220;NOW()&#8221;.  Most people first attempt this in the following way:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$model</span><span class="sy0">-&gt;</span><span class="me1">createdDate</span> <span class="sy0">=</span> <span class="st_h">'NOW()'</span><span class="sy0">;</span></pre></div></div>

<p>The above, however, will most definitely not work.  Why not?  Because Yii will first escape the value and then enclose it in quotes, like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;">... <span class="st0">`createdDate`</span><span class="sy1">=</span> <span class="st0">'NOW()'</span> ...</pre></div></div>

<p>Since it is enclosed in quotes, it is treated as a string and not a function.  If Yii did not clean the data like this, you would have to, and that would be very annoying.</p>
<p>As of version 1.0.2 of Yii however, there is a way to get around this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$model</span><span class="sy0">-&gt;</span><span class="me1">createdDate</span> <span class="sy0">=</span> <span class="kw2">new</span> CDbExpression<span class="br0">&#40;</span><span class="st_h">'NOW()'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>CDbExpression is a special class for using MySQL expressions in your queries.  You use it just like in the above example.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/cdbexpression/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Safe attributes tip</title>
		<link>http://php-thoughts.cubedwater.com/2009/safe-attributes-tip/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/safe-attributes-tip/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 00:35:12 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Enhancement]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[scenarios]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=163</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />In my last two posts [1, 2] I explained how to define scenario-based validation rules and safe attributes.  Something I have noted is that whenever I end up specifying an attribute as &#8220;required&#8221; in the validation rules(), I also always end up specifying it as &#8220;safe&#8221; in safeAttributes() under the same scenario.  This [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>In my last two posts [<a href="http://php-thoughts.cubedwater.com/2009/validation-scenarios/">1</a>, <a href="http://php-thoughts.cubedwater.com/2009/safe-attribute-scenarios/">2</a>] I explained how to define scenario-based validation rules and safe attributes.  Something I have noted is that whenever I end up specifying an attribute as &#8220;required&#8221; in the validation rules(), I also always end up specifying it as &#8220;safe&#8221; in safeAttributes() under the same scenario.  This got me thinking &#8211; is it possible that every &#8220;required&#8221; attribute must also be &#8220;safe&#8221; on a given scenario?  The answer to that seems to be yes.  So I thought, why be redundant?  So I went about the task of teaching Yii that all &#8220;required&#8221; attributes are also &#8220;safe&#8221;.  It seems the most elegant way to do this is by extending getSafeAttributeNames() in your model. So that&#8217;s what I did.  Now, I&#8217;ll share with you.  Just drop this code in any model that you would like to have this behavior.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="coMULTI">/*
* I extended this method so that yii will &quot;automagically&quot; understand that
* 'required' attributes (in the given scenario) are also 'safe'.  This way,
* when defining 'safe' attributes in the safeAttributes() method, you can
* neglect to define attributes as safe that you have already defined at &quot;required&quot;
* in your rules() method.  This basically saves typing (and in some cases stupid
* mistakes), which I am always a fan of.  This method could be moved to another model
* from which other models like this could inherit from if you wish.
* 
* You should NOT call this method directly but it is used by Yii internally
*/</span>
<span class="kw2">public</span> <span class="kw2">function</span> getSafeAttributeNames<span class="br0">&#40;</span><span class="re0">$scenario</span><span class="sy0">=</span><span class="st_h">''</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$safe</span> <span class="sy0">=</span> parent<span class="sy0">::</span><span class="me2">getSafeAttributeNames</span><span class="br0">&#40;</span><span class="re0">$scenario</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">validators</span> <span class="kw1">as</span> <span class="re0">$validator</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw3">get_class</span><span class="br0">&#40;</span><span class="re0">$validator</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="st_h">'CRequiredValidator'</span><span class="br0">&#41;</span> <span class="sy0">||</span> <span class="sy0">!</span><span class="re0">$validator</span><span class="sy0">-&gt;</span><span class="me1">applyTo</span><span class="br0">&#40;</span><span class="re0">$scenario</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">continue</span><span class="sy0">;</span>
		<span class="re0">$safe</span> <span class="sy0">=</span> <span class="kw3">array_merge</span><span class="br0">&#40;</span><span class="re0">$safe</span><span class="sy0">,</span> <span class="re0">$validator</span><span class="sy0">-&gt;</span><span class="me1">attributes</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
	<span class="kw1">return</span> <span class="kw3">array_unique</span><span class="br0">&#40;</span><span class="re0">$safe</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Enjoy if you wish and give feedback.</p>
<p>One thing to worry about is speed however.  Every time this method is called, it loops through all the validators.  If you have a <em>lot</em> of validation rules this could be unwanted.  On the other hand, yii only checks the safe attributes on CModel::setAttributes(), which is generally only called on requests with submitted POST data (e.g. forms, and users don&#8217;t often expect those pages to be lightning fast).  Anyways, I&#8217;m making this code snipped sound slower than it actually is.  It might be interesting to check how many times this method is called on a given request.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/safe-attributes-tip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Safe attribute scenarios</title>
		<link>http://php-thoughts.cubedwater.com/2009/safe-attribute-scenarios/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/safe-attribute-scenarios/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 22:44:59 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[scenarios]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=162</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />If you read my last article on validation scenarios then you may understand why in different scenarios you may need different attributes to be required.  However you may have noticed a missing link &#8211; what if in different scenarios you also need different attributes to be considered as &#8220;safe&#8221;?
If you have no idea about [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>If you read <a href="http://php-thoughts.cubedwater.com/2009/validation-scenarios/">my last article on validation scenarios</a> then you may understand why in different scenarios you may need different attributes to be required.  However you may have noticed a missing link &#8211; what if in different scenarios you also need different attributes to be considered as &#8220;safe&#8221;?</p>
<p>If you have no idea about what I am taking about then you probably don&#8217;t know that in your model you can specify which attributes are &#8220;safe&#8221; to massively assign to a model via CModel::setAttributes().</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="kw2">public</span> <span class="kw2">function</span> safeAttributes<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="co1">//these attributes are safe to massively assign</span>
		<span class="st_h">'attribute1, attribute2'</span><span class="sy0">,</span>
	<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="sy1">?&gt;</span></pre></div></div>

<p>By default, all columns in the table are considered safe except the primary key column (attributes defined in the model are <em>not</em> considered safe by default)</p>
<p>The reason you might not want all attributes to be safe is if for instance you have fields which determine things such as access level.  For instance what if you had a User model with a `is_admin` field.  If you let `is_admin` be defined as safe, you have a security hole, as someone can take a tool such as <a href="https://addons.mozilla.org/en-US/firefox/addon/1290">urlparams</a> and easily set himself as an admin.</p>
<p>Now you may actually want &#8220;is_admin&#8221; to be defined as safe in <em>certain scenarios</em>, such as an user administrative page.  Thus, as of Yii 1.0.2, you can define scenarios through safeAttributes() which was the initial reason for writing this article.</p>
<p>I will simply use a code example taken from the <a href="http://www.yiiframework.com/doc/api/CModel#safeAttributes">Yii Class Reference</a> this time.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="kw2">public</span> <span class="kw2">function</span> safeAttributes<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
	   <span class="co1">// these attributes can be massively assigned in any scenario</span>
	   <span class="co1">// that is not explicitly specified below</span>
	   <span class="st_h">'attr1, attr2, ...'</span><span class="sy0">,</span>
&nbsp;
	   <span class="co1">// these attributes can be massively assigned only in scenario 1</span>
	   <span class="st_h">'scenario1'</span> <span class="sy0">=&gt;</span> <span class="st_h">'attr2, attr3, ...'</span><span class="sy0">,</span> <span class="co1">//Eg in this scenario attr1 is NOT safe</span>
&nbsp;
	   <span class="co1">// these attributes can be massively assigned only in scenario 2</span>
	   <span class="st_h">'scenario2'</span> <span class="sy0">=&gt;</span> <span class="st_h">'attr1, attr3, ...'</span><span class="sy0">,</span>
	<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Now you may set the scenario to use via CModel::setAttributes()</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">setAttributes</span><span class="br0">&#40;</span><span class="kw3">array</span> <span class="sy0">&lt;</span>data<span class="sy0">&gt;,</span> string <span class="sy0">&lt;</span>scenario name<span class="sy0">&gt;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">//Example:</span>
<span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">setAttributes</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#91;</span><span class="st_h">'User'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="st_h">'update'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/safe-attribute-scenarios/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Validation scenarios</title>
		<link>http://php-thoughts.cubedwater.com/2009/validation-scenarios/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/validation-scenarios/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 22:00:13 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[scenarios]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=106</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />As of Yii 1.0.2 you may now define validation scenarios.  This is very useful if for instance you have multiple places in your application that you validate a model, but in each instance you may want different validation rules.  For instance, perhaps in your user registration form you want to have the &#8220;username&#8221;, [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>As of Yii 1.0.2 you may now define validation scenarios.  This is very useful if for instance you have multiple places in your application that you validate a model, but in each instance you may want different validation rules.  For instance, perhaps in your user registration form you want to have the &#8220;username&#8221;, &#8220;email&#8221; and &#8220;password&#8221; fields to be required, while on your &#8220;user recovery&#8221; page, you only want the &#8220;email&#8221; field to be required.  You may see a problem here.  If you set all the fields to be required, then your user recovery page won&#8217;t work, as it does not allow a user to supply neither a password nor a username.</p>
<p>The perfect solution to this are validation scenarios.  You can attach a validation scenario to a validation rule through the &#8216;on&#8217; property.  You may already know you can set the &#8216;on&#8217; property to either &#8216;insert&#8217; or &#8216;update&#8217;, which will automatically cause the rule to only be used on the corresponding type of save.  However sometimes these two options are not enough.  So now with this new enhancement, you may set it to any value you want.  Let me show an example:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="co1">//in user model</span>
<span class="kw2">public</span> <span class="kw2">function</span> rules<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="co1">//Set required fields</span>
 		<span class="co1">//Applies to 'register' scenario</span>
 		<span class="co1">//Note 'on' property</span>
		<span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'username, password, password_repeat, email'</span><span class="sy0">,</span> <span class="st_h">'required'</span><span class="sy0">,</span> <span class="st_h">'on'</span> <span class="sy0">=&gt;</span> <span class="st_h">'register'</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp;
		<span class="co1">//Applies to 'recover' scenario</span>
		<span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'email'</span><span class="sy0">,</span> <span class="st_h">'required'</span><span class="sy0">,</span> <span class="st_h">'on'</span> <span class="sy0">=&gt;</span> <span class="st_h">'recover'</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp;
		<span class="co1">//Applies to all scenarios</span>
		<span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'username, password'</span><span class="sy0">,</span> <span class="st_h">'length'</span><span class="sy0">,</span> <span class="st_h">'max'</span><span class="sy0">=&gt;</span><span class="nu0">35</span><span class="sy0">,</span> <span class="st_h">'min'</span><span class="sy0">=&gt;</span><span class="nu0">3</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp;
		<span class="co1">//This rule checks if the username is unique in the database in</span>
		<span class="co1">//the 'register' scenario (we don't want it to check for uniqueness</span>
		<span class="co1">//on the login page for instance)</span>
		<span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'username'</span><span class="sy0">,</span> <span class="st_h">'unique'</span><span class="sy0">,</span> <span class="st_h">'on'</span> <span class="sy0">=&gt;</span> <span class="st_h">'register'</span><span class="br0">&#41;</span><span class="sy0">,</span>
&nbsp;
		<span class="co1">//This rule applies to 'register' and 'update' scenarios</span>
		<span class="co1">//Compares 'password' field to 'password_repeat' to make sure they are the same</span>
		<span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'password'</span><span class="sy0">,</span> <span class="st_h">'compare'</span><span class="sy0">,</span> <span class="st_h">'on'</span> <span class="sy0">=&gt;</span> <span class="st_h">'register, update'</span><span class="br0">&#41;</span><span class="sy0">,</span>
	<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>With this setup Yii will be able to tell which fields are required in which scenarios.  As a bonus I threw some other rules for example.  Reading the comments will give you an understanding of that.  You may also note from the &#8216;compare&#8217; rule that you may define a rule to be used on multiple scenarios by separating them with commas.</p>
<p>Now when you wish to run validation under a specific scenario you must define it in when calling CModel::validate(), as so</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">validate</span><span class="br0">&#40;</span><span class="st_h">'&lt;scenarioName&gt;'</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">//runs validation under the given scenario</span>
&nbsp;
<span class="co1">//example:</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">validate</span><span class="br0">&#40;</span><span class="st_h">'register'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>So the above example will validate the user under the &#8216;register&#8217; scenario.</p>
<p>Leave a comment if I have left any unanswered questions on this enhancement</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/validation-scenarios/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>PHP Code shortcuts to if/else statements</title>
		<link>http://php-thoughts.cubedwater.com/2009/php-code-shortcuts-to-ifelse-statements/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/php-code-shortcuts-to-ifelse-statements/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 10:34:42 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=131</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />Here are some very useful PHP code shortcuts that I have learned.  You may have seen them before or you may not have, but if you didn&#8217;t understand them, hopefully you will after reading this article.
The first is the Ternary Operator

&#60;?php
$var = &#40;expression&#41; ? 'value if true' : 'value if false';
&#160;
//The above does the [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>Here are some very useful PHP code shortcuts that I have learned.  You may have seen them before or you may not have, but if you didn&#8217;t understand them, hopefully you will after reading this article.</p>
<p>The first is the <strong>Ternary Operator</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$var</span> <span class="sy0">=</span> <span class="br0">&#40;</span>expression<span class="br0">&#41;</span> ? <span class="st_h">'value if true'</span> <span class="sy0">:</span> <span class="st_h">'value if false'</span><span class="sy0">;</span>
&nbsp;
<span class="co1">//The above does the same as the following:</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span>expression<span class="br0">&#41;</span>
	<span class="re0">$var</span> <span class="sy0">=</span> <span class="st_h">'value if true'</span><span class="sy0">;</span>
<span class="kw1">else</span>
	<span class="re0">$var</span> <span class="sy0">=</span> <span class="st_h">'value if false'</span><span class="sy0">;</span>
&nbsp;
<span class="co1">//Example use:</span>
<span class="re0">$name</span> <span class="sy0">=</span> <span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$me</span><span class="br0">&#41;</span> ? <span class="re0">$you</span> <span class="sy0">:</span> <span class="re0">$me</span><span class="sy0">;</span> <span class="co1">//sets $name to $me if $me is not empty, or to $you if $me is empty</span></pre></div></div>

<p>The next two examples show how to use the &#8220;or&#8221; and &#8220;and&#8221; operators (also known as || and &#038;&#038;) as shortcuts</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="br0">&#40;</span>expression1<span class="br0">&#41;</span> or <span class="br0">&#40;</span>expression2<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">//The above does the same as the following:</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>expression1<span class="br0">&#41;</span>
	expression2<span class="sy0">;</span>
&nbsp;
<span class="co1">//Example use:</span>
<span class="co1">//I actually found this line of code in the Yii framework</span>
<span class="kw3">defined</span><span class="br0">&#40;</span><span class="st_h">'YII_DEBUG'</span><span class="br0">&#41;</span> or <span class="kw3">define</span><span class="br0">&#40;</span><span class="st_h">'YII_DEBUG'</span><span class="sy0">,</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">//Defines the constant YII_DEBUG if it has not been defined already</span></pre></div></div>

<p>The above works because in the <strong>or</strong> operator, the right hand expression is not evaluated unless the left hand expression is evaluated to false (if it evaluates to true, there is no need for the right-hand side to be solved anyways &#8211; and PHP tries to be efficient)</p>
<p>The <strong>and</strong> operator does the exact opposite thing:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="br0">&#40;</span>expression1<span class="br0">&#41;</span> and <span class="br0">&#40;</span>expression2<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">//The above does the same as the following:</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span>expression1<span class="br0">&#41;</span>
	expression2<span class="sy0">;</span>
&nbsp;
<span class="co1">//Example use:</span>
<span class="br0">&#40;</span><span class="re0">$page</span> <span class="sy0">&gt;</span> LAST_PAGE<span class="br0">&#41;</span> and <span class="br0">&#40;</span><span class="re0">$page</span> <span class="sy0">=</span> LAST_PAGE<span class="br0">&#41;</span> <span class="co1">//does not allow the page number to be set past the last page</span></pre></div></div>

<p>The reason you may want to use these would be to save typing, and to increase readability (in the case of the Ternary Operator anyways, you can argue the other two are less readable).  Even if you do not like to use these, it is important to know them in case you ever find yourself reading other people&#8217;s code.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/php-code-shortcuts-to-ifelse-statements/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Running your Yii app and configuring it</title>
		<link>http://php-thoughts.cubedwater.com/2008/running-your-yii-app-and-configuring-it/</link>
		<comments>http://php-thoughts.cubedwater.com/2008/running-your-yii-app-and-configuring-it/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 22:05:07 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=108</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />Unlike in CakePHP, it is mandatory to use the shell tool (called yiic, similar to CakePHP&#8217;s &#8220;Bake&#8221; script) to start off your application as it creates the workspace architecture (The Yii package does not come with an application bare-bones, only framework code).  Yiic generates .htaccess files with rules that forwards user requests to index.php [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>Unlike in CakePHP, it is mandatory to use the shell tool (called yiic, similar to CakePHP&#8217;s &#8220;Bake&#8221; script) to start off your application as it creates the workspace architecture (The Yii package does not come with an application bare-bones, only framework code).  Yiic generates .htaccess files with rules that forwards user requests to index.php where the application runs (cake does this too).  When I checked my index.php file to see what was in it, I was amazed with the possibilities of what I saw.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="co1">// change the following paths if necessary</span>
<span class="re0">$yii</span> <span class="sy0">=</span> <span class="st_h">'C:\wamp\www\yiiRepo\framework\yii.php'</span><span class="sy0">;</span>
<span class="re0">$config</span> <span class="sy0">=</span> <span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'/protected/config/main.php'</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// remove the following line when in production mode</span>
<span class="kw3">defined</span><span class="br0">&#40;</span><span class="st_h">'YII_DEBUG'</span><span class="br0">&#41;</span> or <span class="kw3">define</span><span class="br0">&#40;</span><span class="st_h">'YII_DEBUG'</span><span class="sy0">,</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="re0">$yii</span><span class="br0">&#41;</span><span class="sy0">;</span>
Yii<span class="sy0">::</span><span class="me2">createWebApplication</span><span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">run</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>The last two lines are the important ones.  In the second-last line, it includes the main Yii class file, so that it can actually run the application as seen in the last line.  createWebApplication() accepts one argument: the path to the configuration file for the application.  In the configuration file you can configure things such as your database, error and mysql logging, and url routing.  The configurations are stored in the form of an array.  It&#8217;s a much simpler approach than cake&#8217;s, which uses a heavy configuration class.  Personally I am liking Yii&#8217;s array configuration syntax much better than cake&#8217;s (I will show you my Yii configuration file in a second).</p>
<p>Since in Yii you define the configuration file used in your index.php file, you can greatly simplify the synchronization between your development and production server &#8211; you simply need different index files and separate configuration files.  So I thought up a inheritance/tree system for configuration files.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="sy0">/</span>protected
	<span class="sy0">/</span>config
		<span class="sy0">/</span>main<span class="sy0">.</span>php
		<span class="sy0">/</span>production<span class="sy0">.</span>php
		<span class="sy0">/</span>development<span class="sy0">.</span>php</pre></div></div>

<p>Here, the production and development configuration files will simply extent the main configuration file which holds the configurations that are consistent across both production and development servers such as the url routing rules.  Possible examples of each file:</p>
<p>protected/config/<strong>main</strong>.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="co1">// This is the main Web application configuration.</span>
<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
	<span class="st_h">'basePath'</span> <span class="sy0">=&gt;</span> <span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span><span class="sy0">.</span>DIRECTORY_SEPARATOR<span class="sy0">.</span><span class="st_h">'..'</span><span class="sy0">,</span>
	<span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'My Web Application'</span><span class="sy0">,</span>
&nbsp;
	<span class="co1">// Tell's Yii is can auto-load model and component classes on-demand (lazy loading)</span>
	<span class="st_h">'import'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="st_h">'application.models.*'</span><span class="sy0">,</span>
		<span class="st_h">'application.components.*'</span><span class="sy0">,</span>
	<span class="br0">&#41;</span><span class="sy0">,</span>
	<span class="st_h">'preload'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'log'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="co1">//preload the log component right away (eager loading)</span>
&nbsp;
	<span class="co1">// application components</span>
	<span class="st_h">'components'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="st_h">'user'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="co1">// user component settings here (similar to CakePHP's auth component)</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="co1">//log class can output errors, mysql quarry summaries, etc.  The specific</span>
		<span class="co1">//settings are extended in the production and development config files</span>
		<span class="st_h">'log'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
	        	<span class="st_h">'class'</span> <span class="sy0">=&gt;</span> <span class="st_h">'CLogRouter'</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'urlManager'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'urlFormat'</span><span class="sy0">=&gt;</span><span class="st_h">'path'</span><span class="sy0">,</span>
			<span class="st_h">'showScriptName'</span> <span class="sy0">=&gt;</span> <span class="kw2">false</span><span class="sy0">,</span>
			<span class="st_h">'rules'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
				<span class="co1">// some generic url routes I often use</span>
				<span class="st_h">'user/register/*'</span> <span class="sy0">=&gt;</span> <span class="st_h">'user/create'</span><span class="sy0">,</span>
				<span class="st_h">'user/settings/*'</span> <span class="sy0">=&gt;</span> <span class="st_h">'user/update'</span><span class="sy0">,</span>
			<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
	<span class="br0">&#41;</span><span class="sy0">,</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>protected/config/<strong>development</strong>.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="co1">//import main configurations</span>
<span class="re0">$main</span> <span class="sy0">=</span> <span class="kw1">include</span> <span class="st0">&quot;main.php&quot;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Development configurations</span>
<span class="re0">$development</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span>
	<span class="st_h">'components'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="st_h">'db'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'class'</span> <span class="sy0">=&gt;</span> <span class="st_h">'CDbConnection'</span><span class="sy0">,</span>
			<span class="st_h">'connectionString'</span> <span class="sy0">=&gt;</span> <span class="st_h">'mysql:host=localhost;dbname=yiitestdrive'</span><span class="sy0">,</span>
			<span class="st_h">'username'</span> <span class="sy0">=&gt;</span> <span class="st_h">'root'</span><span class="sy0">,</span>
			<span class="st_h">'password'</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'log'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'routes'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
				<span class="co1">//set the log component to show logs on the bottom of the page - similar to CakePHP</span>
				<span class="kw3">array</span><span class="br0">&#40;</span>
					<span class="st_h">'class'</span> <span class="sy0">=&gt;</span> <span class="st_h">'CWebLogRoute'</span><span class="sy0">,</span>
					<span class="st_h">'levels'</span> <span class="sy0">=&gt;</span> <span class="st_h">'trace, info, error, warning'</span><span class="sy0">,</span>
					<span class="st_h">'categories'</span> <span class="sy0">=&gt;</span> <span class="st_h">'system.db.*'</span><span class="sy0">,</span>
				<span class="br0">&#41;</span><span class="sy0">,</span>
			<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
        <span class="br0">&#41;</span><span class="sy0">,</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">//merge both configurations and return them</span>
<span class="kw1">return</span> CMap<span class="sy0">::</span><span class="me2">mergeArray</span><span class="br0">&#40;</span><span class="re0">$main</span><span class="sy0">,</span> <span class="re0">$development</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>protected/config/<strong>production</strong>.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="co1">//import main configurations</span>
<span class="re0">$main</span> <span class="sy0">=</span> <span class="kw1">include</span> <span class="st0">&quot;main.php&quot;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Production configurations</span>
<span class="re0">$production</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span>
	<span class="st_h">'components'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="st_h">'db'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'class'</span> <span class="sy0">=&gt;</span> <span class="st_h">'CDbConnection'</span><span class="sy0">,</span>
			<span class="st_h">'connectionString'</span> <span class="sy0">=&gt;</span> <span class="st_h">'mysql:host=mysql@example.com;dbname=productionDatabase'</span><span class="sy0">,</span>
			<span class="st_h">'username'</span> <span class="sy0">=&gt;</span> <span class="st_h">'admin'</span><span class="sy0">,</span>
			<span class="st_h">'password '</span><span class="sy0">=&gt;</span> <span class="st_h">'password123'</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="st_h">'log'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
			<span class="st_h">'routes'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span>
				<span class="co1">// Configures Yii to email all errors and warnings to an email address</span>
				<span class="kw3">array</span><span class="br0">&#40;</span>
					<span class="st_h">'class'</span> <span class="sy0">=&gt;</span> <span class="st_h">'CEmailLogRoute'</span><span class="sy0">,</span>
					<span class="st_h">'levels'</span> <span class="sy0">=&gt;</span> <span class="st_h">'error, warning'</span><span class="sy0">,</span>
					<span class="st_h">'emails'</span> <span class="sy0">=&gt;</span> <span class="st_h">'admin@example.com'</span><span class="sy0">,</span>
				<span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="br0">&#41;</span><span class="sy0">,</span>
        <span class="br0">&#41;</span><span class="sy0">,</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">//merge both configurations</span>
<span class="kw1">return</span> CMap<span class="sy0">::</span><span class="me2">mergeArray</span><span class="br0">&#40;</span><span class="re0">$main</span><span class="sy0">,</span> <span class="re0">$production</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>As you can see, in the main config file we have the consistent settings such as URL routing, and in the production and development files we have inconsistent things such as database settings.  Note also in the production config I have errors and warnings sent to an email while in the development config I have all logs outputted at the bottom of the page.  Nifty, huh?  Now we can set up the index files for the production and development servers like so:</p>
<p>Development index.php file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$yii</span> <span class="sy0">=</span> <span class="st_h">'C:\wamp\www\yiiRepo\framework\yii.php'</span><span class="sy0">;</span>
<span class="re0">$config</span> <span class="sy0">=</span> <span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'/protected/config/'</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// turns debug on</span>
<span class="kw3">defined</span><span class="br0">&#40;</span><span class="st_h">'YII_DEBUG'</span><span class="br0">&#41;</span> or <span class="kw3">define</span><span class="br0">&#40;</span><span class="st_h">'YII_DEBUG'</span><span class="sy0">,</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="re0">$yii</span><span class="br0">&#41;</span><span class="sy0">;</span>
Yii<span class="sy0">::</span><span class="me2">createWebApplication</span><span class="br0">&#40;</span><span class="re0">$config</span> <span class="sy0">.</span> <span class="st_h">'development.php'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">run</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Production index.php file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="re0">$yii</span> <span class="sy0">=</span> <span class="st_h">'framework/yii.php'</span><span class="sy0">;</span>
<span class="re0">$config</span> <span class="sy0">=</span> <span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'/protected/config/'</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">require_once</span><span class="br0">&#40;</span><span class="re0">$yii</span><span class="br0">&#41;</span><span class="sy0">;</span>
Yii<span class="sy0">::</span><span class="me2">createWebApplication</span><span class="br0">&#40;</span><span class="re0">$config</span> <span class="sy0">.</span> <span class="st_h">'production.php'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">run</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Now you can easily set different settings for production and development set-ups without redundancy.  Enjoy.</p>
<p>UPDATE: Qiang wrote his own version of this method in the Yii Cookbook <a href="http://www.yiiframework.com/doc/cookbook/32/">here</a>.  He recommends you merge the configurations with <em><a href="http://www.yiiframework.com/doc/api/CMap#mergeArray-detail">CMap::mergeArray()</a></em> instead of <em>array_merge_recursive()</em>.  I have changed this article to use <em>CMap</em> also. <em>CMap::mergeArray()</em> is a helper method that comes from the Yii core.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2008/running-your-yii-app-and-configuring-it/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>My findings in Yii and comparisons to CakePHP</title>
		<link>http://php-thoughts.cubedwater.com/2008/my-findings-in-yii-and-comparisons-to-cakephp/</link>
		<comments>http://php-thoughts.cubedwater.com/2008/my-findings-in-yii-and-comparisons-to-cakephp/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 09:00:07 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=63</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />Since I have found out about Yii I have been using it to work on a &#8220;dummy&#8221; website with features that are generally used across a large variety of websites (e.g. news system, user system, authorization, etc).  This is also exactly what I did with CakePHP when I first started learning it, and the [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>Since I have found out about <a href="http://www.yiiframework.com/">Yii</a> I have been using it to work on a &#8220;dummy&#8221; website with features that are generally used across a large variety of websites (e.g. news system, user system, authorization, etc).  This is also exactly what I did with <a href="http://cakephp.org/">CakePHP</a> when I first started learning it, and the reason I do this is not only so I have a set of re-usable resources but also to help learn the framework.  Although I still consider myself a novice in Yii I have learned a lot of things about it, some things very similar to CakePHP while other things very different.  It&#8217;s a learning experience and I must say Yii so far seems a better alternative to CakePHP for many reasons.  I will outline a few reasons/differences here.</p>
<p><strong>PHP 5 features included in the core</strong><br />
First, and most importantly, what allows for most of the stuff that I love in Yii over CakePHP is that it is PHP 5 only.  PHP 4 is not supported.  Because of this, Yii is able to take use of many PHP 5 features that Cake is not able to.  Mainly, that would be the PHP 5 <a href="http://us.php.net/manual/en/language.oop5.overloading.php">magic overloading functions</a>, which leads to the next point:</p>
<p><strong>OOP style AR and lazy loading</strong><br />
Yii takes use of PHP 5&#8217;s overloading functions in its AR implantation in a very beautiful manner.  Instead of storing results from quarries in an array as Cake does, in Yii you can access the quarries in an OOP manner.  Here is an simple example of accessing AR in Yii, taken out of the Yii documentation.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="co1">//Database scheme is 'post' BELONGS_TO 'user'.  Each row in the 'posts' table has a corresponding row in the 'users' table.</span>
<span class="co1">// retrieve the post whose ID is 10</span>
<span class="re0">$post</span> <span class="sy0">=</span> Post<span class="sy0">::</span><span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findByPk</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// retrieve the post's author: a relational query will be performed here</span>
<span class="re0">$user</span> <span class="sy0">=</span> <span class="re0">$post</span><span class="sy0">-&gt;</span><span class="me1">user</span><span class="sy0">;</span></pre></div></div>

<p>Note the last line.  What actually happens is that the related user data is loaded dynamically by simply calling the variable.  The reason for this is because Yii takes use of <a href="http://en.wikipedia.org/wiki/Lazy_loading">lazy</a> <a href="http://www.yiiframework.com/doc/guide/database.arr#performing-relational-query">loading</a> (and of course PHP 5&#8217;s magic).  This means the data is not retrieved until it is actually needed, increasing performance and ease of programming.  If lazy loading does not fit you, you can use eager loading too, which will work similar to Cake&#8217;s ContainableBehavior.  Example:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$posts</span> <span class="sy0">=</span> Post<span class="sy0">::</span><span class="me2">model</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">with</span><span class="br0">&#40;</span><span class="st_h">'user'</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">findByPk</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Now that is what I call beautiful code. You can probably tell what the above does implicitly, but if you can&#8217;t, it simply pulls the post with id of 10 along with its corresponding user (a mysql JOIN will be used).  Beautiful? I think yes.</p>
<p><strong><em>Excellent</em> Documentation</strong><br />
And you can <a href="http://www.yiiframework.com/doc/">find that out for yourself</a>.</p>
<p><strong>Fast and useful developer feedback</strong><br />
Along with the documentation the <a href="http://www.yiiframework.com/forum/">Yii forum</a> is also an excellent place to get help.  I have posted a few questions/bug reports there and have gotten very fast feedback, from the lead developer himself if from no one else.  The bug reports and enchantments I requested there [<a href="http://www.yiiframework.com/forum/index.php/topic,311.msg1482.html#msg1482">1</a>, <a href="http://www.yiiframework.com/forum/index.php/topic,355.msg1697.html#msg1697">2</a>, <a href="http://www.yiiframework.com/forum/index.php/topic,210.msg968.html#msg968">3</a>] were all fixed/implanted within 24 hours of reporting.  Therefore I give Yii two thumbs up for developer feedback.  Arguably the user feedback is not as good has Cake&#8217;s user feedback however, as Cake is much more well known and more widely in use (Yii only just came out with a stable version I believe this month).  But developer feedback is more valuable than user feedback in my opinion.</p>
<p><strong>Faster</strong><br />
<a href="http://www.yiiframework.com/performance">Benchmarks</a>.</p>
<p><strong>Integration with jQuery</strong><br />
Cake uses prototype. Booo!</p>
<p><strong>More easily extended</strong><br />
One example I have for this so far and that I have tested are the validation rules.  Not only can you define a action in the model as a validation as in Cake, but you can can define a whole class to be a validation type.  For instance, you could create a <em>authenticatePass</em> class that works as a validator that you can easily drop into your projects.  Then you could use it in your model as so:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">public</span> <span class="kw2">function</span> rules<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">return</span> <span class="kw3">array</span><span class="br0">&#40;</span>
		<span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'password'</span><span class="sy0">,</span> <span class="st_h">'authenticatePass'</span><span class="br0">&#41;</span><span class="sy0">,</span>
		<span class="co1">//more rules...</span>
	<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>The above validator could be designed to validate the password to the username (if sent) in the users table.</p>
<p><strong>Regarding the design pattern</strong><br />
As far as the structure, e.g. the MVC design pattern, Yii and CakePHP are very similar.  They both have &#8220;components&#8221; for example.  Yii also has &#8220;widgets&#8221;, which can represent anything from a form calendar to a navigational menu.  Widgets consist of both components and views, so in a way, they are similar to Cake&#8217;s &#8220;plugins&#8221; I suppose, but they are not so intimidating to create.  Yii also has <a href="http://www.yiiframework.com/extensions/">their own version</a> of the Bakery for sharing extensions.</p>
<p>Since this post is quite long enough, I will stop here.  In future articles I will try to focus on more narrow topics as I don&#8217;t feel this post is nearly long enough to satisfy my given subject line.  Oh well.  Hope you learned something useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2008/my-findings-in-yii-and-comparisons-to-cakephp/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>
