본문 바로가기

Yii Framework/Guide to Yii 1.0

08. 컨트롤러

컨트롤러 

컨트롤러 는 CController 하거나 CController 를 확장 한 클래스의 인스턴스입니다. 컨트롤러는 사용자가 요청하면 응용 프로그램 객체에 의해 생성됩니다. 컨트롤러는 시작되면 요청 된 작업을 수행하는 데 일반적으로 필요한 모델을 가져와 적절한 뷰를 표시합니다. 액션 은 가장 단순화 된 형태로, 컨트롤러 클래스의 action 로 시작하는 방법입니다.

컨트롤러는 기본 동작 (기본 동작)을 가지고 있습니다. 어떤 작업을 수행하는지 사용자가 지정하지 않으면, 기본 동작이 실행됩니다. 기본적으로 기본 작업 이름은 index 입니다. 이것은 인스턴스의 공용 변수 CController :: defaultAction 설정을 변경할 수 있습니다.

다음 코드는 site 컨트롤러와 index 액션 (기본 동작)와 contact 작업을 정의합니다.

class  SiteController  extends  CController { 
    public  Function  actionIndex ( ) 
    { 
        / / ... 
    }
 
    public  Function  actionContact ( ) 
    { 
        / / ... 
    } }

1. 루트 (경로) 

컨트롤러와 액션은 ID로 식별됩니다. 컨트롤러 ID는 path / to / xyz 형식으로 컨트롤러 클래스 파일protected / controllers / path / to / XyzController.php 에 대응합니다. xyz 를 실제 이름으로 대체 생각하십시오. 예 post 는 protected / controllers / PostController.php 에 해당합니다.) 또한 작업 ID는 액션 메소드 이름에서 접두사 action 을 제외한 것입니다. 예를 들어, 컨트롤러 클래스 actionEdit 라는 메소드가 있으면 작업 ID는 edit 됩니다.

사용자는 루트 (경로)은 특정 컨트롤러와 액션을 요청합니다. 루트는 슬래시는 컨트롤러 ID와 액션 ID를 연결하여 형성됩니다. 예를 들어, 루트 post / edit 는 PostController 의 edit 액션을 참조합니다. 그리고 기본적으로http://hostname/index.php?r=post/edit 라는 URL이 post 컨트롤러와 edit 액션을 요청하는 것입니다.

주의 : 기본적으로 루트는 대소 문자를 구분합니다. 응용 프로그램 초기 구성에서 CUrlManager :: caseSensitive 을 false로 설정하면 대소 문자를 구분하지 않도록 할 수 있습니다. 대소 문자를 구별하지 않는 모드 (case-insensitive mode)의 경우는 컨트롤러 클래스 파일을 포함한 디렉토리 이름이 소문자임을, 또한 controller map 과 action map 모두 키가 소문자임을는 약관을 반드시 지켜주세요.

응용 프로그램 모듈 을 포함 할 수 있습니다. 모듈의 컨트롤러의 액션은 moduleID / controllerID / actionID 형식으로 표시됩니다. 더 자세한 정보는 모듈 의 장을 봐.

2. 컨트롤러의 인스턴스 

컨트롤러의 인스턴스는 CWebApplication 가 들어온 요청을 처리 할 때 생성됩니다. 컨트롤러 ID가 부여되면 응용 프로그램은 다음의 규칙을 사용하여 컨트롤러 클래스와 클래스 파일을 찾습니다.

  • CWebApplication :: catchAllRequest 가 지정되어있는 경우, 컨트롤러는이 속성을 바탕으로 생성되며 사용자 지정된 컨트롤러 ID는 무시됩니다. 이것은 주로 응용 프로그램을 유지 관리 모드로 알림을위한 정적 페이지를 표시하는 데 사용합니다.

  • ID가 CWebApplication :: controllerMap 에 지정되어있는 경우 해당 컨트롤러 설정에 따라 컨트롤러 인스턴스가 생성됩니다.

  • ID가 'path / to / xyz' 형식의 경우, 컨트롤러 클래스 이름은 XyzController 에서 해당 클래스 파일은protected / controllers / path / to / XyzController.php 이라고 가정됩니다. 예를 들어, 컨트롤러 ID가 admin / user 라면, 컨트롤러 클래스 이름이 UserController 에서 클래스 파일이 protected / controllers / admin / UserController.php 됩니다. 만약 클래스 파일이 없으면 404CHttpException 를 호출합니다.

모듈 이 사용되는 경우에는 위의 과정은 약간 다릅니다. 구체적으로는 응용 프로그램 ID가 모듈의 컨트롤러를 참조하고 있는지를 확인하고 만약 그렇다면, 모듈 인스턴스가 처음 생성 된 컨트롤러 인스턴스가 다음 생성됩니다.

3. 액션 

앞서 언급했듯이, 액션은 action 에서 시작하는 이름의 메소드에 의해 정의 할 수 있습니다. 더 진보 된 방법은 액션 클래스를 정의하고 요청시 인스턴스화하도록 컨트롤러에 요청하는 방법입니다. 이 방법을 이용함으로써, 작업의 재사용이 가능하기 때문에보다 재사용 성을 높일 수 있습니다.

새로운 액션 클래스를 정의하기 위해서는 다음과 같이합니다 :

class  UpdateAction  extends  CAction { 
    public  Function  run ( ) 
    { 
        / / 여기에 액션 논리를 작성 
    } }

컨트롤러가이 작업을 인식하도록이 컨트롤러 클래스의 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에서 자동 작업 매개 변수 결합이 지원되었습니다. 이것은 컨트롤러 액션 메서드에서 명명 된 매개 변수를 정의하고 그 값이 자동으로 $ _GET에서 할당되는 것입니다.

이것이 어떻게 작동하는지 설명하기 위해 PostController 컨트롤러 create 액션을 기술하는 것을 생각해 봅시다. 이 작업은 두 파라미터를 필요로합니다.

  • category : 카테고리 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 ' ;
 
        / / ... 재미있는 코드는 여기에서 시작 ... 
    } }

그런데, 액션 매개 변수 기능을 사용하면 작업이 더 재미 있습니다.

class  PostController  extends  CController { 
    public  Function  actionCreate ( $ category , $ language = ' en ' ) 
    { 
        $ category = ( int ) $ category ;
 
        / / ... 재미있는 코드는 여기에서 시작 ... 
    } }

두 매개 변수를 액션 메소드 actionCreate 에 추가 한 것에주의하십시오. 매개 변수 이름은 $ _GET 에서 얻은 매개 변수와 동일하게해야합니다. $ language 매개 변수는 요청이 그러한 매개 변수를 포함하지 않는 경우, 기본값 en 를 취합니다. 한편 $ category 는 기본값이 없기 때문에 요구가 category 매개 변수를 포함하지 않는 경우, CHttpException (error code 400) 오류가 자동으로 발급됩니다.

버전 1.1.5에서 배열 타입의 액션 매개 변수를 지원합니다. 이것은 PHP의 타입 힌팅을 이용하고 있으며, 다음과 같은 문법을 통해 이루어집니다.

class  PostController  extends  CController { 
    public  Function  actionCreate ( array  $ categories ) 
    { 
        / / Yii는 반드시 $ categories를 배열합니다 
    } }

즉, 메소드의 매개 변수 선언에서 $ categories 앞에 array 키워드를 놓습니다. 이렇게하면, $ _GET [ 'categories'] 가 단순한 문자열이면 해당 문자열의 배열로 변환됩니다.

주의 : 만약 매개 변수가 array 타입 힌트없이 선언 된 경우 해당 매개 변수는 스칼라 (배열이 아닌)이 아니면 안됩니다. 이 경우, $ _GET 에서 배열 매개 변수가 전달되면 HTTP 예외가 발생합니다.

버전 1.1.7에서는 자동 매개 결합은 클래스 기반의 작업에도 적용됩니다. 만약 액션 클래스 run () 메소드가 매개 변수와 함께 정의 된 경우, 그 매개 변수는 해당 이름의 요청 매개 변수가 할당됩니다. 예를 들어,

class  UpdateAction  extends  CAction { 
    public  Function  run ( $ id ) 
    { 
        / / $ id는 $ _GET [ 'id']가 할당되는 
    } }

4. 필터 

필터는 컨트롤러의 액션 실행 전이나 후에 (또는 둘 다)에 실행되도록 구성되는 코드 조각입니다. 예를 들어, 액세스 제어 필터는 사용자가 요청한 작업을 수행하기 전에 인증 된 것을 보장하기 위해 사용 될지도 모릅니다. 성능 필터는 작업의 실행 시간을 측정하는 데 사용되는지도 모릅니다.

하나의 작업은 여러 필터를 가질 수 있습니다. 필터는 필터 목록에 등장하는 순서대로 실행됩니다. 필터는 액션과 나머지 실행되지 않은 필터의 실행을 방지 할 수 있습니다.

필터는 컨트롤러 클래스 메소드로 정의 할 수 있습니다. 메소드 명은 반드시 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 작업을 제외한 모든 작업에 적용됩니다. 만약, 플러스와 마이너스가 모두 사용되지 않은 경우, 필터는 모든 작업에 적용됩니다.