Yiissh框架原理及流程控制器动作问题,怎么解决

配置文件设置默认路由 和控制器动作 - 问答 - Yii Framework 中文网
配置文件设置默认路由 和控制器动作
12442次浏览
悬赏 0 金钱
怎么在配置文件设置默认路由 和控制器动作
默认控制器动作,是不是只有在控制器里才能定义
默认控制器动作,是不是只有在控制器里才能定义
共 2 条回复一般都是要自己定义一个controller类 继承自yii的\yii\web\Controller
作为项目里所有controller的父类,可以在这个方法里定义defaultAction,或者在入口脚本里通过Yii::$container-&set() 方法改变\yii\web\Controller的属性defaultAction
@大裤衩子: 好的感谢
'defaultRoute'=&'controller/action',
所有可配置参数请参照
yii\web\Application 和yii\base\Application
共 1 条回复
这个配置什么意思啊 我的配置了没起作用
基础版本的在config/web.php下找到这句
'id' =& 'basic',
'basePath' =& dirname(__DIR__),
'bootstrap' =& ['log'],
'defaultRoute' =& 'index',
您需要登录后才可以回答。 |Yii框架中module(模块)或模块风格控制器的URL美化
由于最近自己业余时间在写一套类似Tumblr的博客,涉及到的模型、控制器、视图比较多,如用户模块、文章模块、图片模块、音乐模块、视频模块、东西(商品)模块,各模块下标签、评论、分类、图片等等自成一块,这样的话控制器和视图如果单独开来的,将会显得很臃肿,繁杂,不便于管理和维护,但是因为功能暂时比较轻,又不想将其各个模块化,于是便准备用模块风格 的文件夹来管理控制器和视图,具体就是类似下面这种风格:
控制器(以文章为例)
视图(以文章为例)
上述控制器中,IndexController对应着原来的ArticleController,因为为了方便在urlManager中进行统一匹配,将所有模块主控制器名设为IndexController,例如MusicController为IndexController,以此类推。ArticleCategoryController改为CategoryController,以此类推,
这样就可以在URL中以形如article/category/create这种方式来访问category的create方法,而对原来article/create,现在配置urlManager仍以article/create的形式访问,具体在protected/config/main.php中设置urlManager如下所示:
* author:农夫庄园
* url: https://www.icultivator.com/p/6168.html
* website: https://www.icultivator.com
'urlManager'=&array(
'urlFormat'=&'path',
'rules'=&array(
''=&'site/index',
''=&'site/',
''=&'/index/index',
'/'=&'/index/view',
'//'=&'/index/',
'/tag/'=&'/index/tag',
'/'=&'/index/',
'//'=&'//view',
'///'=&'//',
'//'=&'//',
'showScriptName'=&FALSE,
这样就可以实现URL的统一美化,如查看article的id为1的文章,可以通过article/1来访问,tag为test的文章可以通过article/tag/test来访问,等等。
此外还要注意的是在各个IndexController中需要更改原来render的url路径为//article/(以article为例),在视图的article控制器对应各view文件中,也要修改相应的url路径,这样就可以实现URL的美化了,如果不想修改render里的路径,可以将原来article里的view文件放到/views/article/index文件夹下,就可以了。原理是如果render里的路径包含//,那么相应的url会解析成/path/to/views.&/&.article/view,否则会解析成/path/to/views/article/index.&/&.view,至于为什么,可以参考Yii核心源文件,简而言之,就是Yii::app( )-&getViewPath( )和$this-&getViewPath( )两个方法的调用问题,前者获取到的view文件是通过Yii::app( )-&getViewPath( ).&/&.$viewName,后者是通过$this-&getViewPath( )获取view文件。
当然如果您有兴趣的话,也可以通过继承CBaseUrlRule类来自定义一个UrlRule类实现自定义URL生成和解析,详情可参见这篇文章:Yii框架官方指南系列43&&专题:URL(创建、路由、美化及自定义)。这里就不赘述了,对于Yii框架中URL的管理,可以参考这篇文章:Yii框架分析(八)&&URL管理。
有什么疑问欢迎在下面的回复中讨论。YII开发技巧分享——控制器中动作权限控制
在YII开发中,我们可以通过控制器中对accessRules函数的配置进行相应动作权限控制,默认情况下可能是这样:
public function accessRules()
array('allow',
'actions'=&array('admin','delete'),
'users'=&array('admin'),
array('deny',
'users'=&array('*'),
在函数中可以配置具体哪些用户可以访问某些动作,但是在开发过程中我们很容易会发现上面有的几个方式完全不够用,于是不约而同地就会相对这个能不能访问的规则是否能让我们自定义了,答案是肯定的,确实可以自定义!
具体方法是这样的(主要是用到accessRules中的expression属性):
在accessRules函数体中:
return array(
array('allow',
'actions'=&array('admin'),
'expression'=&array($this,'getadvancedusers'),
没错就是这一句“ 'expression'=&array($this,'advancedusers')”,我想相信接下来大家就很清楚了,就是在这个控制器中添加一个advancedusers函数(该函数名自己可以根据自己的需要修改),函数如下:
public function advancedusers()
$users=Users::model()-&findByAttributes(array('uid'=&Yii::app()-&user-&id));
return ($users-&ugid == 1);//看当前用户的用户组ID是否为1(我这里1代表高级用户)
public function accessRules()
return array(
array('allow',
// 所有用户有操作权限:index,view
'actions'=array('index','view'),
'users'=array('*'),
array('allow', // 仅登录用户有权限操作:create,update
'actions'=array('create','update'),
'users'=array('@'),
array('allow', // 指定用户有权限操作:admin,delete
'actions'=array('admin','delete'),
'users'=array('admin'),
array('deny',
// 禁止所有用户操作
'users'=array('*'),
这里返回一个bool值,返回0代表检查不通过,就是说没有访问admin这个动作的权限!
自定义控制器验证 behaviors()
Yii2全面解析之权限管理RBAC
Yii的accessRules用法
Yii2 路由之同时支持 URL 原始和美化的请求 [ 2.0 版本 ]
Yii-控制器- accessRules访问权限控制
Yii2-权限控制RBAC实战篇(一)
没有更多推荐了,Yii2.0源码分析之——控制器文件分析(Controller.php)创建动作、执行动作
先说一下Yii中的控制器是做什么用的,以及在什么地方使用.
在Yii中,当请求一个Url的时候,首先在application中获取request信息,然后由request通过urlManager解析出route,再在Module中根据route来创建controller并处理request。
如:。会使用SiteController里面的actionLogin动作来处理这个请求。
Yii中总共有三种控制器类
base\Controller.php& && &&&这个是下面两个的基类console\Controller.php& &这个是控制台控制器web\Controller.php& && &&&这个是web控制器
先看看基类base\Controller.php,在基类中大致可分为三个部分
和action相关的功能和render相关的功能其它功能
1、和action相关的函数
我们按照这些函数的调用顺序来一一说明
执行路由:public function run($route, $params = [])
* route值即可以为当前controller中的action id,
* 也可为module id/controller id/action id/这种格式
* 如果以“/”开头,将于application来处理,否则,用控制器所属模块来处理
public function run($route, $params = [])
//先判断route中有没有“/”
$pos = strpos($route, '/');
if ($pos === false) {
//如果没有“/”,则为action id,直接调用runAction来执行这个action。如:index
return $this-&runAction($route, $params);
} elseif ($pos & 0) {
//如果“/”在中间,由当前的模块来处理这个route。如:test/index
return $this-&module-&runAction($route, $params);
//如果以“/”开头,则用当前的应用程序来处理这个route。如:/test/
return Yii::$app-&runAction(ltrim($route, '/'), $params);
执行动作:public function runAction($id, $params = [])
* $id 为action的id,如定义的actionIndex,那么id就为Index。
public function runAction($id, $params = [])
//创建action
$action = $this-&createAction($id);
if ($action === null) {
throw new InvalidRouteException('Unable to resolve the request: ' . $this-&getUniqueId() . '/' . $id);
Yii::trace(&Route to run: & . $action-&getUniqueId(), __METHOD__);
if (Yii::$app-&requestedAction === null) {
Yii::$app-&requestedAction = $action;
$oldAction = $this-&
$this-&action = $action;
//用来保存当前控制器的所有父模块,顺序为由子模块到父模块
$modules = [];
$runAction = true;
* 获取当前控制器的所以的模块,并执行每个模块的beforeAction来检查当前的action是否可以执行,
* 注意:getModules返回的数组顺序为:从父模块到子模块,
* 所以在执行beforeAction的时候,先检查最外层的父模块,然后检查子模块。
* 然而在执行afterAction的时候,顺序就反过来了,先执行子模块,最后执行父模块。
foreach ($this-&getModules() as $module) {
if ($module-&beforeAction($action)) {
array_unshift($modules, $module);
$runAction = false;
$result = null;
//如果所以的父模块都满足执行的条件
if ($runAction) {
* 再判断当前控制器中是beforeAction,
* 最后由生成的action对象来执行runWithParams方法
* 执行完后,再执行afterAction方法
if ($this-&beforeAction($action)) {
$result = $action-&runWithParams($params);
$result = $this-&afterAction($action, $result);
//执行所有父模块的afterAction
foreach ($modules as $module) {
/** @var Module $module */
$result = $module-&afterAction($action, $result);
$this-&action = $oldAction;
return $result;
创建动作 public function createAction($id)
//由action id来创建action对象
public function createAction($id)
//使用默认的action id ,默认值为:index
if ($id === '') {
$id = $this-&defaultA
$actionMap = $this-&actions();
if (isset($actionMap[$id])) {
//如果在actions方法中指定了独立的动作,则直接使用此动作。
return Yii::createObject($actionMap[$id], [$id, $this]);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
* action id由:a到z、0到9、\、-、_ 这五种字符组成,
* 并且不能包含“--”
* 并且不能以“-”为开头或结尾
* 先以“-”把id分隔为数组,再以“ ”连接到字符串,把每个单词首字母大写,最后把“ ”去掉,并和&action&连接
* 1、new-post-v-4
* 2、['new','post','v','4']
* 3、new post v 4
* 4、New Post V 4
* 5、NewPostV4
* 6、actionNewPostV4
$methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
if (method_exists($this, $methodName)) {
* 如果当前控制器中存在这个actionXXX方法,
* 再通过反射生成方法,再次检查一遍,最后生成InlineAction
$method = new \ReflectionMethod($this, $methodName);
if ($method-&getName() === $methodName) {
return new InlineAction($id, $this, $methodName);
return null;
所以,如果一个动作在定义的时候是用骆驼格式名称的,如actionNewArticle,那么写url的时候r=site/new-article。详情见中的路由部分。
定义独立动作的数组:public function actions()
* 独立action定义
* 这个用来指定独立的action,返回格式为name-value的数组,name为action的id,value为action类的实现,如:
* return [
'action1' =& 'app\components\Action1',
'action2' =& [
'class' =& 'app\components\Action2',
'property1' =& 'value1',
'property2' =& 'value2',
* 这个主要是用于在子类中重写
public function actions()
return [];
由createAction可知,当controller在创建action的时候,会根据动作ID先在这个数组里面查找,如果找到则返回这个动作。所以这里定义的动作的优先级要大于在控制器里面定义的actionXXX函数。
绑定动作的参数:public function bindActionParams($action, $params)
* 绑定action的参数。
* 比如定义了动作 actionCrate($id,$name=null)
* 那个这个函数的作用就是从params(一般为$_GET)中提取$id,$name,
* 具体的实现在web\Controller.php和console\Controller.php中
public function bindActionParams($action, $params)
return [];
beforeAction、afterAction,事件触发
//在具体的动作执行之前会先执行beforeAction,如果返回false,则动作将不会被执行,
//后面的afterAction也不会执行(但父模块跌afterAction会执行)
public function beforeAction($action)
$event = new ActionEvent($action);
$this-&trigger(self::EVENT_BEFORE_ACTION, $event);
return $event-&isV
//当前动作执行之后,执行afterAction
public function afterAction($action, $result)
$event = new ActionEvent($action);
$event-&result = $result;
$this-&trigger(self::EVENT_AFTER_ACTION, $event);
return $event-&
在这个都会触发事件,beforeAction触发EVENT_BEFORE_ACTION事件,afterAction触发EVENT_AFTER_ACTION
2、和render相关的功能
关于视图的可以参考
另外对于视图文件是怎么查找的请参考:
获取、设置view组件:public function getView()、public function setView($view)
//获取view组件,
public function getView()
if ($this-&_view === null) {
$this-&_view = Yii::$app-&getView();
return $this-&_
//设置view组件
public function setView($view)
$this-&_view = $view;
渲染视图文件和布局文件(如果有布局的话):public function render($view, $params = [])
//渲染视图文件和布局文件(如果有布局的话)
public function render($view, $params = [])
//由view对象渲染视图文件
$output = $this-&getView()-&render($view, $params, $this);
//查找布局文件
$layoutFile = $this-&findLayoutFile($this-&getView());
if ($layoutFile !== false) {
//由view对象渲染布局文件,
//并把上面的视图结果作为content变量传递到布局中,所以布局中才会有$content变量来表示
return $this-&getView()-&renderFile($layoutFile, ['content' =& $output], $this);
return $output;
渲染视图文件,不会应用布局:public function renderPartial($view, $params = [])
//这个只渲染视图文件,不会应用布局
public function renderPartial($view, $params = [])
return $this-&getView()-&render($view, $params, $this);
渲染文件:public function renderFile($file, $params = [])
//这个就是用来渲染一个文件,$file为文件实路径或别名路径
public function renderFile($file, $params = [])
return $this-&getView()-&renderFile($file, $params, $this);
获取这个控制器对应的view的文件路径:public function getViewPath()
//获取这个控制器对应的view的文件路径,如@app/views/site/xxxx.php
public function getViewPath()
return $this-&module-&getViewPath() . DIRECTORY_SEPARATOR . $this-&
查找布局文件:protected function findLayoutFile($view)
//查找布局文件
protected function findLayoutFile($view)
$module = $this-&
//如果当前控制器设置了布局文件,则直接使用所设置的布局文件
if (is_string($this-&layout)) {
$layout = $this-&
} elseif ($this-&layout === null) {
//如果没有设置布局文件,则查找所有的父模块的布局文件。
while ($module !== null && $module-&layout === null) {
$module = $module-&
if ($module !== null && is_string($module-&layout)) {
$layout = $module-&
//如果没有设置布局文件,返回false
if (!isset($layout)) {
return false;
* 布局文件有三种路径写法
* 1、以“@”开头,这种会在别名路径中查找布局文件
* 2、以“/”开头,这个会从应用程序的布局文件目录下面查找布局文件
* 3、其它情况,
这个会从当前模块的布局文件目录下查查找布局文件
if (strncmp($layout, '@', 1) === 0) {
$file = Yii::getAlias($layout);
} elseif (strncmp($layout, '/', 1) === 0) {
$file = Yii::$app-&getLayoutPath() . DIRECTORY_SEPARATOR . substr($layout, 1);
$file = $module-&getLayoutPath() . DIRECTORY_SEPARATOR . $layout;
//如果布局文件有文件扩展名,返回
if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
return $file;
//加上默认的文件扩展名。
$path = $file . '.' . $view-&defaultE
//如果文件不存在,并且,默认的文件扩展名也不是php,则给加上php作为扩展名。
if ($view-&defaultExtension !== 'php' && !is_file($path)) {
$path = $file . '.php';
return $path;
3、其它功能
获取当前控制器所有的父模块:public function getModules()
//获取当前控制器所有的父模块
public function getModules()
$modules = [$this-&module];
$module = $this-&
while ($module-&module !== null) {
//由这里可知,返回的数组顺序为从父模块到子模块
array_unshift($modules, $module-&module);
$module = $module-&
return $modules;
获取控制器id:public function getUniqueId()
//返回控制器id
public function getUniqueId()
//如果当前所属模块为application,则就为该id,否则要前面要加上模块id
return $this-&module instanceof Application ? $this-&id : $this-&module-&getUniqueId() . '/' . $this-&
获取路由信息:public function getRoute()
//获取路由信息
public function getRoute()
return $this-&action !== null ? $this-&action-&getUniqueId() : $this-&getUniqueId();
另外还有几个变量和2个事件
//在执行beforeAction方法时触发的事件,
//如果对事件的isValid属性设置为false,将取消action的执行
const EVENT_BEFORE_ACTION = 'beforeAction';
//在执行afterAction方法是触发的事件
const EVENT_AFTER_ACTION = 'afterAction';
//控制器id
public $id;
//所属模块
public $module;
//控制器中默认动作
public $defaultAction = 'index';
//布局文件,如果设置为false,则不使用布局文件
public $layout;
//当前下面执行的action,可在事件中根据这个action来执行不同的操作
public $action;
//视图对象
private $_view;
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?yii搭建的框架,但是无法访问页面,怎么回事呀
[问题点数:40分]
本版专家分:0
CSDN今日推荐
本版专家分:10
本版专家分:20
本版专家分:104
本版专家分:367
本版专家分:50
匿名用户不能发表回复!|
其他相关推荐

我要回帖

更多关于 ssh框架各个框架作用 的文章

 

随机推荐