컨트롤러 Controllers

컨트롤러는 여러분 프로그램의 핵심이라 할 수 있습니다. 왜냐하면 Http 요청을 어떻게 처리할지 결정하기 때문입니다.

컨트롤러란 무엇인가? What is a Controller?

간단하게 말하면 컨트롤러는 URL과 상호작용하는 클래스 파일이라고 할 수 있습니다.

아래 URI를 보세요:

example.com/index.php/blog/

위 예제에서 CodeIgniter 는 Blog.php 라는 파일을 Controller 로서 찾은후 로드 합니다.

컨트롤러의 이름이 URI 의 첫 번째 새그먼트와 동일하다면 해당 컨트롤러는 자동적으로 로드될것입니다.

해 봅시다: Hello World!

간단한 컨트롤러를 생성해보고, 어떻게 행동하는지 봐봅시다. 텍스트에디터를 통해 Blog.php 라는 파일 하나를 생성하시고, 아래 코드를 입력해보세요:

<?php
class Blog extends CI_Controller {

        public function index()
        {
                echo 'Hello World!';
        }
}

그다음에 application/controllers/ 디렉토리에 저장하세요.

Important

The file must be called ‘Blog.php’, with a capital ‘B’.

자 이제 아래예 처럼 브라우저에서 접속보세요:

example.com/index.php/blog/

정상적으로 하셨다면, 아래를볼 수 있습니다:

Hello World!

Important

클래스명은 반드시 대문자로 시작되어야 합니다.

아래의 예제는 맞습니다:

<?php
class Blog extends CI_Controller {

}

아래의 예제는 틀렸습니다:

<?php
class blog extends CI_Controller {

}

또하 항상 만드신 컨트롤러는 부모 컨트롤러부터 상속 받아야 합니다.

함수들 Methods

위 예제에서 함수이름은 index() 였습니다. “index” 함수는 URI 에서 두 번째 새그먼트가 전달되지않을 때 기본으로 실행됩니다. 아래와 같은 방법으로도 위 예제와 같이 “Hello World” 를 화면에 뿌릴 수 있습니다 :

example.com/index.php/blog/index/

URI 의 두 번째 새그먼트는 컨트롤러 내의 어떤함수가 실행될지를 결정합니다.

따라해보세요. 새로운 함수를 컨트롤러에 추가합니다:

<?php
class Blog extends CI_Controller {

        public function index()
        {
                echo 'Hello World!';
        }

        public function comments()
        {
                echo 'Look at this!';
        }
}

아래 URL로 접속하여 comment 함수를 실행시켜봅시다:

example.com/index.php/blog/comments/

새로운 메세지를 보실 수 있습니다.

URI Segments를 함수에 전달하기 Passing URI Segments to your methods

URI 가 2개보다 많은 새그먼트를 포함하고있다면 나머지들은 파라미터로 함수에 전달됩니다.

예를 들어 다음의 URL 이라면:

example.com/index.php/products/shoes/sandals/123

함수는 새그먼트 3번과 4번(“sandals” 그리고 “123”)을 파라미터로 전달받게 됩니다 :

<?php
class Products extends CI_Controller {

        public function shoes($sandals, $id)
        {
                echo $sandals;
                echo $id;
        }
}

Important

만약 URI 라우팅(Routing) 을 사용하고있다면, 함수에전달된 새그먼트는 재 라우팅된 새그먼트 일것입니다.

기본 Controller정의 Defining a Default Controller

새그먼트 없이 사이트의 루트 url 만 요청될 때 실행될 기본 컨트롤러를 지정할 수 있습니다. 기본 컨트롤러를 지정하려면 application/config/routes.php 파일의 아래 변수에 세팅합니다:

$route['default_controller'] = 'Blog';

위와 같이 Blog를 기본 컨트롤러로 지정하면 루트 url 이 요청되었을 때 이제는 Hello World를 보실 수 있을 것입니다.

함수요청을 재매핑 하기 Remapping Method Calls

위에서 설명한 것처럼, 일반적으로 URI 의 두 번째 새그먼트는 컨트롤러내의 어떤 함수를 실행할 것인가를 결정합니다. 이런 일반루틴을 재정의하여 원하는 액션으로 바꿀 수 있습니다. 그러려면 _remap() 함수를 사용합니다:

public function _remap()
{
        // Some code here...
}

Important

만약 컨트롤러가 _remap()함수를 포함하고이다면, URI가 어떻든 간에 _remap() 함수를 호출하게될것입니다.왜냐하면 _remap()은 CI 가 정의해 놓은 일반루틴 대신 여러분 자신만의 라우팅방법으로 재정의 해버리기 때문입니다.

재정의된 함수 호출(일반적으로 URI의 두 번째 새그먼트)은 함수명이 _remap() 의 파라미터로 전달됩니다:

public function _remap($method)
{
        if ($method === 'some_method')
        {
                $this->$method();
        }
        else
        {
                $this->default_method();
        }
}

_remap() 함수로 넘기는 함수 이름 외의 파라미터는 모두 옵션입니다. 이 배열은 PHP의 call_user_func_array() 와 결합하여, CodeIgniter의 기본 동작처럼 작동합니다.

예제:

public function _remap($method, $params = array())
{
        $method = 'process_'.$method;
        if (method_exists($this, $method))
        {
                return call_user_func_array(array($this, $method), $params);
        }
        show_404();
}

출력데이터 조절 Processing Output

CodeIgniter 는 최종적으로 렌더링되어 자동적으로 브라우저에 데이터를 전송해주는 출력클래스를 가지고있습니다. 뷰(Views)출력클래스(Output Class) 페이지에서 보다 자세한 정보를 보실 수 있습니다. 그러나 어떤경우에는 최종적으로 데이터가 브라우저로 보내지기전에 뭔가 전처리를 해야할 때도 있을 것입니다. 그것은 컨트롤러에 _output() 함수를 추가하는 것으로 가능합니다.

Important

컨트롤러가 _output() 라는 함수를 가지고있다면 최종 데이터를 바로 전송하는 것 대신 그 함수가 실행될 것입니다. 함수의 첫 번째 파라미터는 최종 출력 데이터를 가지고 있습니다.

예제:

public function _output($output)
{
        echo $output;
}

Note

_output() 는 최종데이터를 받습니다. 최종데이터가 _output()에 전달되기전에 벤치마크 및 메모리사용 데이터는 렌더링될것이고,캐시작성이 활성 상태라면 캐시 파일도 작성되며, feature 항목을 사용한다면 헤더 정보도 보내질 것입니다. 컨트롤러가 출력캐시를 정상적으로 보내게 하려면, _output() 함수를 아래와 같이 사용하세요.

if ($this->output->cache_expiration > 0)
{
        $this->output->_write_cache($output);
}

그런데 이 함수를 사용한다면 페이지 실행시간 및 메모리 사용 상태 정보는 정확하지 않을 수 있습니다. 왜냐하면 그러한 정보들은 당신이 _output() 에서 처리할 내용이 어떤 것인지 계산에 넣고 있지 않기 때문입니다. 출력을 조절하는 다른 방법은 출력라이브러리(Output Library) 항목에서 찾아보세요..

Private 함수 Private methods

때에 따라서 함수의 공개적 접근을 허용해서는 안 될 경우도 있을 것입니다. 함수를 private 으로 만들려면, 간단히 밑줄(_)을 함수 이름 앞에 추가해 주세요. 그러면 웹에서 호출할 수 없게 됩니다:

private function _utility()
{
        // some code
}

아래와 같이 접근하려해도 작동하지않을것입니다:

example.com/index.php/blog/_utility/

Note

언더바가 프리픽스로 포함된 함수이름을 호출하는 것도 방지할 수 있습니다. 이것은 이전 버전과의 호환성을 위해 남아있는 레거시 기능입니다.

컨트롤러들을 하위 폴더로 구성하기 Organizing Your Controllers into Sub-directories

대형 사이트를 만든다면 아마도 컨트롤러를 하위 폴더로 구성하는 것이 더 나을것입니다.

application/controllers/ 아래에 디렉토리를 만든다음 컨트롤러 클래스들을 그 안에 넣으세요.

Note

이런 식으로 사용하는 경우에 URI 첫 번째 새그먼트는 반드시 디렉토리명이라야 합니다. 예를 들어, 여러분의 컨트롤러 위치가 아래와 같다면:

application/controllers/products/Shoes.php

위의 컨트롤러를 호출하기 위해서는 아래와 같은 URI를 사용해야 합니다:

example.com/index.php/products/shoes/show/123

각각의 하위 폴더는 URL 에서 하위 폴더만을 호출할 때를 대비하여 기본 컨트롤러를 가지고 있어야 할 것입니다. 간단히 기본컨트롤러를 application/config/routes.php 파일에 설정하시면 됩니다.

또한 CodeIgniter 는 URI 를 URI라우팅( Routing) 기능을 이용하여 재 매핑할 수 있도록 지원하고 있습니다.

클래스 생성자 Class Constructors

컨트롤러에서 생성자를 사용하고자 한다면 생성자아래 반드시 아래의 코드가 들어있어야 합니다:

parent::__construct();

그렇지않으면 여러분이 만든 생성자가 부모 controller 의 생성자를 재정의 해버리기 때문입니다. 그러므로 반드시 위와 같이 부모 controller 를 수동으로 호출해 주어야 합니다.

예제:

<?php
class Blog extends CI_Controller {

        public function __construct()
        {
                parent::__construct();
                // Your own constructor code
        }
}

생성자는 클래스가 초기화될 때 어떤 기본값들을 설정해야 한다거나 어떤 프로세스를 수행해야할 때 유용합니다. 생성자는 리턴값이 있어서는 안됩니다.

예약된 함수명 Reserved method names

여러분의 컨트롤러는 부모클래스로부터 상속받아 작성되기 때문에 부모클래스에서 사용하는 함수이름을 사용하지않도록 주의해야 합니다. 그렇지않으면 부모클래스의 함수를 재정의 해버리기 때문에 오작동 합니다. 예약어 전체 목록을 확인하세요.

Important

또한 클래스명과 똑같은 함수명을 가질 수 없습니다. 그리고 같은 클래스에 __construct() 가 없다면 Index::index() 함수가 생성자로 실행될 것입니다. 이것은 PHP4 와의 호환성 때문입니다.

이것이 전부입니다!

이것이 컨트롤러에 관해 알아야 할 전부입니다.