Learning from the CakePHP source code - Part I
Posted on 25/9/06 by Felix Geisendörfer
Deprecated post
The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.
Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.
Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).
I originally wanted to write a complete guide to studying the CakePHP source code today, but this 2 hours monster of a post got into the way. So therefor I decided to split it up in two (or maybe more) parts.
Why study the code if it just works?
If you are already convinced you want to learn more about the CakePHP core just skip this section, if not keep reading.
When hanging out in #cakephp I usally try to answer questions people have as good as I can. A lot of the times I have no idea what the answer is and in most cases the fastest way to find out is by looking at the core code. Ok, the manual is pretty decent these days and I would recommend most people to look for an answer in there first. But if you take the time to study the core code, you'll be able to answer almost any question by yourself, no matter if it has been answered somewhere before. Another big advantage is that you can start to enjoy some of the useful & undocumented functionality hidden in the core files most people don't know about. Very few of you will know that there is a Configure Singleton class that you can use to share & manipulate variable values or other information throughout all parts of you application or that you can use the ClassRegistry to register objects you want to be globally accessible. Ok a lot of those things you'll never need or shouold be treated carefully in order to not break the MVC pattern, but hey some of this stuff is damn useful. But the main advantage you should keep in mind, is that you cannot write a really big & good application if you lack the understanding how the framework behind it works. You might open your app to security issues because you are not fully aware of what requestAction does, or because you simply thought CakePHP would automatically sanitize a certain value for you. So knowing the framework will help you to write better apps.
But not only that, one of my favourite parts about reading the framework, was learning how to write easy to read and effective php code. Ok, some parts are rather cryptic and not easy to decipher, but most of them are delightful and should help you to become a better programmer. Oh and also make sure to check out the coding standards used for CakePHP. Even so at some point they broke up with the braces style recommend in there (I liked the old one better), it should help you to read the code and to write better code yourself.
But alright, let's make our first steps in the beautiful code of CakePHP:
First things first, /app/webroot/index.php
The first file you should check out is the one that actually get's called first when a CakePHP site is being requested. It's the /app/webroot/index.php file and it's main purpose is to define the most important path's of the folder layout, you can find some information about that in the manual. After that the $_GET['url'] value is used to invoke the Dispatcher class (/cake/dispatcher.php). There is also a little if statement checking if this value is 'favicon.ico' which can be used to bootstrap CakePHP without invoking a Dispatcher request, which is handy if you want to use CakePHP with an existing CMS like drupal or wordpress. The last thing happening in here is always a check if DEBUG is > 0, and if so, the execution time of this request is added as a hidden html comment to the source of your site.
The heart of CakePHP - The Dispatcher
Alright, you might have heard of this class before as it is the most important part of CakePHP. If it wasn't for the Dispatcher, none of your sites would ever render. It is the responsibility of the Dispatcher, together with the Router (/cake/libs/router.php) to turn your '/posts/index'-like requests into action. Action in this case means to figure out what Controller to use, setting this controller up (loading Models, Components, etc.), invoking possible error pages and handling a couple other things you don't even know about existing ; ).
As I'm running out of time for today, most of the Dispatcher functionality will be covered in Part II. For now I just want to tell you how to use the Disaptcher from any part your application.
But First of all: in most situations Object/Controller::requestAction() will be what you should use when trying to call another action inside one of your Controllers. However, there are situations where you want a little bit more control and use the Dispatcher directly. In those cases you create an instance of the Dispatcher and call the Dispatcher::dispatch() function like this:
$Dispatcher->dispatch('/posts/index');
This will have the same effect as calling /posts/index via your browser and output the view directly where you place this call. So if you call the Dispatcher like this from within another action you'll probably see two pages being returned instead of one, causing ugly results. If you use the Dispatcher like this, in most case you will want to call ob_start() before and ob_get_clean() afterwards to tunnel the output into a variable, rather then directly echo'ing it out.
Another neat feature of the Dispatcher::dispatch() function is that you can set a 2nd parameter called $additionalParams ($extra for requestAction), where you can set things like the layout, form/url data or any other information you want to make available via $this->params in the invoked Controller.
Ok, more good stuff will be coming tomorrow and if you have any questions so far, feel free to ask. Oh and while reading this "Learning from the CakePHP source code"-series, please keep one thing in mind: 99% of what I know about the core code comes from my own efforts of reading and playing around with it. I might be sometimes wrong about the exact interpreation or best use of a function/class/whatever, so if you know more then I do (maybe because you are a dev ^^), please let me know so I can correct errors easily.
--Felix Geisendörfer aka the_undefined
You can skip to the end and add a comment.
Hi Felix,
I am surprised that there are still no comments for this post :).
I think that all cake users can learn something from looking at the code as I put in one of my own posts a while ago. However, I don't think that the dispatcher is the place to be looking. The example you have given of when the dispatcher could be called directly, could easily be achieved by using requestAction (as I put in my comment for the printing post). I would go as far as to say that calling the dispatcher directly is a bad idea - I am curious if I am the only person thinking this.
It can never cause a problem to know how something works, but there are some things that should be looked into only after it is undersood how it fits in 'the big picture'.
Anyway, these are just my thoughts, and it doesn't mean I don't appreciate the time you have put into creating your 'learning from the source' series.
cheers,
AD7six
AD7six: I read your comment on the PrintController, I'll test it out at some point soon.
But anyway, I think knowing how to call the Dispatcher yourself isn't something you'll need nor something you should use very often. But especially when working on smooth transition with legacy apps or other more advanced Cake installs, this can certainly be of help. For everything else, requestAction is the way to go.
[...] So far I found only two pages with “Rails-quality” documentation: Learning from the CakePHP source code - Part I and Part II. [...]
Sweet. Exactly what I was looking for.
Tyler: Careful, some things from this article might be outdated.
[...] - thinkingphp, bagian 1 & bagian 2 [...]
Thanks. It is outdated
Thanks..
But why is it deprecated? Is there any other solution to do the same thing?
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.
[...] In the previous post I was showing how to use the Dispatcher::dispatch() function. Now what’s more interesting, is what it actually does and in what order. [...]