Learning from the CakePHP source code - Part II
这段评论有意思: 非常正确,确实应该从代码入手!
Hey Felix!
As you wrote in Part I most of Cake's core code is "delightful and should help you to become a better programmer" and that's what makes it so easy to read. I think what you did in this post was mainly "translating sourcecode into prose"... Well, what I want to say: I just think that any programmer who is really willing to learn more about the core is also able to directly read through some lines of code and understand them without additional explanation.
All I want to suggest is just don't waste your time with discribing sections of code but tell us more about all that powerful, hidden stuff, e.g. how to use the class registry and stuff like that! I know you're - compared to most of us - damn familiar with the core so I'm really curious to learn more about the might & magic of Cake's core!
Hey, but maybe that's exactly what you wanted to do in Part III, so I'm already looking forward to it!
------------------------------------------------------------------------------------------------------
Sorry this post took me a while. The last couple days have been sort of busy and a lot of things on my lists didn't get done. Anyway, I'll continue right where I stopped, with the Dispatcher:
The heart of CakePHP - The Dispatcher
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.
- Build the $params array. The first thing the Dispatcher::dispatch() function does is to perform an array_merge between $this->parseParams($url) and $additionalParams. Dispatcher::parseParams() is quite interesting as well. The first thing it does is to create a new Instance of the Router and call Router::parse($from_url). This returns an array with fields like 'controller', 'action', etc.. After that all variables from $_GET, $_POST and $_FILE are being merged into the $params array as well and finally returned to the Dispatcher function.
- Find the base url: The next thing Dispatcher::dispatch() does, is to find the base url, that all controller actions, routes, etc. happen within. This url is then assigned to $this->base. All the base url retrieving logic is implemented in Dispatcher::baseUrl().
- Load/Include the requested Controller: From now on I'll focus on the most important things going on because it would be insane to go into every little detail. The next block of code basically sees if $params['controller'] is emtpy, and if yes object::cakeError() is invoked to show the 'missingController' page all of us know. If the controller field is not empty, the first thing CakePHP tries to do is to load this controller (via loadController) from within /app/controllers. If that fails, CakePHP looks if there is a plugin with the name of $params['controller'] (via loadPluginController), and if not, missingController is invoked as well.
- Possible Plugin Logic: In case there was a plugin found, the next thing that happens is some plugin logic that does not get executed for normal Controller requests. It's basically some $params shifting magic (Dispatcher::_restructureParams()), and most notably the point where loadPluginModels() get's executed.
- Executing the Admin Route: If you have CAKE_ADMIN defined in your /app/config/core.php, then this is the point where the 'admin_' prefix (or whatever CAKE_ADMIN is set to) is added to the $params['action'] parameter. And here you also have a check that protects CAKE_ADMIN routes as private actions. This basically means if somebody would call /posts/admin_index instead of /admin/posts/index he wouldn't get very far.
- Render a possible missingController error: If at some point in the code above $missingController was set to true, this is the point where $this->cakeError('missingController', ...) is invoked. If not, $controller is being assigned a new instance of our $ctrlClass.
- Action exists? Action private?: The next couple of lines are dedicated to perform some checks on the $params['action'] parameter. The following things happen in the order I mention them: If $params['action'] is empty, it is set to 'index' instead. If the Controller has an action with the name $params['action'] but it starts with '_', $privateAction is set to true. If the Controller does not have an action $params['action'], or it happens to be named: 'beforeFilter', 'beforeRender' or 'afterFilter', $missingAction is set true.
- Set Controller variables: Now it's time for all of the Controller variables to be set with interesting information. This includes the 'autoRender', 'base', 'here', 'webroot', 'params', 'action', 'data', 'passedArgs', 'autoLayout', 'webservices' and 'plugin'.
- Load Components & Models: The Dispatcher now calls $controller->_initComponents() which attaches all components as references to the Controller object, but does not yet call their startup() function. After that, the same thing happens with Models when calling $controller->constructClasses().
- Render possible missingAction/privateActione errors: If there had been a missingAction or privateAction error before, this is the point where $this->cakeError() get's called to render those.
- Invoke the controller: The last call in Dispatcher::dispatch() goes to Dispatcher::_invoke(), but since it's still the same operation we are doing, I'll continue writing about things like before. The _invoke function directly executes Dispatcher::start(), which does the following things: If Controller::beforeFilter is a string/array, call the/all function(s) in this string/array (Warning: This is depracted!). Afterwards Controller::beforeFilter() get's executed without further checking. And the last thing happening in Dispatcher::start() is that all component's startup() functions get called. So back in Dispatcher::_invoke() there comes a check whether we are scaffolding or not, and if no, our Controller action get's called via call_user_func_array. Then, if $controller->autoRender is set to true, $controller->render() is called, and finally the afterFilter get's executed. Depending on whether there was some rendering going on or not either the raw output or the action's return value are getting returned to Dispatcher::dispatch() which directly returns this value back to the point where the initial call came from.
That's it, you've just witnessed the miracle of birth ... er dispatching. I've skipped some minor things here and there, but in general this together with Part I should be a good guide to the things happening before all your wonderful application code kicks in. Of course, there is a lot more like all the Model and View stuff. But talking about all of this would take for ever, bore you to death and would only be useful to very few of us. However, if you guys would be interested in it, I would post a Part III where I would just do some pointing at classes and code snippets a CakePHP user should have read to get a better understanding of the things going on in the background.
Oh, and today is probably also going to be the day I'll buy myself some yummy Cake ... : /. I'm not sure if I'll be able to take the picture and everything today, but I'll try my best. Hmm ... after that I should probably close this blog since nobody is going to hire me in the field of web development any more and I'll have to look for a new area to work in : /.
Learning from the CakePHP source code - Part II的更多相关文章
- Learning from the CakePHP source code - Part I
最近开始痛定思痛,研究cakephp的源码. 成长的路上从来没有捷径,没有小聪明. 只有傻傻的努力,你才能听到到成长的声音. 下面这篇文章虽然过时了,但是还是可以看到作者的精神,仿佛与作者隔着时空的交 ...
- Learning English From Android Source Code:1
英语在软件行业的重要作用不言自明,尤其是做国际项目和写国际软件,好的英语表达是项目顺利进行的必要条件.纵观眼下的IT行业.可以流利的与国外客户英文口语交流的程序猿占比并非非常高.要想去国际接轨,语言这 ...
- Learning English From Android Source Code:2 Ampersand
这一次想把标点符号的英语表达总结一下,这些单词非常重要但easy被我们忽视.以我的经验,还是多认识几个.以备不时之需. 以下从"标点符号"開始: punctuation [英][ˌ ...
- Classic Source Code Collected
收藏一些经典的源码,持续更新!!! 1.深度学习框架(Deep Learning Framework). A:Caffe (Convolutional Architecture for Fast Fe ...
- CRC32 Source Code
/* The Quest Operating System * Copyright (C) 2005-2010 Richard West, Boston University * * This pro ...
- attack source code
不废话,直接上代码, 先看截图use pictures;
- Tree - AdaBoost with sklearn source code
In the previous post we addressed some issue of decision tree, including instability, lack of smooth ...
- Tree - Decision Tree with sklearn source code
After talking about Information theory, now let's come to one of its application - Decision Tree! No ...
- Tree - Gradient Boosting Machine with sklearn source code
This is the second post in Boosting algorithm. In the previous post, we go through the earliest Boos ...
随机推荐
- kivy create a package for Android
Now that you've successfully coded an app. Now you want to deploy it to Android. So now we would nee ...
- svn的使用详细说明
转载请指明:杨凯专属频道 1.在电脑的任意位置创建一个版本库文件夹 最好是全英文的目录 例如 在c:\svn下面创建一个 2.打开此文件,在这里右键 找--TortoiseSVN--->Crea ...
- Python pandas 0.19.1 Intro to Data Structures 数据结构介绍 文档翻译
官方文档链接http://pandas.pydata.org/pandas-docs/stable/dsintro.html 数据结构介绍 我们将以一个快速的.非全面的pandas的基础数据结构概述来 ...
- cpu组相连映射
组相联映射方式 组相联映射方式 是全相联映射方式和直接相联映射方式的结合,结合两者的优点 · 方法:把Cache分为若干组,每组含有若干行. 组间直接映射,组内全相联映射. (图7) · 映射过程:( ...
- .Net程序员学用Oracle系列(2):准备测试环境
<.Net程序员学用Oracle系列:导航目录> 本文大纲 1.创建说明 1.1.为什么要创建的测试环境? 1.2.了解 Oracle 实例的默认用户 2.创建环境 2.1.创建基本环境 ...
- NSClassFromString,NSSelectorFromString,isKingOfClass
1. NSClassFromString 这个方法判断类是否存在,如果存在就动态加载的,不存为就返回一个空对象; id myObj = [[NSClassFromString(@"MySpe ...
- springMVC框架中json处理
1.在项目中导入jackson-core.jar包 2.使用@ResponseBody注解,此注解会自动装换为json 如图: 3.如此,便可以得到json对象
- The Linux Mint 17.1:Eclipse Run The C++ And Python Configoration
p { margin-bottom: 0.1in; line-height: 120% } # Copyright (c) 2016, 付刘伟 (Liuwei Fu)# All rights rese ...
- oracle——用户
新增用户 用system用户登录 CREATE USER TEST1 IDENTIFIED BY TEST1; CREATE USER:创建用户命令,后跟用户名: IDENTIFIED BY:后跟密码 ...
- PostgreSQL 序列使用
数据库中主键的生成一般是通过序列来生成,PG的序列知识主要罗列如下: 如何找到序列的名称:用pgadmin打开当前所用数据库,在schemas->sequences下找到相关的序列,然后SELE ...