<?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>cakebaker &#187; php</title>
	<atom:link href="http://cakebaker.42dh.com/tags/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Tue, 20 Dec 2011 15:29:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Accepting the Google OpenID with PHP OpenID</title>
		<link>http://cakebaker.42dh.com/2009/12/31/accepting-the-google-openid-with-php-openid/</link>
		<comments>http://cakebaker.42dh.com/2009/12/31/accepting-the-google-openid-with-php-openid/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 16:45:04 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1322</guid>
		<description><![CDATA[If you are using the PHP OpenID library (which is also used by my OpenID component for CakePHP), it is possible that you get an &#8220;Invalid OpenID&#8221; error when you try to login with the Google OpenID (https://www.google.com/accounts/o8/id), or any other OpenID that uses &#8220;https&#8221;. In this case, the following steps might help to fix [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using the <a href="http://openidenabled.com/php-openid/">PHP OpenID library</a> (which is also used by my <a href="http://code.42dh.com/openid/">OpenID component</a> for CakePHP), it is possible that you get an &#8220;Invalid OpenID&#8221; error when you try to login with the Google OpenID (https://www.google.com/accounts/o8/id), or any other OpenID that uses &#8220;https&#8221;.</p>
<p>In this case, the following steps might help to fix this issue:</p>
<ul>
<li>Ensure you have Curl and OpenSSL installed</li>
<li>Enable the Curl and OpenSSL extensions in your php.ini (on Archlinux this file is found in /etc/php/):
<pre>
<code>extension=curl.so
extension=openssl.so</code>
</pre>
</li>
<li>Restart your web server</li>
</ul>
<p>Now the error message should disappear and you should be able to log in with the Google OpenID. </p>
<p>&#8212;-</p>
<p>That&#8217;s it for 2009. It was a rather lazy year on this blog from my side (I didn&#8217;t even manage to do a redesign&#8230;), and so I hope I will be a bit less lazy with writing on this blog in 2010.</p>
<p>Anyway, thank you for reading this blog, and for all your comments and emails. A Happy New Year everyone &#038; cu in 2010 :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/12/31/accepting-the-google-openid-with-php-openid/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Auto-loading vendor files (or any other file)</title>
		<link>http://cakebaker.42dh.com/2008/11/28/auto-loading-vendor-files-or-any-other-file/</link>
		<comments>http://cakebaker.42dh.com/2008/11/28/auto-loading-vendor-files-or-any-other-file/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 16:47:47 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[vendor]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=979</guid>
		<description><![CDATA[If you use classes which do not fit into CakePHP&#8217;s structure (i.e. they are no components, helpers, etc.), you have to import those classes manually with App::import(&#8216;Vendor&#8217;, &#8216;ClassName&#8217;), at least if your classes are in the &#8220;vendors&#8221; folder. This means, every time you want to use such a class, you first have to import it [...]]]></description>
			<content:encoded><![CDATA[<p>If you use classes which do not fit into CakePHP&#8217;s structure (i.e. they are no components, helpers, etc.), you have to import those classes manually with App::import(&#8216;Vendor&#8217;, &#8216;ClassName&#8217;), at least if your classes are in the &#8220;vendors&#8221; folder. This means, every time you want to use such a class, you first have to import it before you can use it. And that&#8217;s a bit of a pain ;-)</p>
<p>Fortunately, PHP5 provides a solution for this &#8220;problem&#8221;: auto-loading. The explanation from the <a href="http://www.php.net/manual/en/language.oop5.autoload.php">manual</a>: &#8220;You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn&#8217;t been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.&#8221;</p>
<p>In CakePHP a good place for this function is app/config/bootstrap.php. The function to auto-load vendor files looks like:</p>
<pre>
<code>function __autoload($className) {
    App::import('Vendor', $className);
}</code>
</pre>
<p>If you want to use a custom function or a method of a class, you simply have to register your auto-load implementation. The example from above realized with a static method looks like:</p>
<pre>
<code>class AutoLoader {
    public static function load($className) {
        App::import('Vendor', $className);
    }
}

spl_autoload_register(array('AutoLoader', 'load'));</code>
</pre>
<p>You can find more information about auto-loading in the PHP manual: <a href="http://www.php.net/manual/en/language.oop5.autoload.php">Autoloading objects</a> and <a href="http://www.php.net/manual/en/function.spl-autoload-register.php">spl_autoload_register</a>.</p>
<p>Happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/11/28/auto-loading-vendor-files-or-any-other-file/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Grouping of constants</title>
		<link>http://cakebaker.42dh.com/2008/10/09/grouping-of-constants/</link>
		<comments>http://cakebaker.42dh.com/2008/10/09/grouping-of-constants/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 17:10:46 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=882</guid>
		<description><![CDATA[Almost every application uses some constants, and sometimes you have groups of related constants. And so the question arises: &#8220;How can I group those constants?&#8221;. The easiest way is to use a prefix as shown in the following example: define('OAUTH_REQUEST', 'http://oauth.net/core/1.0/endpoint/request'); define('OAUTH_AUTHORIZE', 'http://oauth.net/core/1.0/endpoint/authorize'); define('OAUTH_ACCESS', 'http://oauth.net/core/1.0/endpoint/access'); These constants build the (implicit) group &#8220;OAUTH&#8221;. With the old [...]]]></description>
			<content:encoded><![CDATA[<p>Almost every application uses some constants, and sometimes you have groups of related constants. And so the question arises: &#8220;How can I group those constants?&#8221;. The easiest way is to use a prefix as shown in the following example:</p>
<pre>
<code>define('OAUTH_REQUEST', 'http://oauth.net/core/1.0/endpoint/request');
define('OAUTH_AUTHORIZE', 'http://oauth.net/core/1.0/endpoint/authorize');
define('OAUTH_ACCESS', 'http://oauth.net/core/1.0/endpoint/access');</code>
</pre>
<p>These constants build the (implicit) group &#8220;OAUTH&#8221;. With the old PHP 4 that&#8217;s all you can do, with PHP 5 it is also possible to create explicit groups by using class constants. So we can refactor the example from above to:</p>
<pre>
<code>class OauthConstants {
    const REQUEST = 'http://oauth.net/core/1.0/endpoint/request';
    const AUTHORIZE = 'http://oauth.net/core/1.0/endpoint/authorize';
    const ACCESS = 'http://oauth.net/core/1.0/endpoint/access';
}</code>
</pre>
<p>The group name is now the name of the class, and we can access those constants with ClassName::CONSTANT_NAME (e.g. OauthConstants::REQUEST). </p>
<p>Even though this approach is a bit limited (for example, you can&#8217;t use string concatenation, see also <a href="http://ch.php.net/manual/en/language.oop5.constants.php">Class Constants</a>) and there is no convention on where to place such classes in CakePHP, it is a handy way to organize your constants. </p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/10/09/grouping-of-constants/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Regular expression to check for content between tags</title>
		<link>http://cakebaker.42dh.com/2007/09/10/regular-expression-to-check-for-content-between-tags/</link>
		<comments>http://cakebaker.42dh.com/2007/09/10/regular-expression-to-check-for-content-between-tags/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 15:23:16 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[regular expression]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2007/09/10/regular-expression-to-check-for-content-between-tags/</guid>
		<description><![CDATA[Regular expressions are something I often struggle with. I can usually draw the state machine which represents the regular expression, but to translate it to a regular expression is sometimes a hard task. Today I wanted to write a regular expression to check whether a certain tag is between the head tags of a HTML [...]]]></description>
			<content:encoded><![CDATA[<p>Regular expressions are something I often struggle with. I can usually draw the <a href="http://en.wikipedia.org/wiki/Finite_state_machine">state machine</a> which represents the regular expression, but to translate it to a regular expression is sometimes a hard task. </p>
<p>Today I wanted to write a regular expression to check whether a certain tag is between the head tags of a HTML document. The regular expression itself was not difficult, but as I forgot the <a href="http://ch2.php.net/manual/en/reference.pcre.pattern.modifiers.php">s modifier</a> it took quite a while to make it work&#8230;</p>
<p>Anyway, here is the pattern:</p>
<pre>
$this-&gt;assertPattern('#&lt;head&gt;(.)*&lt;link rel="xy" href="some_url" /&gt;(.)*&lt;/head&gt;#s', $html);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2007/09/10/regular-expression-to-check-for-content-between-tags/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How to use Selenium with SimpleTest</title>
		<link>http://cakebaker.42dh.com/2006/11/16/how-to-use-selenium-with-simpletest/</link>
		<comments>http://cakebaker.42dh.com/2006/11/16/how-to-use-selenium-with-simpletest/#comments</comments>
		<pubDate>Thu, 16 Nov 2006 09:39:52 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[simpletest]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2006/11/16/how-to-use-selenium-with-simpletest/</guid>
		<description><![CDATA[Up to now there was no PHP support for Selenium Remote Control, i.e. you couldn&#8217;t integrate your Selenium tests with a testing framework like SimpleTest. On PEAR there is now a package called Testing_Selenium which makes it easy to use PHP and Selenium Remote Control together. To use them you need PHP5 and a JRE [...]]]></description>
			<content:encoded><![CDATA[<p>Up to now there was no PHP support for <a href="http://www.openqa.org/selenium-rc/">Selenium Remote Control</a>, i.e. you couldn&#8217;t integrate your Selenium tests with a testing framework like <a href="http://www.lastcraft.com/simple_test.php">SimpleTest</a>. On PEAR there is now a package called <a href="http://pear.php.net/package/Testing_Selenium">Testing_Selenium</a> which makes it easy to use PHP and Selenium Remote Control together. To use them you need PHP5 and a JRE (Java Runtime Environment) version 1.5 or higher. The installation itself is simple. Here the installation instructions for CakePHP:</p>
<ul>
<li><a href="http://pear.php.net/package/Testing_Selenium/download">Download</a> the package</li>
<li>Put Selenium.php to your &#8220;vendors&#8221; folder</li>
<li>Create a folder &#8220;Testing&#8221; in your &#8220;vendors&#8221; folder</li>
<li>Put the &#8220;Selenium&#8221; folder from the archive to the &#8220;Testing&#8221; folder</li>
<li>Put selenium-server.jar to a folder of your choice</li>
</ul>
<p>Ok, as the installation is done, let&#8217;s write a simple testcase. We want to verify that the title of the cake website is correct.</p>
<pre>
vendor('Selenium');

class SeleniumTest extends UnitTestCase
{
    function setUp()
    {
        $this-&gt;selenium = new Testing_Selenium("*firefox /usr/lib/firefox/firefox-bin", "http://cakephp.org");
        $result = $this-&gt;selenium-&gt;start();
    }

    function tearDown()
    {
        $this-&gt;selenium-&gt;stop();
    }

    function testCakePHPTitle()
    {
        $this-&gt;selenium-&gt;open("/");
        $this-&gt;assertEqual('CakePHP : the rapid development php framework', $this-&gt;selenium-&gt;getTitle());
    }
}
</pre>
<p>What does this do? In the setUp() function we start a Firefox browser (we could also use a different browser). With that browser we open in the test function the cake homepage and get the page title. And in tearDown() we close the browser.</p>
<p>Before we can run this test, we have to start the Selenium server with:</p>
<pre>
java -jar selenium-server.jar
</pre>
<p>Now, we should get a green bar when we run the test. </p>
<p>Happy testing :)</p>
<p>Update (2006-11-29): If you don&#8217;t want to put the exception class to the vendors folder, you can replace in Selenium.php </p>
<pre>
require_once 'Testing/Selenium/Exception.php';
</pre>
<p>with</p>
<pre>
class Testing_Selenium_Exception extends Exception {}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/11/16/how-to-use-selenium-with-simpletest/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t rely on side effects in your code</title>
		<link>http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/</link>
		<comments>http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/#comments</comments>
		<pubDate>Tue, 07 Nov 2006 16:39:57 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/</guid>
		<description><![CDATA[This post is inspired by a bug I encountered today. As I think it is an instructive bug, I will do a little code review of the relevant parts. Ok, let&#8217;s dive into the code. First a bit of context: // snippet from View::_render() $loadedHelpers = $this-&#62;_loadHelpers($loadedHelpers, $this-&#62;helpers); foreach(array_keys($loadedHelpers) as $helper) { As we move [...]]]></description>
			<content:encoded><![CDATA[<p>This post is inspired by a bug I encountered today. As I think it is an instructive bug, I will do a little code review of the relevant parts. </p>
<p>Ok, let&#8217;s dive into the code. First a bit of context:</p>
<pre>
// snippet from View::_render()
$loadedHelpers = $this-&gt;_loadHelpers($loadedHelpers, $this-&gt;helpers);

foreach(array_keys($loadedHelpers) as $helper) {
</pre>
<p>As we move to the View::_loadHelpers() function, we detect the following statement: </p>
<pre>
return $this-&gt;cakeError('missingHelperFile', array(array(
    'helper' =&gt; $helper,
    'file' =&gt; Inflector::underscore($helper) . '.php',
    'base' =&gt; $this-&gt;base
)));
</pre>
<p>That is a bit weird, as the statement returns an error, but there was no error handling in the previous code snippet. But maybe the cakeError function just returns an empty array, who knows. So let&#8217;s have a look at the cakeError function defined in the Object class:</p>
<pre>
function cakeError($method, $messages) {
    ...
    if (class_exists('AppError')) {
        $error = new AppError($method, $messages);
    } else {
        $error = new ErrorHandler($method, $messages);
    }
    return $error;
}
</pre>
<p>No, the function doesn&#8217;t return an array. Hm. As this function returns an object, and the first snippet expects an array, then there should be some PHP errors when displaying a &#8220;missing helper file&#8221; error. But there are no PHP errors. We find the answer in the ErrorHandler class: it just shows the error message and calls &#8220;exit&#8221; to stop the script execution. And so the returns are never called&#8230;</p>
<p>Well, this solution would work fine as long as it is only used internally (even though it is not very elegant). But the framework allows you to write a custom error handler, and so if you want to handle a &#8220;missing helper file&#8221; error yourself, you get PHP errors when you don&#8217;t use an exit. </p>
<p>That&#8217;s it. I hope you learned something from this example :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Redirecting&#8221; database calls</title>
		<link>http://cakebaker.42dh.com/2006/11/02/redirecting-database-calls/</link>
		<comments>http://cakebaker.42dh.com/2006/11/02/redirecting-database-calls/#comments</comments>
		<pubDate>Thu, 02 Nov 2006 17:54:44 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2006/11/02/redirecting-database-calls/</guid>
		<description><![CDATA[For the test suite I wanted to &#8220;redirect&#8221; all database calls to the test database. But how to do that without touching the application code? Well, I could solve it with a little hack. I dynamically add a constructor to the code of database.php and execute that code with the eval function: $config = file_get_contents(CONFIGS.'database.php'); [...]]]></description>
			<content:encoded><![CDATA[<p>For the test suite I wanted to &#8220;redirect&#8221; all database calls to the test database. But how to do that without touching the application code? Well, I could solve it with a little hack. I dynamically add a constructor to the code of database.php and execute that code with the eval function:</p>
<pre>
$config = file_get_contents(CONFIGS.'database.php');
$config = str_replace('&lt;?php', '', $config);
$config = str_replace('?&gt;', '', $config);
$config = str_replace('}', 'function __construct() {$this-&gt;default = $this-&gt;test;}}', $config);
eval($config);
</pre>
<p>It is not very elegant, but it does the job ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/11/02/redirecting-database-calls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EasyEclipse</title>
		<link>http://cakebaker.42dh.com/2006/06/28/easyeclipse/</link>
		<comments>http://cakebaker.42dh.com/2006/06/28/easyeclipse/#comments</comments>
		<pubDate>Wed, 28 Jun 2006 15:28:32 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpeclipse]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.cakebaker.42dh.com/?p=216</guid>
		<description><![CDATA[A project I wish I had detected earlier: EasyEclipse. What is EasyEclipse? From their website: EasyEclipse packages together Eclipse, the open-source software development platform, and selected open source plugins. They provide packages for Java, PHP, Ruby on Rails, and Python. Just download the desired package, unpack it, and start programming ;-)]]></description>
			<content:encoded><![CDATA[<p>A project I wish I had detected earlier: <a href="http://www.easyeclipse.org">EasyEclipse</a>. What is EasyEclipse? From their website:</p>
<blockquote><p>
EasyEclipse packages together Eclipse, the open-source software development platform, and selected open source plugins.
</p></blockquote>
<p>They provide packages for Java, PHP, Ruby on Rails, and Python. Just download the desired package, unpack it, and start programming ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/06/28/easyeclipse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Run PHP5 in PHP4 mode</title>
		<link>http://cakebaker.42dh.com/2006/04/03/run-php5-in-php4-mode/</link>
		<comments>http://cakebaker.42dh.com/2006/04/03/run-php5-in-php4-mode/#comments</comments>
		<pubDate>Mon, 03 Apr 2006 14:28:11 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://www.cakebaker.42dh.com/?p=156</guid>
		<description><![CDATA[Today, I had to track down a bug in my application which only occured with PHP4. The problem was that I use PHP5 and I couldn&#8217;t reproduce the bug with PHP5. So I needed PHP4 on my machine. I installed php4-cgi, but for some reason I was not able to configure it correctly (I am [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I had to track down a bug in my application which only occured with PHP4. The problem was that I use PHP5 and I couldn&#8217;t reproduce the bug with PHP5. So I needed PHP4 on my machine. I installed php4-cgi, but for some reason I was not able to configure it correctly (I am not an Apache guru *g*). After more searching I found a hint of a special property in php.ini with which it is possible to run PHP5 in PHP4 mode. That property is:</p>
<pre>
zend.ze1_compatibility_mode
</pre>
<p>After enabling this property, I was able to reproduce the bug.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/04/03/run-php5-in-php4-mode/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Comparison of ten PHP frameworks</title>
		<link>http://cakebaker.42dh.com/2006/03/20/comparison-of-ten-php-frameworks/</link>
		<comments>http://cakebaker.42dh.com/2006/03/20/comparison-of-ten-php-frameworks/#comments</comments>
		<pubDate>Mon, 20 Mar 2006 16:01:46 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.cakebaker.42dh.com/?p=147</guid>
		<description><![CDATA[Dennis Pallett compares in an article ten popular PHP frameworks. He writes about CakePHP: CakePHP is mostly an advanced MVC framework, with a few extra modules added on top. It can handle most of the database stuff for you, and it includes support for Ajax and data validation. It also has a unique user authentication [...]]]></description>
			<content:encoded><![CDATA[<p>Dennis Pallett compares in an <a href="http://www.phpit.net/article/ten-different-php-frameworks/">article</a> ten popular PHP frameworks. He writes about CakePHP:</p>
<blockquote><p>
CakePHP is mostly an advanced MVC framework, with a few extra modules added on top. It can handle most of the database stuff for you, and it includes support for Ajax and data validation. It also has a unique user authentication module called &#8216;Access Lists&#8217;, which can be used to give different users access to different parts of your CakePHP website.</p>
<p>This framework seems quite thorough and ready for use, although the CakePHP website is extremely confusing. There doesn&#8217;t seem to be a stable version yet, which is a bit surprising since it&#8217;s been in development for months now, but I guess it&#8217;s probably possible to use the beta version on a production website as well.
</p></blockquote>
<p>[via <a href="http://blog.samdevore.com/archives/2006/03/20/phpitnet-taking-a-look-at-ten-different-php-frameworks/">Sam's random musings</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/03/20/comparison-of-ten-php-frameworks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

