<?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>web(cslai) &#187; PHP</title>
	<atom:link href="http://cslai.coolsilon.com/category/web-development/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://cslai.coolsilon.com</link>
	<description>Findings and Notes in Web Development</description>
	<lastBuildDate>Tue, 06 Sep 2011 08:15:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Redland for RDF Work</title>
		<link>http://cslai.coolsilon.com/2011/05/13/redland-for-rdf-work/</link>
		<comments>http://cslai.coolsilon.com/2011/05/13/redland-for-rdf-work/#comments</comments>
		<pubDate>Fri, 13 May 2011 06:47:20 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Semantic Web]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=226</guid>
		<description><![CDATA[Although my supervisor strongly recommend using JENA for RDF related work, but as I really don&#8217;t like Java (just personal preference), and wouldn&#8217;t want to install JRE/JVM (whatever it is called) at my shared server account, so I went to look for an alternative. After spending some time searching, I found this library called Redland [...]]]></description>
			<content:encoded><![CDATA[<p>Although my supervisor strongly recommend using JENA for RDF related work, but as I really don&#8217;t like Java (just personal preference), and wouldn&#8217;t want to install JRE/JVM (whatever it is called) at my shared server account, so I went to look for an alternative. After spending some time searching, I found this library called <a href="http://librdf.org/">Redland</a> and it provides binding for my current favorite language &#8212; PHP, so I decided to use this for my RDF work.</p>
<p><span id="more-226"></span></p>
<p>I used pure relational database approach (postgresql to be exact) to store information collected via flickr initially, but it wouldn&#8217;t really scale (or I just simply suck at designing/maintaining database tables) and my queries got killed numerously by the web host. Besides that, as the table grow larger, the amount of resource consumed to serve a query also grow, hence I needed to find another way to store the data. At first I thought of using some popular noSQL solutions, but my supervisor told me to turn the data into RDF format instead. So I went on with Redland and use postgresql (again) as storage.</p>
<p>However, for some reason, postgresql doesn&#8217;t seem to work efficiently and a simple query can take tens of minutes to run when it holds more than 100k RDF statements. For some reason, the <a href="http://stackoverflow.com/questions/5882707/getting-statements-from-redland-hash-storage">hash storage doesn&#8217;t work</a> on my Ubuntu development VM, so I switched the storage engine to MySQL after <a href="https://twitter.com/#!/dajobe/status/67969726550253568">@dajobe&#8217;s suggestion</a>.</p>
<p>However, as PHP binding apparently not that popular, so there aren&#8217;t much information / tutorial posted. I actually wanted to write a collection of scripts to collect data from <a href="http://flickr.com/">flickr</a> for my research project, so I began with finding an existing script for that task. However, I didn&#8217;t find good ones in PHP, so I ported <a href="https://github.com/straup/p5-Net-Flickr-RDF">this from Perl</a> to PHP and use Redland. Then after knowing how it really works, I rewrote everything again from scratch (will put them up to bitbucket when I have time to clean up). I even wrapped the library with class methods, which I hope to release later (I only knew about another <a href="http://blog.literarymachine.net/?p=5">OO wrapper in PHP</a> for Redland after almost done writing my scripts).</p>
<p>To use Redland&#8217;s PHP functions without OO wrapper, we always start with a statement to build a world. I am not very sure what this means (yes, I didn&#8217;t really read the <a href="http://librdf.org/docs/api/index.html">documentation</a> that thoroughly), but it seems that almost all constructor functions depend on it to create new object (yes, Redland has this OO feel although all the function calls are in procedural style). So, in PHP, the statement would look like:</p>
<pre class="php"><code>$world = librdf_new_world();</code></pre>
<p>Then you would want to decide <a href="http://librdf.org/docs/api/redland-storage-modules.html">where to store your RDF statements</a>. For this piece of note, I will just use non-persistent memory store. So the function call to build a storage object is</p>
<pre class="php"><code>$storage = librdf_new_storage($world, 'memory', $name, $options);</code></pre>
<p>where <code>$name</code> stores the name of the storage object, and <code>$options</code> often carries the <abbr title="Database Source Name">DSN</abbr>, but in our case it is NULL. Now that we have storage defined, then we proceed with building a model to actually store RDF statements into the storage (it would be easy to think model as a database library, and storage as an abstraction layer).</p>
<pre class="php"><code>$model = librdf_new_model($world, $storage, NULL);</code></pre>
<p>Statements are consists of nodes, so let&#8217;s create some. To create a URI node, it is just as easy as</p>
<pre class="php"><code>$foo = librdf_new_node_from_uri_string($world, 'urn:foo');
$bar = librdf_new_node_from_uri_string($world, 'urn:bar');</code></pre>
<p>Creating a literal node would be just as simple as</p>
<pre class="php"><code>$baz = librdf_new_node_from_literal($world, 'baz', NULL, FALSE);</code></pre>
<p>Putting them into a statement</p>
<pre class="php"><code>$statement = librdf_new_statement_from_nodes($world, $foo, $bar, $baz);</code></pre>
<p>which is the equivalent to this</p>
<pre><code>&lt;urn:foo&gt; &lt;urn:bar&gt; 'baz' .</code></pre>
<p>To run a query to the model, just simply send a SPARQL statement as follows</p>
<pre><code>
$query = librdf_new_query(
    $world,
    'sparql',
    NULL,
<<<SPARQL
SELECT  ?subject, ?object
WHERE   {
            ?subject <urn:bar> ?object .
        }
SPARQL
);
</code></pre>
<p>Running the query and get result</p>
<pre><code>$result = librdf_model_query_execute($model, $query);
var_dump(librdf_query_results_to_string2($result, 'json', 'application/json', NULL, NULL));</code></pre>
<p>Enjoy!</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2011/05/13/redland-for-rdf-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mixing Non-array and Array in array_map()</title>
		<link>http://cslai.coolsilon.com/2010/01/28/mixing-non-array-and-array-in-array_map/</link>
		<comments>http://cslai.coolsilon.com/2010/01/28/mixing-non-array-and-array-in-array_map/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 03:34:07 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array_map]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=141</guid>
		<description><![CDATA[array_map function is a function that I use the most in my php scripts recently. However, there are times where I want to pass some non-array into it, therefore often times I have code like the snippet shown below: $result = array_map( 'some_callback', array_fill(0, count($some_array), 'some_string'), array_fill(0, count($some_array), 'some_other_string'), $some_array ) It doesn&#8217;t look good [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.php.net/manual/en/function.array-map.php">array_map</a> function is a function that I use the most in my php scripts recently. However, there are times where I want to pass some non-array into it, therefore often times I have code like the snippet shown below:</p>
<p><code class="php">$result = array_map(<br />
    'some_callback',<br />
    array_fill(0, count($some_array), 'some_string'),<br />
    array_fill(0, count($some_array), 'some_other_string'),<br />
    $some_array<br />
)</code></p>
<p>It doesn&#8217;t look good IMO, as it makes the code looks complicated. Hence, after seeing how the code may vary in all different scenarios, I created some functions to clean up the array_map call as seen above. Code snippet after the jump</p>
<p><span id="more-141"></span></p>
<p><code class="php">function array_map_mix($callback, $param) {<br />
    $main = array();</p>
<p>    $args = func_get_args();</p>
<p>    if((is_numeric($param) &#038;&#038; count($args) < 3)<br />
        || (is_array($param) &#038;&#038; count($args) < 2)) {<br />
        throw new Exception('No input available.');<br />
    } elseif(is_array($param)) {<br />
        list($main, $param) = array($param, count($param));<br />
    } elseif(is_numeric($param) === FALSE) {<br />
        throw new Exception('Invalid parameter');<br />
    }</p>
<p>    return call_user_func_array(<br />
        'array_map',<br />
        array_merge(<br />
            array($callback),<br />
            count($main) > 0 ? array($main) : array(),<br />
            count($args) - 2 > 0 ?<br />
                array_map(<br />
                    'array_create',<br />
                    array_create(count($args) - 2, $param),<br />
                    array_slice($args, 2)<br />
                )<br />
                : array()<br />
        )<br />
    );<br />
}</p>
<p>function array_create($count, $input) {<br />
    $result = array_fill(0, $count, NULL);</p>
<p>    if(is_array($input) &#038;&#038; count($input) == 1 &#038;&#038; is_array($input[0])) {<br />
        $result = array_fill(0, $count, $input[0]);<br />
    } else if(is_array($input) &#038;&#038; count($input) == $count) {<br />
        $result = $input;<br />
    } else {<br />
        $result = array_fill(0, $count, $input);<br />
    }</p>
<p>    return $result;<br />
}</code></p>
<h2>array_create</h2>
<p>Before stepping into the main array_map_mix function, we first look at the array_create function. It is basically a variant of <a href="http://www.php.net/manual/en/function.array-fill.php">array_fill</a> function, but without the initial index argument.</p>
<p>The important argument here is the <code class="php">$input</code> argument, depending on what is passed into the function, the end result can be different. If anything but array is passed in, then it will behave exactly like the array_fill call as follows:</p>
<p><code class="php">$foo = array_create(5, 'bar');<br />
// is equivalent to<br />
$foo = array_fill(0, 5, 'bar');</code></p>
<p>However, if an array is passed in, and the array element count is equivalent to the <code class="php">$count</code> argument, then array_create will return <code class="php">$input</code> without any modification.</p>
<p><code class="php">array('bar', 'baz') == array_create(2, array('bar', 'baz'));</code></p>
<p>If the array passed in has one and only one element, and the element happens to be another array, then the child array is passed into the array_fill function, as follows</p>
<p><code class="php">$foo = array_create(3, array(array('bar', 'baz')));<br />
// is equivalent to<br />
$foo = array_fill(0, 3, array('bar', 'baz'))</code></p>
<p>If the array passed in doesn&#8217;t fulfill the above two conditions, then the end result is similar like passing in a non-array argument.</p>
<p><code class="php">$foo = array_create(3, array('bar'));<br />
// is equivalent to<br />
$foo = array_fill(0, 3, array('bar'));</code></p>
<p>The weird behavior caused by the array argument is actually intended, as this function is initially created for the following function, which is the array_map_mix function.</p>
<h2>array_map_mix</h2>
<p>The first 2 mandatory arguments for array_map_mix are the <code class="php">$callback</code> as well as <code class="php">$param</code>. The <code class="php">$callback</code> is the callback function, and <code class="php">$param</code> is the parameter. The parameter can be either a number, or an array.</p>
<p>When a number is passed in as the parameter, then the code is throwing all the following arguments into array_create function as described above, with the number is sent in as <code class="php">$count</code>. This is an example showing the equivalent array_map function call.</p>
<p><code class="php">$foo = array_map_mix(<br />
    'some_callback',<br />
    2,<br />
    array('foo', 'bar'),<br />
    'baz'<br />
);<br />
// is equivalent to<br />
$foo = array_map(<br />
    'some_callback',<br />
    array('foo', 'bar'),<br />
    array_fill(0, 2, 'baz')<br />
);</code></p>
<p>What if the number passed in does not equal to the count of array elements?</p>
<p><code class="php">$foo = array_map_mix(<br />
    'some_callback',<br />
    2,<br />
    array('foo', 'bar', 'baz')<br />
);<br />
// is equivalent to<br />
$foo = array_map(<br />
    'some_callback',<br />
    array_fill(0, 2, array('foo', 'bar', 'baz'))<br />
);</code></p>
<p>What if I have 2 array, <code class="php">$foo</code> and <code class="php">$bar</code>, even both has the same amount of array elements, but I want the callback to receive <code class="php">$bar</code> as a whole, instead of just an element?</p>
<p><code class="php">// given<br />
count($foo) == count($bar);<br />
// wants this<br />
$foo = array_map(<br />
    'some_callback',<br />
    $foo,<br />
    array_fill(0, count($foo), $bar)<br />
);<br />
// equivalent array_map_mix call<br />
$foo = array_map_mix(<br />
    'some_callback',<br />
    count($foo),<br />
    $foo,<br />
    array($bar)<br />
);</code></p>
<p>Hopefully this explains why array_create is coded like above. As mentioned above, <code class="php">$param</code> can be an array as well. This is helpful when the count of array to be passed to array_map is dynamic and a fixed number is not always available.</p>
<p><code class="php">// suppose function foo() returns an array of variable size<br />
$foo = array_map_mix(<br />
    'some_callback',<br />
    foo(),<br />
    'baz'<br />
);<br />
// the equivalent code<br />
$bar = foo();<br />
$foo = array_map(<br />
    'some_callback',<br />
    $bar,<br />
    array_fill(0, count($bar), 'baz')<br />
);</code></p>
<p>Nevertheless, array_map_mix can also be used as a direct array_map alternative, although this is not advisible as the function call should take much longer time to complete because of the call_user_func_array call within array_map_mix.</p>
<p><code class="php">array_map('some_callback', array('foo', 'bar')) == array_map_mix('some_callback', array('foo', 'bar'));</code></p>
<p>The total number of arguments required is 2 when <code class="php">$param</code> is an array (means using array_map_mix as array_map) and 3 when <code class="php">$param</code> is a non-array. An exception will be thrown if expected argument is missing. Also, if anything but an array or a number is passed into array_map_mix as <code class="php">$param</code>, then another exception is thrown.</p>
<p>Hopefully these two short code snippet helps for people who uses array_map as much as I do.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2010/01/28/mixing-non-array-and-array-in-array_map/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello World from Zend MVC</title>
		<link>http://cslai.coolsilon.com/2009/09/08/hello-world-from-zend-mvc/</link>
		<comments>http://cslai.coolsilon.com/2009/09/08/hello-world-from-zend-mvc/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 14:00:22 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=125</guid>
		<description><![CDATA[This post continued from this post. Finally I have found some time to start developing my pet project using Zend Framework. After getting the controller to work the way I am more familiar (comparing to Kohana which I used at work) with, the next step is to get it to output some data. Base Action [...]]]></description>
			<content:encoded><![CDATA[<p>This post continued from this <a href="http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/">post</a>. Finally I have found some time to start developing my pet project using <a href="http://framework.zend.com/">Zend Framework</a>. After getting the controller to work the way I am more familiar (comparing to <a href="http://www.kohanaphp.com/">Kohana</a> which I used at work) with, the next step is to get it to output some data.</p>
<p><span id="more-125"></span></p>
<h3>Base Action Controller</h3>
<p>When I used other frameworks like Kohana or <a href="http://codeigniter.com/">CodeIgniter</a>, without extra modules installed, I would have to define view scripts specifically. However, in Zend_Controller, a view is likely to be defined properly and is waiting for data to be populated in. However, I still don&#8217;t get any output after a few attempts so I went to compare my dispatch method in the derived action controller with Zend_Controller_Action. The following code shows the updated dispatch method:</p>
<p><code class="php"><br />
    public function dispatch($actionName) {<br />
        $this->_helper->notifyPreDispatch();<br />
        $this->preDispatch();<br />
        $parameters = array();<br />
        foreach($this->_parametersMeta($actionName) as $paramMeta) {<br />
            $parameters = array_merge(<br />
                $parameters,<br />
                $this->_parameter($paramMeta, $this->_getAllParams())<br />
            );<br />
        }<br />
        call_user_func_array(array(&#038;$this, $actionName), $parameters);<br />
        $this->postDispatch();<br />
        $this->_helper->notifyPostDispatch();<br />
    }<br />
</code></p>
<p>Apparently there are some &#8216;hooks&#8217; that needs to be called throughout the dispatching process. Besides that, I want my view scripts to be loaded from another folder instead of the default ones, so I added a init method in the base action controller, as follows:</p>
<p><code class="php"><br />
    public function init() {<br />
        $this->view->addScriptPath(sprintf('%s/View', APP_PATH));<br />
    }<br />
</code></p>
<p>The script path should be defined during bootstrap phase, and I will post up a better solution once I find the exact place to configure it. Now that we have our base action controller fixed, let&#8217;s move to the actual action controller.</p>
<h3>Action Controller</h3>
<p>I am not sure whether action stack is <a href="http://en.wikipedia.org/wiki/Presentation-abstraction-control">HMVC</a>, however, I like the way it works (although it is <a href="http://www.rmauger.co.uk/2009/03/why-the-zend-framework-actionstack-is-evil/">evil</a>). I will probably stick to action stack for the time being while finding out how partial view can help in widgetizing my page. Besides having a view defined automatically, to put them into a layout I made a call in my bootstrap script, as follows:</p>
<p><code class="php"><br />
        Zend_Layout::startMvc(array(<br />
            'layoutPath' => APP_PATH . '/View/_layout'<br />
        ));<br />
</code></p>
<p>Then I did the action stack thingy as follows:</p>
<p><code class="php"><br />
class Controller_Index<br />
    extends Coolsilon_Controller_Base {<br />
    public function index() {<br />
        $this->_helper->actionStack('menu', 'index');<br />
    }<br />
    public function menu() {<br />
        $this->_helper->viewRenderer->setResponseSegment('menu');<br />
    }<br />
}<br />
</code></p>
<p>Then, in my View/_layout/layout.phtml, </p>
<p><code class="php"><br />
< ?php echo $this->layout()->menu; ?><br />
< ?php echo $this->layout()->content; ?><br />
</code></p>
<p>View/index/index.phtml</p>
<p><code>This is the main content.</code></p>
<p>View/index/menu.phtml</p>
<p><code>This is the menu.</code></p>
<p>Then by visiting the project site, then I get the following output</p>
<p><code><br />
This is the menu.<br />
This is the main content.<br />
</code></p>
<p>Phew, I can&#8217;t believe I spent so much time on this easy stuff, XD. Now I am one step closer in writting the actual website, now what kind of website should I make?</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/09/08/hello-world-from-zend-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending Zend Framework</title>
		<link>http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/</link>
		<comments>http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 14:31:18 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=91</guid>
		<description><![CDATA[I like how Kohana 3 organizes the classes, and I thought the same thing may be applied to my Zend Framework experimental project. Basically what this means is that I can name the controller class according to PEAR naming convention, and deduce the location of the file by just parsing the class name. Suppose the [...]]]></description>
			<content:encoded><![CDATA[<p>I like how Kohana 3 organizes the <a href="http://forum.kohanaphp.com/comments.php?DiscussionID=1096&#038;page=1">classes</a>, and I thought the same thing may be applied to my Zend Framework experimental project. Basically what this means is that I can name the controller class according to PEAR naming convention, and deduce the location of the file by just parsing the class name.</p>
<p><span id="more-91"></span></p>
<p>Suppose the file structure of my experimental project as follows</p>
<ul>
<li>
		private_files</p>
<ul>
<li>Model</li>
<li>View</li>
<li>
				Controller</p>
<ul>
<li>Index.php</li>
</ul>
</li>
<li>Libraries</li>
</ul>
</li>
<li>public_html</li>
</ul>
<p>I am expecting if I need to load a controller named Controller_Index, then it should be able to find the controller class file in private_files/Controller/Index.php. To do so, as hinted by <a href="http://stackoverflow.com/users/45531/tim-lytle">Tim Lytie</a> at <a href="http://stackoverflow.com/questions/378284/zendcontroller-following-pear-naming-convention">stackoverflow</a>, I wrote a dispatcher class that subclassed from Zend_Dispatcher_Standard as follows</p>
<p><code class="php"><br />
class Coolsilon_Controller_Dispatcher<br />
    extends Zend_Controller_Dispatcher_Standard {<br />
    public function __construct() {<br />
        parent::__construct();<br />
    }<br />
&nbsp;<br />
    public function formatControllerName($unformatted) {<br />
        return sprintf(<br />
            'Controller_%s', ucfirst($this->_formatName($unformatted))<br />
        );<br />
    }<br />
&nbsp;<br />
    public function formatActionName($unformatted) {<br />
        $formatted = $this->_formatName($unformatted, true);<br />
        return strtolower(substr($formatted, 0, 1)) . substr($formatted, 1);<br />
    }<br />
}<br />
</code></p>
<p>Then, in order to make the parameters passed in as <a href="http://stackoverflow.com/questions/378284/zendcontroller-following-pear-naming-convention">method parameters</a>, after reading through the code as <a href="http://devzone.zend.com/article/2855-Actions-now-with-parameters">posted here</a>, I refactored it to (I &lt;3 short methods).</p>
<p><code class="php"><br />
abstract class Coolsilon_Controller_Base<br />
    extends Zend_Controller_Action {<br />
&nbsp;<br />
    public function dispatch($actionName) {<br />
        $parameters = array();<br />
&nbsp;<br />
        foreach($this->_parametersMeta($actionName) as $paramMeta) {<br />
            $parameters = array_merge(<br />
                $parameters,<br />
                $this->_parameter($paramMeta, $this->_getAllParams())<br />
            );<br />
        }<br />
&nbsp;<br />
        call_user_func_array(array(&#038;$this, $actionName), $parameters);<br />
    }<br />
&nbsp;<br />
    private function _actionReference($className, $actionName) {<br />
        return new ReflectionMethod(<br />
            $className, $actionName<br />
        );<br />
    }<br />
&nbsp;<br />
    private function _classReference() {<br />
        return new ReflectionObject($this);<br />
    }<br />
&nbsp;<br />
    private function _constructParameter($paramMeta, $parameters) {<br />
        return array_key_exists($paramMeta->getName(), $parameters) ?<br />
            array($paramMeta->getName() => $parameters[$paramMeta->getName()]) :<br />
            array($paramMeta->getName() => $paramMeta->getDefaultValue());<br />
    }<br />
&nbsp;<br />
    private function _parameter($paramMeta, $parameters) {<br />
        return $this->_parameterIsValid($paramMeta, $parameters) ?<br />
            $this->_constructParameter($paramMeta, $parameters) :<br />
            $this->_throwParameterNotFoundException($paramMeta, $parameters);<br />
    }<br />
&nbsp;<br />
    private function _parameterIsValid($paramMeta, $parameters) {<br />
        return $paramMeta->isOptional() === FALSE<br />
            &#038;&#038; empty($parameters[$paramMeta->getName()]) === FALSE;<br />
    }<br />
&nbsp;<br />
    private function _parametersMeta($actionName) {<br />
        return $this->_actionReference(<br />
                $this->_classReference()->getName(),<br />
                $actionName<br />
            )<br />
            ->getParameters();<br />
    }<br />
&nbsp;<br />
    private function _throwParameterNotFoundException($paramMeta, $parameters) {<br />
        throw new Exception("Parameter: {$paramMeta->getName()} Cannot be empty");<br />
    }<br />
}<br />
</code></p>
<p>It may affect the performance but the code is much easier to read as I am the only one who is wokring on the project.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2009/03/28/extending-zend-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Blending ACL and FSM-based Workflow</title>
		<link>http://cslai.coolsilon.com/2008/10/01/blending-acl-and-fsm-based-workflow/</link>
		<comments>http://cslai.coolsilon.com/2008/10/01/blending-acl-and-fsm-based-workflow/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 04:07:08 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=61</guid>
		<description><![CDATA[After reading through the documentation, I find that the role based ACL and work flow can be more tightly integrated. Therefore I made all the transaction into many FSMs and my work flow component now consists of one work flow library and one work flow management model. As I am going a more normalized design [...]]]></description>
			<content:encoded><![CDATA[<p>After reading through the documentation, I find that the role based ACL and work flow can be more tightly integrated. Therefore I made all the transaction into many FSMs and my work flow component now consists of one work flow library and one work flow management model. As I am going a more normalized design (I use denormalized design in work as it deals with a lot of documents, however for a small project like mine, a denormalized design should do well).</p>
<p><span id="more-61"></span></p>
<p>So for the current stage, I have a set of relations as follows.</p>
<p>Resources (resource_id, name, description) a nested set table<br />
Roles (role_id, name, description) a nested set table</p>
<p>Resources table stores resources available in the system (duh~), and Roles table stores roles available in the system&#8230; Both of them are nested set table as they store hierarchical data (handled by doctrine). The documentation provided by Zend states that:</p>
<blockquote><ul>
<li>a <strong>resource</strong> is an object to which access is controlled.</li>
<li>a <strong>role</strong> is an object that may request access to a <strong>Resource</strong>.</li>
</ul>
<p>Put simply, <strong>roles request access to resources</strong>. For example, if a parking attendant requests access to a car, then the parking attendant is the requesting role, and the car is the resource, since access to the car may not be granted to everyone. </p></blockquote>
<p>So in my project, to further simplifying the concept, a resource simply means a table which access is managed.</p>
<p>Then I have a states table, which is one of the key tables in work flow component. </p>
<p>States (state_id, name, description, is_start, is_end, is_delete)</p>
<p>Each record has a state, therefore each of the record references to this table to find out what the state is. There are three boolean fields added, which is `is_start`, `is_end` and `is_delete`, to further describe the status. As there is a is_delete field, the site will have the unwanted record soft deleted at first.</p>
<p>Then we have a composite table to link up resource and states to be used later</p>
<p>States_Resources (state_resource_id, state_id *, resource_id *)</p>
<p>Followed by the actions table, which provide a set of verbs that can be used as action name. The primary concern of having this table is to achieve consistency. Otherwise I would have URL in the form of user/profile/edit, post/update, feed/edit. </p>
<p>Actions (action_id, name, description)</p>
<p>Followed by the transition table, which stores possible transition for each of the resource at every state. Speaking in terms of Zend_ACL, each transition is like a privilege which is explained by Zend as follows:</p>
<blockquote><p>Zend_Acl also supports privileges on resources (e.g., &#8220;create&#8221;, &#8220;read&#8221;, &#8220;update&#8221;, &#8220;delete&#8221;), so the developer can assign rules that affect all privileges or specific privileges on one or more resources. </p></blockquote>
<p>Transitions (transition_id, action_id *, from_resource_state_id *, to_resource_state_id *)</p>
<p>Then I have access_rules table which stores the actual ACL</p>
<p>Access_Rules (access_rules_id, role_id, transition_id)</p>
<p>To check whether a transition is doable, frequently I would have to check the condition through some callback functions, therefore I need to store them into another table.</p>
<p>Transitions_Callbacks (transition_callback_id, transition_id *, callback_class_id *)</p>
<p>Callback_Classes (callback_class_id, name)</p>
<p>Lastly, the history table (there is nothing much to track at the moment)</p>
<p>Transition_History (transition_history_id, transition_id, user_id, ip_address, timestamp)</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2008/10/01/blending-acl-and-fsm-based-workflow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVC: Kohana vs. Zend Framework</title>
		<link>http://cslai.coolsilon.com/2008/09/30/mvc-kohana-vs-zend-framework/</link>
		<comments>http://cslai.coolsilon.com/2008/09/30/mvc-kohana-vs-zend-framework/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 08:58:22 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Active Record]]></category>
		<category><![CDATA[Kohana]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=56</guid>
		<description><![CDATA[After comparing my own implementation of MVC with CodeIgniter&#8217;s, now I&#8217;m comparing Kohana&#8217;s and Zend&#8217;s. I have just shifted from CodeIgniter to Kohana recently in work and is currently learning on how to use Zend Framework to build my web-app. As everybody knows, Zend Framework is more like a collection of library classes than a [...]]]></description>
			<content:encoded><![CDATA[<p>After <a href="http://cslai.coolsilon.com/2008/03/19/mvc-me-vs-codeigniter/">comparing my own implementation of MVC with CodeIgniter&#8217;s</a>, now I&#8217;m comparing Kohana&#8217;s and Zend&#8217;s. I have just shifted from CodeIgniter to Kohana recently in work and is currently learning on how to use Zend Framework to build my web-app. As everybody knows, Zend Framework is more like a collection of library classes than a framework a la Ruby on Rails, using MVC in Zend Framework would require one to begin from bootstrapping stage. However, in Kohana, just like other frameworks, bootstrapping is done by the framework itself so the developer will get an installation that almost just works (after a little bit of configuration).</p>
<p><span id="more-56"></span></p>
<h2>Controller</h2>
<p>Basically there is no much difference in the controller, besides the naming convention that one has to follow. However, in Zend Framework, every public action method in the controller will be configured to a view template by default. For example, if you have a controller as follows:</p>
<p><code class="php"><br />
&lt;?php<br />
    class IndexController extends Zend_Controller {<br />
        public function __construct() {<br />
            parent::__construct();<br />
        }<br />
&nbsp;<br />
        public function indexAction() {<br />
            // some code<br />
        }<br />
    }<br />
</code></p>
<p>Even if you choose only to perform one print hello world statement, you will still get an error message indicating that the view is not found, as follows:</p>
<blockquote><p>Uncaught exception &#8216;Zend_View_Exception&#8217; with message &#8216;script &#8216;index/index.phtml&#8217; not found</p></blockquote>
<p>Just like what I mentioned above, in Kohana, they don&#8217;t even care whether you are using view, I can simply just output from the controller whenever I want. </p>
<h2>View</h2>
<p>From the first glance, Kohana and Zend Framework is doing similar things with the View. In Kohana, you can have a view defined with the following code in the controller (or any other place):</p>
<p><code class="php"><br />
    // in the controller<br />
    // instantiate the view object<br />
    $view = new View('path_to_the_filename_without_extension');<br />
    // another form<br />
    $view = new View;<br />
    $view->set_filename('path_to_the_filename_without_extension');<br />
    // yet another form<br />
    $view = View::factory('path_to_the_filename_without_extension');<br />
&nbsp;<br />
    // inject in some values to the view to be manipulated<br />
    $view->set('variable_name', 'some value');<br />
    // this is also valid<br />
    $view->variable_name = 'some value';<br />
&nbsp;<br />
    // display the view<br />
    $view->render(TRUE);<br />
</code></p>
<p>Most of the time you won&#8217;t even need to further subclass the supplied View class. To display content to the browse, you will need a view file (more like a template file). The view file will be something like follows:</p>
<p><code class="html"><br />
&lt;html&gt;<br />
    &lt;head&gt;<br />
    &lt;/head&gt;<br />
    &lt;body&gt;<br />
        &lt;p&gt;&lt;?php echo $variable_name; ?&gt;&lt;/p&gt;<br />
    &lt;/body&gt;<br />
&lt;/html&gt;<br />
</code></p>
<p>In Zend Framework, the code is almost similar, but I think they have more to offer if you want flexibility.</p>
<h2>Model</h2>
<p>In Kohana, you have 2 choices, either to use ORM as model or just a model that doesn&#8217;t really do anything much by default. I use a variant of IgnitedRecord as model in work, and I just started to <a href="http://stackoverflow.com/questions/56546/activerecord-as-model-is-this-a-good-idea">question</a> whether ActiveRecord pattern is suitable as a model in MVC few weeks ago. In Zend Framework you get no model at all as you are expected to create one for yourself.</p>
<h2>Conclusion</h2>
<p>Nothing much to conclude, but through the comparison between 4 different implementations to MVC, I kinda learn a lot. As I have just only started learning MVC these days, I think I will post further notes on MVC in Zend Framework soon.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2008/09/30/mvc-kohana-vs-zend-framework/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Real Life Enterprise Class Website Development</title>
		<link>http://cslai.coolsilon.com/2008/05/28/real-life-enterprise-class-website-development/</link>
		<comments>http://cslai.coolsilon.com/2008/05/28/real-life-enterprise-class-website-development/#comments</comments>
		<pubDate>Wed, 28 May 2008 13:59:17 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=44</guid>
		<description><![CDATA[Recently I am involved in developing some small modules for a enterprise class website using CodeIgniter (CI). There was no restriction given on which framework should I use for the development and I chose CI as I learned a bit on it (when I was considering whether to shift my personal development project). Of course [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I am involved in developing some small modules for a enterprise class website using <a href="http://www.codeigniter.com/">CodeIgniter</a> (CI). There was no restriction given on which framework should I use for the development and I chose CI as I learned a bit on it (when I was considering whether to shift my personal development project). Of course there are other reasons why I chose to learn CI, for example the superior documentation and screencasts available.</p>
<p><span id="more-44"></span></p>
<p>Somehow the Technical Director prefers CI over Symphony (as my colleague, also a new staff member like me, was working with Symphony at the same time as I was developing my first project) which I don&#8217;t have any idea why. Then he made a decision to choose CI as the new framework to be used for future projects, well, at least for the particular project which we are still working on. The reason for the switch from internal framework to another framework like CI is that their internal framework was written for PHP4 and they want to switch to PHP5. </p>
<p>Their internal framework was very well done, at least from what my Technical Director showed. They have their own database abstraction layer, a CRUD application generator, Object-Relational Mapping etc. that really helps building an application fast. By comparing to their framework, I find CI although quite well done as well but it is no way near as good as the internal framework. Then I went looking around to find some plugins for the CI to implement some of the mentioned features above. Then I found <a href="http://rabbitforms.com/">Rabbit-Forms</a> for CRUD application generator and form generation, and <a href="http://www.cibase.info/index.php/code/details/22">Ignited Record</a> for proper ActiveRecord support.</p>
<p>However, I found Rabbit-Forms very restrictive and decided to write a simple form generator and CRUD application generator. Although the final product may not be good enough, but I certainly enjoyed and learned a lot through actually developing it.</p>
<p>These few days I am picking up Drupal, a content management system (CMS). Drupal is a very interesting system where one can almost build any website as long as it is community driven with it. However, there are a lot of things to learn to make sure you are not screwing your installation. I am extremely amazed by the way they implement the plugin system. Although it is a procedural system, but as my Technical Director says there are many <a href="http://api.drupal.org/api/file/developer/topics/oop.html/5">object oriented concepts being implemented</a>. Besides that, with plugins like CCK one can even do CRUD application with Drupal (although debugging will be extremely painful IMHO). There are a lot of fun stuff in Drupal for example the form generator, the hooking system, access control and of course their nearly perfect documentation (somehow i prefer it than YUI&#8217;s documentation).</p>
<p>Besides that, I am also doing some personal reading on Test Driven Development (TDD) and is currently focusing on unit testing PHP scripts with simpletest. Many developers who practices TDD claimed that TDD helps increasing the productivity. However after reading many documents and I am still don&#8217;t have the idea how to set up tests. Guess I would have to find out some examples elsewhere.</p>
<p>I only realize that my software design really sucks after getting involved in a real life development project and is currently doing a lot of readings to improve my design skill. So the main impact made to my personal project is that the project is currently on hold indefinitely until I feel that I am ready and want to practice what I have learnt these few weeks.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2008/05/28/real-life-enterprise-class-website-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working Life</title>
		<link>http://cslai.coolsilon.com/2008/05/04/working-life/</link>
		<comments>http://cslai.coolsilon.com/2008/05/04/working-life/#comments</comments>
		<pubDate>Sun, 04 May 2008 08:08:31 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=43</guid>
		<description><![CDATA[I didn&#8217;t realize that I have been working for 3 weeks until the Labour Day which was a public holiday. Many things happened in these few weeks and I am still struggling to catch up with it. My superior and colleagues have been very helpful and offered me some helpful tutorials and books. I was [...]]]></description>
			<content:encoded><![CDATA[<p>I didn&#8217;t realize that I have been working for 3 weeks until the Labour Day which was a public holiday. Many things happened in these few weeks and I am still struggling to catch up with it. My superior and colleagues have been very helpful and offered me some helpful tutorials and books. I was instructed to build a event scheduler application using <a href="http://codeigniter.com">codeigniter</a> in the first week and then work on a side project that extends a form using DOM methods and properties.</p>
<p><span id="more-43"></span></p>
<p>Developing the scheduler was not too difficult as I do not have to deal with browser experience inconsistencies very much and only concentrate on the business logic. However, when I started on my second project that extends a form to provide various widgets to guide users in filling the form correctly using <a href="http://developer.yahoo.com/yui/">YUI</a> I nearly killed myself due to frustration. I am developing my scripts in a Ubuntu Gutsy Gibbon 7.10 desktop and use firefox 3 beta 4 to test them. I finally managed to produce a workable prototype in a week that runs almost perfectly under firefox.</p>
<p>Nightmare comes when the same script is deployed to a windows machine with the major 4 browsers installed (firefox, safari, opera and internet explorer). All browsers except IE7 runs my script and the error message offered by IE7 has no meaning. The first problem encountered was with the select box creation through DOM. As suggested by a tutorial in <a href="http://www.w3schools.com/htmldom/met_select_add.asp">w3school</a>, I used the following code to create the selection box.</p>
<p><code class="javascript">var y=document.createElement('option');<br />
y.text='Kiwi'<br />
var x=document.getElementById("mySelect");<br />
try {<br />
    x.add(y,null); // standards compliant<br />
}<br />
catch(ex) {<br />
    x.add(y); // IE only<br />
}</code></p>
<p>Internet Explorer was not giving any helpful error message telling me which part is not right and I would have to use the following code to achieve the same thing.</p>
<p><code class="javascript">x.options.add(new Option(...))</code></p>
<p>The reference of the constructor parameters to instantiate an Option object can be found <a href="http://www.javascriptkit.com/jsref/select.shtml">here</a>.</p>
<p>There are a couple of other problems too but fortunately I managed to fixed it in time. Internet Explorer is very strict with DOM but the problem with it is that the error message it spits is often far from being helpful. How the hell can one find out what can possibly be the cause of a &#8220;random runtime error&#8221;?</p>
<p>Recently I started to learn how to code using VIM through <a href="http://cream.sf.net/">CREAM</a> and vimtutor. I am now in the progress of remembering the key commands and probably uninstall cream by the end of the week to fully switch to VIM. I used to code in a mini-emacs editor provided by swi-prolog when I was doing my prolog subject but I didn&#8217;t quite like it because I don&#8217;t have a very flexible fingers to press the modifier keys all the time. <img src='http://cslai.coolsilon.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2008/05/04/working-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What a WonderFOOL Life</title>
		<link>http://cslai.coolsilon.com/2008/04/02/what-a-wonderfool-life/</link>
		<comments>http://cslai.coolsilon.com/2008/04/02/what-a-wonderfool-life/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 04:26:05 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[April Fool]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Rick Roll]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/?p=41</guid>
		<description><![CDATA[I have just re-started to find myself a job as my work in mybloggercon almost come to an end (after helping them to set up an April Fool Prank). I have sent some enquiry letters to apply for a job in web-development field mostly involves PHP. I prefer PHP over ASP.NET because I can have [...]]]></description>
			<content:encoded><![CDATA[<p>I have just re-started to find myself a job as my work in <a href="http://www.mybloggercon.com/">mybloggercon</a> almost come to an end (after helping them to set up an April Fool Prank). I have sent some enquiry letters to apply for a job in web-development field mostly involves PHP. I prefer PHP over ASP.NET because I can have greater flexibilities in developing in PHP as what I experienced when I was developing my final year project.</p>
<p><span id="more-41"></span></p>
<p>I did not quite like ASP.NET when I took the course in Internet Programming. Probably the unit merely touches the surface of the power of ASP.NET but I still prefer PHP because every thing is not encapsulated. However, ASP.NET is great in the sense that it helps desktop application programmers to do web-development because the programmer can still double click on a control and then add in codes to model the behavior. Anyway, since I work in Gnome Environment most of the time, unless I install mono develop, I would not have a chance to do ASP.NET unless somehow I find myself a job for that.</p>
<p>This is also the reason why my new personal project will be written in PHP5 instead of ASP.NET. I have recently applied a free subversion hosting at <a href="http://unfuddle.com/">unfuddle</a> as my current web host does not offer subversion. The reason I start learning sub-version is because <a href="http://www.yongfook.com/post/view/267/10-dirty-little-web-development-tricks">in this post</a>, the author says,</p>
<blockquote><p>The n00b way of updating files on your web host would be to FTP in and drag and drop / delete stuff. Doing it like this will quickly get you into a mess with a large site with many files &#8211; there’s the potential to forget to upload certain files, accidentally overwriting things you shouldn’t etc. Some FTP apps have a “sync” button that tries to solve this, but I don’t trust them; you’re still overwriting files that you can never get back. That’s not a good policy to have with the valuable data on your production server.</p></blockquote>
<p>I quite agree with that as it happened when I was deploying my final year project online last year. Uploading the files online was one of the problems, and another one was to keep mine and Regina&#8217;s work in sync. We didn&#8217;t use revision control at the time because we thought we didn&#8217;t have enough time on learning it and it seems that we wasted more time in making sure we have the identical copy all the time.</p>
<p>However, I am still not being able to use subversion fully because my current web-host doesn&#8217;t allow me to use SSH. I will have to find a way later to deploy my personal project online.</p>
<h2>April FOOOOL~</h2>
<p>Anyway, yesterday was a wonderful day as you an find jokes everywhere. Recently a lot of people seems to love Mr. Rick Astley and his &#8220;<a href="http://youtube.com/watch?v=Yu_moia-oVI">Never Gonna Give You Up</a>&#8221; music video clip very much. I was told that <a href="http://www.youtube.com/">youtube</a> was linking all the featured videos to the music video clip yesterday (Rick Rolling). <a href="http://www.digg.com">Digg</a> on the other hand shows random mathematical symbols(some claimed each symbol represents a certain number of diggs) after a user diggs on the article.</p>
<p>My fellow bloggers were having fun as well as one of them claimed that their blog was being <a href="http://duller.kukuchew.com/archives/2826">sold</a> (in Chinese language) and there are also some saying that they have stopped blogging. As mentioned above, I helped mybloggercon to set up a <a href="http://mybloggercon.com/blog/movie-project/">joke</a> (in Chinese language) claiming that we are filming a movie. Then I further rick rolled the visitors without them knowing that the song actually means. Besides that, I have recently just finished posting my short story and made an announcement that the story will be published. Some friends like <a href="http://blog.reginabally.net/">Regina</a> actually took it seriously, anyway, I will make a hardcopy for her as she wanted earlier before she flies back to Sandakan.</p>
<p>Hopefully I can get employed by the end of the month. <img src='http://cslai.coolsilon.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2008/04/02/what-a-wonderfool-life/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MVC : Me vs. CodeIgniter</title>
		<link>http://cslai.coolsilon.com/2008/03/19/mvc-me-vs-codeigniter/</link>
		<comments>http://cslai.coolsilon.com/2008/03/19/mvc-me-vs-codeigniter/#comments</comments>
		<pubDate>Wed, 19 Mar 2008 10:48:39 +0000</pubDate>
		<dc:creator>Jeffrey04</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Code Igniter]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://cslai.coolsilon.com/2008/03/19/mvc-me-vs-codeigniter/</guid>
		<description><![CDATA[Background While my static pages and site theme is still under construction, I went to CodeIgniter.com to see how to work with it and played the tutorial screencasts. The reason behind in considering CodeIgniter (CI) to be used in my next project is because I don&#8217;t feel like re-inventing the wheel. However to port my [...]]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>While my static pages and site theme is still under construction, I went to <a href="http://CodeIgniter.com">CodeIgniter.com</a> to see how to work with it and played the tutorial screencasts. The reason behind in considering CodeIgniter (CI) to be used in my next project is because I don&#8217;t feel like re-inventing the wheel. However to port my current project to use CI may cause some problems as there are differences in how we implement MVC structure.</p>
<p><span id="more-4"></span></p>
<h2>Model-View-Controller Architecture</h2>
<p>Quoted from <a href="http://java.sun.com/blueprints/patterns/MVC-detailed.html">Java BluePrints</a> :</p>
<blockquote>
<dl>
<dt>Model</dt>
<dd>The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.</dd>
<dt>View</dt>
<dd>The view renders the contents of a model. It accesses enterprise data through the model and specifies how that data should be presented. It is the view&#8217;s responsibility to maintain consistency in its presentation when the model changes. This can be achieved by using a push model, where the view registers itself with the model for change notifications, or a pull model, where the view is responsible for calling the model when it needs to retrieve the most current data.</dd>
<dt>Controller</dt>
<dd>The controller translates interactions with the view into actions to be performed by the model. In a stand-alone GUI client, user interactions could be button clicks or menu selections, whereas in a Web application, they appear as GET and POST HTTP requests. The actions performed by the model include activating business processes or changing the state of the model. Based on the user interactions and the outcome of the model actions, the controller responds by selecting an appropriate view.</dd>
</dl>
</blockquote>
<p>Note: You may have to view the following page with the source view as I am still looking for a good syntax highlighting plugin for my wordpress installation.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://cslai.coolsilon.com/2008/03/19/mvc-me-vs-codeigniter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

