컨트롤러는 CController의 인스턴스 또는 해당 하위 클래스 중 하나입니다. 사용자가 요청할 때 애플리케이션에 의해 생성됩니다. 컨트롤러가 실행되면 일반적으로 필요한 모델을 도입하고 해당 뷰를 렌더링하는 요청된 작업을 수행합니다. 가장 간단한 형태의 작업은 이름이 작업으로 시작하는 컨트롤러 클래스 메서드입니다.
컨트롤러에는 일반적으로 기본 작업이 있습니다. 사용자의 요청에 수행할 작업이 지정되어 있지 않으면 기본 작업이 수행됩니다. 기본적으로 기본 작업 이름은 index입니다. CController::defaultAction을 설정하여 수정할 수 있습니다.
다음은 컨트롤러 클래스에 필요한 가장 간단한 코드입니다. 이 컨트롤러에는 정의된 작업이 없으므로 이에 대한 요청은 예외를 발생시킵니다.
class SiteController extends CController { }
컨트롤러와 액션은 ID로 식별됩니다. 컨트롤러 ID는 해당 컨트롤러 클래스 파일 protected/controllers/path/to/XyzController.php에 해당하는 'path/to/xyz' 형식입니다. 여기서 xyz 플래그는 실제 이름으로 대체되어야 합니다(예: post는 protected/controllers/PostController.php에 해당합니다.) 작업 ID는 작업 접두사가 없는 작업 메서드 이름입니다. 예를 들어 컨트롤러 클래스에 actionEdit이라는 메서드가 포함된 경우 해당 작업 ID는 edit입니다.
참고: 버전 1.0.3 이전에는 컨트롤러 ID 형식이 path/to/xyz가 아닌 path.to.xyz였습니다.
사용자는 경로 형태로 특정 컨트롤러와 작업을 요청합니다. 경로는 슬래시로 구분된 컨트롤러 ID와 작업 ID로 연결됩니다. 예를 들어 post/edit 경로는 PostController와 해당 편집 작업을 나타냅니다. 기본적으로 URL http://www.php.cn/은 이 컨트롤러와 작업을 요청합니다.
참고: 기본적으로 라우팅은 대소문자를 구분합니다. 버전 1.0.1부터 애플리케이션 구성에서 CUrlManager::caseSensitive를 false로 설정할 수 있습니다. 경로 대소문자를 구분하지 않습니다 . 대소문자를 구분하지 않는 모드에서는 컨트롤러 클래스 파일이 포함된 디렉토리 이름이 소문자이고 컨트롤러 맵 및 액션 맵에 사용되는 키가 소문자라는 규칙을 따라야 합니다.
버전 1.0.3부터 애플리케이션에 모듈이 포함될 수 있습니다. 모듈에서 컨트롤러 작업의 라우팅 형식은 moduleID/controllerID/actionID입니다. 자세한 내용은 모듈의 관련 장을 참조하세요.
컨트롤러 인스턴스는 CWebApplication이 들어오는 요청을 처리할 때 생성됩니다. 컨트롤러 ID가 지정되면 애플리케이션은 다음 규칙을 사용하여 컨트롤러의 클래스와 클래스 파일의 위치를 결정합니다.
CWebApplication::catchAllRequest를 지정하면 이 속성을 기반으로 컨트롤러가 생성되며 사용자가 지정한 컨트롤러 ID는 무시됩니다. 일반적으로 애플리케이션을 유지 관리 상태로 설정하고 정적 프롬프트 페이지를 표시하는 데 사용됩니다.
CWebApplication::controllerMap에서 ID를 찾으면 해당 컨트롤러 구성을 사용하여 컨트롤러 인스턴스를 생성합니다.
ID가 'path/to/xyz' 형식인 경우 컨트롤러 클래스 이름이 XyzController로 판단되어 해당 클래스 파일이 보호됩니다/ 컨트롤러/경로/to/XyzController .php. 예를 들어 컨트롤러 ID admin/user는 컨트롤러 클래스 UserController로 확인되고 클래스 파일은 protected/controllers/admin/UserController.php입니다. 클래스 파일이 없으면 404 CHttpException이 트리거됩니다.
모듈(1.0.3 버전 이후 사용 가능)을 사용한 후에는 위의 과정이 약간 다릅니다. 특히 애플리케이션은 이 ID가 모듈의 컨트롤러를 나타내는지 여부를 확인합니다. 그렇다면 모듈 인스턴스가 먼저 생성된 후 모듈 내의 컨트롤러 인스턴스 가 생성됩니다.
위에서 언급했듯이 액션은 접두사로 액션을 붙인 메소드로 정의할 수 있습니다. 더 발전된 방법은 액션 클래스를 정의하고 컨트롤러가 요청을 받을 때 이를 인스턴스화하도록 하는 것입니다. 이를 통해 작업을 재사용할 수 있어 재사용성이 향상됩니다.
새 액션 클래스를 정의하려면 다음 코드를 사용하세요.
class UpdateAction extends CAction { public function run() { // place the action logic here } }
컨트롤러의 클래스를 가져오려면 attention 이 작업에 도달하려면 다음과 같은 방법으로 컨트롤러 클래스의 actions() 메서드를 재정의해야 합니다.
class PostController extends CController { public function actions() { return array( 'edit'=>'application.controllers.post.UpdateAction', ); } }
위에 표시된 대로, 경로 별칭 application.controllers.post.UpdateAction을 사용하여 액션 클래스 파일을 protected/controllers/post/UpdateAction.php로 지정했습니다.
클래스 기반 액션을 작성하여 다음을 수행할 수 있습니다. 애플리케이션을 모듈 스타일로 구성합니다. 예를 들어, 다음 디렉토리 구조를 사용하여 컨트롤러 관련 코드를 구성할 수 있습니다:
protected/ controllers/ PostController.php UserController.php post/ CreateAction.php ReadAction.php UpdateAction.php user/ CreateAction.php ListAction.php ProfileAction.php UpdateAction.php
액션 매개변수 바인딩
从版本 1.1.4 开始,Yii 提供了对自动动作参数绑定的支持。 就是说,控制器动作可以定义命名的参数,参数的值将由 Yii 自动从 $_GET 填充。
为了详细说明此功能,假设我们需要为 PostController 写一个 create 动作。此动作需要两个参数:
category: 一个整数,代表帖子(post)要发表在的那个分类的ID。
language: 一个字符串,代表帖子所使用的语言代码。
从 $_GET 中提取参数时,我们可以不再下面这种无聊的代码了:
class PostController extends CController { public function actionCreate() { if(isset($_GET['category'])) $category=(int)$_GET['category']; else throw new CHttpException(404,'invalid request'); if(isset($_GET['language'])) $language=$_GET['language']; else $language='en'; // ... fun code starts here ... } }
现在使用动作参数功能,我们可以更轻松的完成任务:
class PostController extends CController { public function actionCreate($category, $language='en') { $category=(int)$category; // ... fun code starts here ... } }
注意我们在动作方法 actionCreate 中添加了两个参数。 这些参数的名字必须和我们想要从 $_GET 中提取的名字一致。 当用户没有在请求中指定 $language 参数时,这个参数会使用默认值 en 。 由于 $category 没有默认值,如果用户没有在 $_GET 中提供 category 参数, 将会自动抛出一个 CHttpException (错误代码 400) 异常。从版本1.1.5开始, Yii还支持数组类型的动作参数绑定。 这是通过PHP的类型约束来实现的,语法如下:
class PostController extends CController { public function actionCreate(array $categories) { // Yii will make sure $categories be an array } }
也就是说我们在方法参数声明里的$categories之前添加了array关键字。这样的话,如果$_GET['categories']只是一个简单的字符串,它将会被转化为一个包含该字符串的数组。
注意: 如果参数声明没有加上 array 类型约束, 意味着参数必须是标量 (i.e., not an array)。这种情况下,通过 $_GET 传入一个数组参数将会引发HTTP异常。
过滤器是一段代码,可被配置在控制器动作执行之前或之后执行。例如, 访问控制过滤器将被执行以确保在执行请求的动作之前用户已通过身份验证;性能过滤器可用于测量控制器执行所用的时间。
一个动作可以有多个过滤器。过滤器执行顺序为它们出现在过滤器列表中的顺序。过滤器可以阻止动作及后面其他过滤器的执行
过滤器可以定义为一个控制器类的方法。方法名必须以 filter 开头。例如,现有的 filterAccessControl 方法定义了一个名为 accessControl 的过滤器。 过滤器方法必须为如下结构:
public function filterAccessControl($filterChain) { // 调用 $filterChain->run() 以继续后续过滤器与动作的执行。 }
其中的 $filterChain (过滤器链)是一个 CFilterChain 的实例,代表与所请求动作相关的过滤器列表。在过滤器方法中, 我们可以调用 $filterChain->run() 以继续执行后续过滤器和动作。
过滤器也可以是一个 CFilter 或其子类的实例。如下代码定义了一个新的过滤器类:
class PerformanceFilter extends CFilter { protected function preFilter($filterChain) { // 动作被执行之前应用的逻辑 return true; // 如果动作不应被执行,此处返回 false } protected function postFilter($filterChain) { // 动作执行之后应用的逻辑 } }
要对动作应用过滤器,我们需要覆盖 CController::filters() 方法。此方法应返回一个过滤器配置数组。例如:
class PostController extends CController { ...... public function filters() { return array( 'postOnly + edit, create', array( 'application.filters.PerformanceFilter - edit, create', 'unit'=>'second', ), ); } }
上述代码指定了两个过滤器: postOnly 和 PerformanceFilter。 postOnly 过滤器是基于方法的(相应的过滤器方法已在 CController 中定义); 而 performanceFilter 过滤器是基于对象的。路径别名application.filters.PerformanceFilter 指定过滤器类文件是protected/filters/PerformanceFilter。我们使用一个数组配置 PerformanceFilter ,这样它就可被用于初始化过滤器对象的属性值。此处 PerformanceFilter 的 unit 属性值将被初始为 second。
使用加减号,我们可指定哪些动作应该或不应该应用过滤器。上述代码中, postOnly 应只被应用于 edit 和 create动作,而 PerformanceFilter 应被应用于 除了 edit 和 create 之外的动作。 如果过滤器配置中没有使用加减号,则此过滤器将被应用于所有动作。
附图:控制器的run方法执行过程
以上就是Yii框架官方指南系列7——基础知识:控制器的内容,更多相关内容请关注PHP中文网(www.php.cn)!