您好,欢迎访问一九零五行业门户网

YII 的源码分析(三),yii源码分析_PHP教程

yii 的源码分析(三),yii源码分析前面已经看完了启动一个yii程序所要经过的流程,以及渲染一个页面是怎么完成的。今天要分析的是yii是如何处理用户请求的。也就是控制和动作部分。
还是以helloworld为例演示这一过程。我们在地址栏输入http://localhost/study/yii/demos/helloworld/index.php,页面就显示了hello world.
前面的分析都是用的默认值,但是如果url有参数的时候,yii又是怎么处理的呢?带着这个问题,我们具体来分析一下。
在cwebapplication中有这样一行代码:
$route=$this->geturlmanager()->parseurl($this->getrequest());
这就是传说中的路由了,是不是有点小鸡冻呢?先看看geturlmanager是个神马。
public function geturlmanager() { return $this->getcomponent('urlmanager'); }
这个又要通过找关系了.
public function getcomponent($id,$createifnull=true) { if(isset($this->_components[$id])) return $this->_components[$id]; elseif(isset($this->_componentconfig[$id]) && $createifnull) { $config=$this->_componentconfig[$id]; if(!isset($config['enabled']) || $config['enabled']) { yii::trace(loading \$id\ application component,'system.cmodule'); unset($config['enabled']); $component=yii::createcomponent($config); $component->init(); return $this->_components[$id]=$component; } } }
执行了return $this->_components[$id]; id就是传进去的urlmanager,其实从这里也还看不出什么,直接找到urlmanager这个类,看parseurl:
public function parseurl($request) { if($this->geturlformat()===self::path_format) { $rawpathinfo=$request->getpathinfo(); $pathinfo=$this->removeurlsuffix($rawpathinfo,$this->urlsuffix); foreach($this->_rules as $i=>$rule) { if(is_array($rule)) $this->_rules[$i]=$rule=yii::createcomponent($rule); if(($r=$rule->parseurl($this,$request,$pathinfo,$rawpathinfo))!==false) return isset($_get[$this->routevar]) ? $_get[$this->routevar] : $r; } if($this->usestrictparsing) throw new chttpexception(404,yii::t('yii','unable to resolve the request {route}.', array('{route}'=>$pathinfo))); else return $pathinfo; } elseif(isset($_get[$this->routevar])) return $_get[$this->routevar]; elseif(isset($_post[$this->routevar])) return $_post[$this->routevar]; else return ''; }
从上面的代码来看,如果我们不在url上传点东西,直接就return ''了。于是问题来了,参数要怎么传呢?
isset($_get[$this->routevar])

public $routevar='r';
于是有办法了,让我们一起来使点坏吧。加上这样的一个参数helloworld/index.php?r=abc
发现报错了。说明abc这个控制器是不存在的,事实上也是不存在的,使点小坏坏而已,正所谓男人不坏,女人不爱。
改成helloworld/index.php?r=site就可以显示hello world了,这是什么鬼原理呢?原因很简单,因为定义了site控制器嘛。
class sitecontroller extends ccontroller{ /** * index action is the default action in a controller. */ public function actionindex() { echo 'hello world'; }}
好吧,这个我没有意见,但是actionindex又是神么鬼?在yii中,这称为动作。它捕获的是控制器后面的参数,如果我们输?r=site/index就是index,动作是用“/进行分隔的,为了验正一下我说的不是骗女孩子的鬼话,我在site控制器里加一个动作给你看一下:
class sitecontroller extends ccontroller{ /** * index action is the default action in a controller. */ public function actionindex() { echo 'hello world'; } public function actionview() { echo 'hello view'; }}
访问?r=site/view的时候,是不是看到输出'hello view'了呢?肯定是的,虽然我读的书少,但是你骗不了我的,有图有真相:
我一点儿也不喜欢用site这个名字,test才是我的最爱,于是我又建了一个test控制器来尝试一下。
眼尖的一定看到怎么写了一个actions,这是什么鬼?我也是刚试了才知道,它其实是另一种表示方式。
我记得在blog那个例子中有用过,用来显示验证码:
/** * declares class-based actions. */ public function actions() { return array( // captcha action renders the captcha image displayed on the contact page 'captcha'=>array( 'class'=>'ccaptchaaction', 'backcolor'=>0xffffff, ), // page action renders static pages stored under 'protected/views/site/pages' // they can be accessed via: index.php?r=site/page&view=filename 'page'=>array( 'class'=>'cviewaction', ), ); }
我把它理解为集中声明第三方业务的动作集合,因为本控制器内的动作,我觉得还是action+id 的方式直接。
什么鬼?你说我用的是index.php/site/captcha 而不是index.php?r=site/captcha .这又得从配置文件说起。
'urlmanager'=>array( 'urlformat'=>'path', 'rules'=>array( 'post//'=>'post/view', 'posts/'=>'post/index', '/'=>'/', ), ),
urlformat 有path 和 get两种,如果在main.php中没有指定,那么就是get方式,也就是index.php?r=site/captcha这种。如果指定了,即index.php/site/captcha这种
从字面上也很好理解,path就是像路径的格式,get就是?这种形式。
关于路由和控制器部分的内容还有很多,但是本节就到这里了。
http://www.bkjia.com/phpjc/930706.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/930706.htmltecharticleyii 的源码分析(三),yii源码分析 前面已经看完了启动一个yii程序所要经过的流程,以及渲染一个页面是怎么完成的。今天要分析的是yii是如...
其它类似信息

推荐信息