YII Framework学习教程-YII的C-控制器-2011-11-14

       设计模式中,MVC结构是使用最多的。现在大部分PHP框架的必备标准就是拥有MVC模式。这是最基本的要求。如果不具备这个要求,就不能称之为框架,只能说是一个工具类集合。M-V-C中是控制器,可以认为是MVC结构的核心,调度者,像一个国家的领导人。大部分程序的实现还是在此部分,(如果没有涉及的很多数据逻辑的时候,因为对数据库的访问操作,我们大部分都可以用YII提供的功能实现,绝大部分无非就是CRUD。),所以你的MVC中C的代码决定了你的代码的质量。你的水平也可以通过C层的代码来衡量。当然这不是绝对的。

    MVC结构中action也是很重要的角色。

    控制器C的功能其实是action实现的。所以C如果是是领导人。那么他内部的action可以认为是一个个的政府官员。所以action决定了这个国家的。。。。aciton的所作所为,他的好坏决定了整个政府体系的好坏。所以作为一个aciton要做好自己的职责。为人民服务。

    

     来看看YII中C的规则:

     C类文件的存放位置以及规范:

     一般是在protected/controllers文件夹中。如果你的框架中存在modules.就位于/protected/modules/模块名称/controllers下面

    

      C类的文件名通常是一Controller.php结尾。的前面是你的类名。例如TestController.php。Test就是控制器的名称。如果是TestTestController.php,注意了默认的访问的时候的路由是第一个字母变为小写其他的保持不变。即http://www.localyii.com/testwebap/index.php?r=testTest。 对应View中文件夹应该为testTest和默认路由保持一直。所以C类的名称大小写敏感。并且敏感到VIew层。



   C类的结构

1.必须extends Controller或者CController

2.类名一般和文件名保持一直必须一Controller结尾。

<?php


class UserController extends Controller
{
}

如果看文档是用的

<?php
class SiteController extends CController
{
}

 CController和Controller的关系是什么

看看代码

<?php
/**
 * Controller is the customized base controller class.
 * All controller classes for this application should extend from this base class.
 */
class Controller extends CController
{
	/**
	 * @var string the default layout for the controller view. Defaults to '//layouts/column1',
	 * meaning using a single column layout. See 'protected/views/layouts/column1.php'.
	 */
	public $layout='//layouts/column1';
	/**
	 * @var array context menu items. This property will be assigned to {@link CMenu::items}.
	 */
	public $menu=array();
	/**
	 * @var array the breadcrumbs of the current page. The value of this property will
	 * be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
	 * for more details on how to specify this property.
	 */
	public $breadcrumbs=array();
}


可以看到他们之间的关系。看看注释就知道了他们直接的区别。可以认为Controller是CController边角料,实质上还是CController是做主要工作的。不信可以找到CController类的实现代码看看,就发现了。这里用Controller,毕竟可以少些一个字母。

下面看看控制器的内部的结构,打开SiteController.php文件

<?php

class SiteController extends Controller
{
	/**
	 * 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',
			),
		);
	}

	/**
	 * This is the default 'index' action that is invoked
	 * when an action is not explicitly requested by users.
	 */
	public function actionIndex()
	{
		// renders the view file 'protected/views/site/index.php'
		// using the default layout 'protected/views/layouts/main.php'
		$this->render('index');
	}

	/**
	 * This is the action to handle external exceptions.
	 */
	public function actionError()
	{
	    if($error=Yii::app()->errorHandler->error)
	    {
	    	if(Yii::app()->request->isAjaxRequest)
	    		echo $error['message'];
	    	else
	        	$this->render('error', $error);
	    }
	}

	/**
	 * Displays the contact page
	 */
	public function actionContact()
	{
		$model=new ContactForm;
		if(isset($_POST['ContactForm']))
		{
			$model->attributes=$_POST['ContactForm'];
			if($model->validate())
			{
				$headers="From: {$model->email}\r\nReply-To: {$model->email}";
				mail(Yii::app()->params['adminEmail'],$model->subject,$model->body,$headers);
				Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
				$this->refresh();
			}
		}
		$this->render('contact',array('model'=>$model));
	}

	/**
	 * Displays the login page
	 */
	public function actionLogin()
	{
		$model=new LoginForm;

		// if it is ajax validation request
		if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
		{
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}

		// collect user input data
		if(isset($_POST['LoginForm']))
		{
			$model->attributes=$_POST['LoginForm'];
			// validate user input and redirect to the previous page if valid
			if($model->validate() && $model->login())
				$this->redirect(Yii::app()->user->returnUrl);
		}
		// display the login form
		$this->render('login',array('model'=>$model));
	}

	/**
	 * Logs out the current user and redirect to homepage.
	 */
	public function actionLogout()
	{
		Yii::app()->user->logout();
		$this->redirect(Yii::app()->homeUrl);
	}
}
 

3.action方法的的规范可以从上述代码中看到。就是以action开头。然后是action的具体名称

  类中有一个actions方法。看具体代码

/**
	 * 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',
			),
		);
	}


    public function actions()
	{
		// return external action classes, e.g.:
		return array(
			'action1'=>'path.to.ActionClass',
			'action2'=>array(
				'class'=>'path.to.AnotherActionClass',
				'propertyName'=>'propertyValue',
			),
		);
	}
	




public function createAction($actionID)
	{
		if($actionID==='')
			$actionID=$this->defaultAction;
		if(method_exists($this,'action'.$actionID) && strcasecmp($actionID,'s')) // we have actions method
			return new CInlineAction($this,$actionID);
		else
		{
			$action=$this->createActionFromMap($this->actions(),$actionID,$actionID);
			if($action!==null && !method_exists($action,'run'))
				throw new CException(Yii::t('yii', 'Action class {class} must implement the "run" method.', array('{class}'=>get_class($action))));
			return $action;
		}
	}
	protected function createActionFromMap($actionMap,$actionID,$requestActionID,$config=array())
	{
		if(($pos=strpos($actionID,'.'))===false && isset($actionMap[$actionID]))
		{
			$baseConfig=is_array($actionMap[$actionID]) ? $actionMap[$actionID] : array('class'=>$actionMap[$actionID]);
			return Yii::createComponent(empty($config)?$baseConfig:array_merge($baseConfig,$config),$this,$requestActionID);
		}
		else if($pos===false)
			return null;
		// the action is defined in a provider
		$prefix=substr($actionID,0,$pos+1);
		if(!isset($actionMap[$prefix]))
			return null;
		$actionID=(string)substr($actionID,$pos+1);
		$provider=$actionMap[$prefix];
		if(is_string($provider))
			$providerType=$provider;
		else if(is_array($provider) && isset($provider['class']))
		{
			$providerType=$provider['class'];
			if(isset($provider[$actionID]))
			{
				if(is_string($provider[$actionID]))
					$config=array_merge(array('class'=>$provider[$actionID]),$config);
				else
					$config=array_merge($provider[$actionID],$config);
			}
		}
		else
			throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));
		$class=Yii::import($providerType,true);
		$map=call_user_func(array($class,'actions'));
		return $this->createActionFromMap($map,$actionID,$requestActionID,$config);
	}

主要功能:

1.可以把action的功能放到一个单独的类文件中,这里就是可来绑定action和action的具体类文件。可以不action写到外部,其他的框架应该没这个功能。

 例如。

自带的验证码的例子,生成验证码

http://www.localyii.com/testwebap/index.php?r=site/captcha

自定义例子

目录结构

├── controllers
│   ├── post
│   │   └── UpdateAction.php
│   ├── SiteController.php
│   ├── TestTestController.php
│   └── UserController.php

文件TestTestController.php

 

	public function actions()
	{
		// return external action classes, e.g.:
		return array(
			'update'=>'application.controllers.post.UpdateAction',
		);
	}


 文件UpdateAction.php



<?php
class UpdateAction extends CAction {
	public function run() {
		exit('Test1 ,run  update action') ;
	}
}

访问

http://www.localyii.com/testwebap/index.php?r=testTest/update


会看到打印如下结果

Test1 ,run update action



大体对控制器和action的使用有所了解了。具体的还需要慢慢写代码体会。具体的细节也需也自己在代码中学习理解。这里只是简单的例子。



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值