• Main navigation
登入區塊
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站資訊區塊
站務管理者

kiang
 

tokimeki
 

sam0228
 

morris
 

shiang
 

SoltyRain
 

廣告
   查看所有文章 (qq71151461)




Cakephp执行详细流程
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
加载基本文件
cake/basics.php 里面定义了常用的方法以及时间常量
$TIME_START = getMicrotime(); 记录开始执行时间
cake/config/paths.php 里面定义一些基本路径
cake/lib/object.php cake的基本类
cake/lib/inflector.php 这里主要是处理单复数,带下划开命名以及驼峰式命名
cake/lib/configure.php 里面提供文件配置的读写,路径的设置,以及加载文件的方法
cake/lib/cache.php 缓存的操作

Configure::getInstance(); 开始对项目的配置
config/core.php 项目的配置文件
config/bootstrap.php 项目的入口文件

App::import('Core', array('Dispatcher')); 加载核心,开始做正事了,GO
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch($url); 开始执行,通过对当前的url解析,如果你设置了压缩Js、Css,则对这些文件压缩输出,如果你对页面设置缓存,则直接输出缓存页面,最后查找相应的 Controller。如果找不到,则进行相应的错误处理。
实例化当前Controller,确定视图路径,实例化Component,获得仅当前Controller[不包含父类Controller]的方法
对当前Controller中私有方法、带admin路由或者带prefix的方法进行保护,不允许直接访问
设置当前Controller的基本属性,如base、here、webroot、plugin、params、action、 passedArgs[array_merge($this->params['pass'], $this->params['named'])]
调用Controller中的constructClasses方法
执行__mergeVars方法,该方法对父子类的components、helpers、uses等属性进行特殊合并处理
调用Component->init()方法,载入用户设置的系列components(Session为默认),并默认enabled属性为true。(该属性可以后期在beforeFilter里修改)
调用Component->initialize()方法,若系列components里有这个initialize方法并且该component 的enabled为true,则调用该components->initialize方法(这里enabled用户好像无法通过 Controller设置,只能为true)
调用当前Controller中beforeFilter()方法,这个方法是个好东西^_^
调用Component->startup()方法,同样,若系列components里有这个startup方法并且该component的 enabled为true,则调用该components->startup方法(这里enabled倒是可以通过beforeFilter设置),该方法也是components里最重要的方法,比如Auth就在这里大作文章^_^
开始执行当前Controller里的Action方法
如果设置autoRender为true,则根据调用当前Controller的render()方法,否则返回或输出Action方法的返回的数据
调用Controller的render()方法时,先调用当前Controller中的beforeRender()方法
加载视图渲染类
调用Component->beforeRender()方法,同样,若系列components里有这个beforeRender方法并且该 component的enabled为true,则调用该components->beforeRender方法(这里enabled可以通过 beforeFilter设置)
获取当前Model的数据验证错误信息,给View使用
调用View的render()方法
载入相关Helper助手
调用Helper的beforeRender()方法
调用Helper的afterRender()方法
相关的缓存处理
执行renderLayout()方法,当然前提你要允许渲染布局,默认为default.ctp布局文件
调用Helper的beforeLayout()方法
调用Helper的afterLayout()方法
调用Component->shutdown()方法,同样,若系列components里有这个shutdown方法并且该component的 enabled为true,则调用该components->shutdown方法(这里enabled可以通过beforeFilter设置)
执行当前Controller里的afterFilter方法,这里你可以对视图的输出内容($controller->output)做一些处理
返回或输出视图数据。
流程完毕。
以上只是以个人目前水平,浏览源代码所得结论。可能还不全面。清楚了这些,你就知道在cakephp项目里在适当的地方做适当的事情了。
此文章,我会在我的博客上慢慢完善

發表日期:2009/1/1 21:55
應用擴展 工具箱


回覆: 解决Router带prefix时,formHelper Create的问题
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
plugin当然也可以了,但相同功能的代码,几乎要复制一遍,而且万一以后,修改也不方便^_^

發表日期:2008/12/30 13:29
_________________
CAKEPHP教程:http://www.71151461.cn
應用擴展 工具箱


回覆: 解决Router带prefix时,formHelper Create的问题
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
routing.admin路由只能设置一个呀。但是prefix不同,按所需我可以分配如超级管理员后台superuser_... 普通管理员后台admin_...,会员后台member_...等等。然后可以对每个prefix进行不同的权限控制

發表日期:2008/12/29 21:57
_________________
CAKEPHP教程:http://www.71151461.cn
應用擴展 工具箱


解决Router带prefix时,formHelper Create的问题
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
(顺便说一下重大消息:cake出稳定版了^_^)
Router代码如下:

1. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin', 'admin' => true));

当表单Add时候,也就是

1. $form->create('Model', array('url' => array('admin' => true)));

生成的代码是/admin/models/add,正是所期望的。

但是表单为编辑时,也就是$this->data填充了$form表单值后,问题就出来了,同样上面的create代码,生成的结果却为/models/edit/{id}/admin:1。

这显然不是我们所要的,正确应当为/admin/models/edit/{id}。

这个问题困扰了我很久,一直找不出十分完美的解决方案。

起先采用更改$form->create时,url写成绝对路径,如

1. $form->create('Model', array('url' => Router::url(array('action' => 'admin_edit', 'admin' => true, $form->value('Model.id')))));

但是实在是别扭,总感觉没达到cake懒人的要求。

后来,翻了formHelper源码,貌似当表单为编辑时,url里,会自动多出个参数(named)id。

大概源码如下:

1. ......
2. if ($recordExists) {
3. $created = true;
4. $id = $this->data[$model][$data['key']];
5. }
6. ......
7. $actionDefaults = array(
8. 'plugin' => $this->plugin,
9. 'controller' => $view->viewPath,
10. 'action' => $options['action'],
11. 'id' => $id
12. );

所以问题就来了,因为我的路由规则是

1. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin', 'admin' => true));

是不带named形式参数的。所以,上面编辑表单时的url路径当然就不匹配了。

在此规则后,再添加如下规则

1. Router::connect('/admin/:controller/:action/:id', array('prefix' => 'admin', 'admin' => true));

一切完美……http://www.71151461.cn/articles/view/35

發表日期:2008/12/28 11:31
應用擴展 工具箱


回覆: Containable使用方法
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
写的很简单,呵呵。其实更多的方法,可以参考cake/test下的东西,里面的方法比较全面。

發表日期:2008/12/24 12:35
_________________
CAKEPHP教程:http://www.71151461.cn
應用擴展 工具箱


回覆: 升級RC4後無法 redirect ?
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
在下一直很正常的说。
有没有错误信息之类的?

發表日期:2008/12/23 16:01
_________________
CAKEPHP教程:http://www.71151461.cn
應用擴展 工具箱


Containable使用方法
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
首先,要知道cake的behaviors是怎么用。唠叨一句,cake里的behaviors是拿来扩展model的。

model 里提供了好多回调函数,诸如 beforeSave afterSave beforeDelete.....等等,这些方法,在behaviors里同样适用。只过,model调用这些回调函数时,默认把当前model实例当成第一个参数传入。所以behaviors的方法,如果想让外部可用,那么函数名大概为

1. function myFunc(&$model, $参数1, $参数2...) {
2. //doSomeThing
3. }

使用时,载入当前behaviors,然后$model->myFunc($参数1, $参数2...);

载入behaviors,最简单的方法当前就是在Model里加上,如:

1. <?php
2. class AppModel extends Model {
3. var $actsAs = array(
4. 'Containable'
5. );
6. }
7. ?>

忘了介绍Containable是干什么用的了。经常听到人说,“我Model间使用了很多关联,怎么样才能取到所需的数据,减少不必要的数据库操作呢?”。Containable就是拿来干这事儿的。当然Model里有recursive属性,但是这个不怎么人性化,虽然有-1 0 1 2等等几级可以设置关联,但是同一级之间,我想取消到不必要的关联,这办法就不管用了。顺便说一句,要想取消掉当前Model所有关 联,recursive应该设置为-1,而不是为0。如果为0的话,当前Model还会关联belongsTo和hasOne的Model。

Model里还有bindModel和unbindModel方法,但是写起来太啰嗦了,对于太懒的人,包括我,肯定……@#&%……¥。我想不通的是,cake为什么不把Containable写到Model内部里去,而非要当成behaviors使用。难道是为了证明behaviors的强大,呵呵!废话不说,说说它是如何使用的吧。

按照上面的代码,载入所需的behaviors,如果你只想在特定环境用一次的话,那么就动态载入

1. $model->Behaviors->attach('Containable');

因为Containable比较实用,所以我在Model基类,即AppModel就载入这个Behaviors了。

假如

User hasMany Article

User hasOne Profile

User belongsTo Group

User hasAndBelongsToMany Role

Article hasMany Comment

Comment belongsTo User

......

我当前对User Model进行操作。

1、我只想取出用户所对应的文章

1. $userModel->contain('Article');
2. $data = $userModel->find('all');

2、我想取出用户所对应的文章,以及文章所拥有的评论

1. $userModel->contain('Article.Comment');
2. //或者
3. $userModel->contain(array('Article' => 'Comment'));
4. $data = $userModel->find('all');

3、我只想取出用户对应文章的标题

1. $userModel->contain('Article(title)');
2. $data = $userModel->find('all');

4、我想取出用户对应的文章,以及文章对应的评论,以及评论所对应的用户

1. $userModel->contain(array('Article' => array('Comment' => 'User')));

5、我想取出用户对应文章的标题,但是这些文章的条件是is_top=1

1. $userModel->contain(array('Article' => array('fields' => array('title'), 'conditions' => array('is_top' => 1))));

........依此类推吧,大概就这样。

如何在分页里使用呢。很简单,拿上面的例子来说。

1. $this->paginate = array('User' => array('fields' => array('title'), 'contain' => array('Article(title)')));

有人说,分页时,我也用

1. $userModel->contain('Article');

好像结果不对。那就对了,因为分页时,Model其实find了两次了,一次是find count取总数,一次是取出当页数据。而每次find时,默认reset为true,所以find结束后,都会resetAssociations一下,重置当前的Model关联。所以换个方法

1. $userModel->contain(false, array('Article'));

第一个参数如果为布尔值的话,那么会当成reset参数传递进去了。
更多请参考cakephp教程系列

發表日期:2008/12/23 10:52
應用擴展 工具箱


修改Auth默认加密方式
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
Auth默认的加密方式比较复杂。

大概的步骤为:

1. $password = Configure::read('Security.salt') . $password;

如果当前PHP环境里sha1函数存在,则

1. $password = sha1($password);

如果当前PHP环境里mhash函数存在,则

1. $password = bin2hex(mhash(MHASH_SHA256, $password));

如果当前PHP环境里hash函数存在,则

1. $password = hash('sha256', $string);

最后,逼不得已,才使用

1. $password = md5($string);

那么可不可以更改Auth默认的加密方式。答案是肯定的,CakePHP还是比较人性化的,呵呵!

通过下面的方法,我们可以把Auth默认加密方式改成md5。当然看个人所需,你可以随便修改。

方法一:

修改

1. $this->Auth->authenticate = new XXXXXClass();

看清楚是authenticate而不是authorize

在这个XXXXXClass里写个hashPasswords()方法,如:

1. class XXXXXClass {
2.
3. var $userModel = 'User';
4.
5. var $fields = array(
6.
7. 'username' => 'username',
8.
9. 'password' => 'password',
10.
11. );
12.
13. function hashPasswords($data){
14.
15. if (is_array($data) && isset($data[$this->userModel])) {
16. if (isset($data[$this->userModel][$this->fields['username']]) && isset($data[$this->userModel][$this->fields['password']])) {
17. $data[$this->userModel][$this->fields['password']] = $this->password($data[$this->userModel][$this->fields['password']]);
18. }
19. }
20. return $data;
21.
22. }
23.
24. function password($password){
25.
26. return md5($password);//我们采用md5方式
27.
28. }
29.
30. }

这样子,我们就已经把Auth加密方式改成了md5了(以上代码形式其实就来自Auth,我懒的动,你或许可以写的更好一些,呵呵)。通常我们不需要另外再建立个Class文件,因为Auth默认需要一个UserModel来做登陆的。上面可以改成

1. $this->Auth->authenticate = $this->Auth->getModel();

然后,我们就可以把上面Class文件里的代码移到User Model里了。

方法二:

Auth加密方式,采用的是Security::hash($string, $type = null, $salt = false)静态方法。其代码如下:

1. function password($password) {
2. return Security::hash($password, null, true);
3. }

再看看Security::hash方法

1. function hash($string, $type = null, $salt = false) {
2. $_this =& Security::getInstance();
3.
4. if ($salt) {
5. if (is_string($salt)) {
6. $string = $salt . $string;
7. } else {
8. $string = Configure::read('Security.salt') . $string;
9. }
10. }
11.
12. if (empty($type)) {
13. $type = $_this->hashType;
14. }
15. $type = strtolower($type);
16.
17. if ($type == 'sha1' || $type == null) {
18. if (function_exists('sha1')) {
19. $return = sha1($string);
20. return $return;
21. }
22. $type = 'sha256';
23. }
24.
25. if ($type == 'sha256' && function_exists('mhash')) {
26. return bin2hex(mhash(MHASH_SHA256, $string));
27. }
28.
29. if (function_exists('hash')) {
30. return hash($type, $string);
31. }
32. return md5($string);
33. }

我们看到Auth调用时,参数$type为null。那么就可以修改Security的hashType属性,如:

1. Security::setHash('md5');

强制改变其加密方式了。但是这里有个不称心的地方就是无论你修改为何种加密方式,其密码总是以

1. $password = Configure::read('Security.salt') . $password;

为基础的。

方法三:

修改Auth组件,有一次在一个群,总是听一个家伙在嚷嚷,其大意是"CakePHP哪里哪里有BUG,我要修改它的源代码"。你确信 CakePHP的代码有BUG,你确信你写的代码没有BUG,并且能兼容整个CakePHP环境,你不再去更新它的升级版了,那么你改吧,呵呵!

OOP的好处之一就是可以继承并修改。言归正传,那么我们如何修改Auth呢。简单,自己再写个Component,继承AuthComponent

1. <?php
2. App::import('Component', 'Auth');
3.
4. class MyAuthComponent extends AuthComponent {
5. /**
6. * 更改Auth用户密码加密方式为md5
7. * @return string md5($password)
8. */
9. function password($password) {
10. return md5($password);
11. }
12. }

以后,我们就可以直接用MyAuth组件来替换Auth了。当然了,你可以在里面做更多的事。

方法四:

你来想吧……^_^
更多信息:http://www.71151461.cn/

發表日期:2008/12/20 9:15
應用擴展 工具箱


小型博客Cake源码下载
Just popping in
註冊日期:
2008/12/19 9:24
文章: 9
基于CakePHP1.2 RC3

表在config/sql/ahuino1.sql中

下载cakephp框架,放在你喜欢的目录里,不要放在本项目当中。然后修改webroot/index.php里第59行


define('CAKE_CORE_INCLUDE_PATH', 'E:\wamp\www\lib\cakephp');

以上改成cakephp所放的地址。

下载地址:http://www.71151461.cn/articles/view/22

功能大概有:

文章管理
文章类别管理
文章标签
评论
友情链接
采用Routing.admin作后台管理
文章发布整合了fck。可以看看里面的FckHelper。fck同时带了代码高亮插件。

布局layout + element + requestAction。不过还没有缓存控制!

發表日期:2008/12/19 9:29
應用擴展 工具箱