컨트롤러

컨트롤러는 HTTP 요청이 처리되는 방식을 결정하므로 애플리케이션의 핵심입니다.

컨트롤러란 무엇인가?

컨트롤러는 URI와 연관될 수 있는 방식으로 이름이 지정된 단순한 클래스 파일입니다.

다음 URI를 살펴보세요:

example.com/index.php/blog/

위 예시에서 CodeIgniter는 Blog.php라는 컨트롤러를 찾아 로드합니다.

컨트롤러의 이름이 URI의 첫 번째 세그먼트와 일치하면 로드됩니다.

시작해봅시다: Hello World!

간단한 컨트롤러를 만들어 실제 작동을 확인해 봅시다. 텍스트 편집기를 사용하여 Blog.php라는 파일을 만들고 다음 코드를 넣으세요:

<?php
class Blog extends CI_Controller {

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

그런 다음 application/controllers/ 디렉터리에 파일을 저장하세요.

중요

파일 이름은 대문자 ‘B’를 사용하여 ‘Blog.php’로 지정해야 합니다.

이제 다음과 유사한 URL을 사용하여 사이트를 방문하세요:

example.com/index.php/blog/

올바르게 했다면 다음을 볼 수 있습니다:

Hello World!

중요

클래스 이름은 반드시 대문자로 시작해야 합니다.

다음은 유효합니다:

<?php
class Blog extends CI_Controller {

}

다음은 유효하지 않습니다:

<?php
class blog extends CI_Controller {

}

또한 컨트롤러가 모든 메소드를 상속할 수 있도록 항상 부모 컨트롤러 클래스를 확장해야 합니다.

메소드

위의 예시에서 메소드 이름은 index() 입니다. URI의 두 번째 세그먼트가 비어 있으면 “index” 메소드가 항상 기본으로 로드됩니다. “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을 로드하여 comments 메소드를 확인하세요:

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

새 메시지를 볼 수 있을 것입니다.

URI 세그먼트를 메소드에 전달

URI에 두 개 이상의 세그먼트가 있으면 매개변수로 메소드에 전달됩니다.

예를 들어, 다음과 같은 URI가 있다고 가정해 봅시다:

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

메소드에 URI 세그먼트 3과 4(“sandals”와 “123”)가 전달됩니다:

<?php
class Products extends CI_Controller {

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

중요

URI 라우팅 기능을 사용하는 경우, 메소드에 전달되는 세그먼트는 재라우팅된 것입니다.

기본 컨트롤러 정의

URI가 없을 때, 즉 사이트의 루트 URL만 요청될 때 기본 컨트롤러를 로드하도록 CodeIgniter에 지시할 수 있습니다. 기본 컨트롤러를 지정하려면 application/config/routes.php 파일을 열고 다음 변수를 설정하세요:

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

‘blog’는 사용하려는 컨트롤러 클래스의 이름입니다. 이제 URI 세그먼트를 지정하지 않고 메인 index.php 파일을 로드하면 기본적으로 “Hello World” 메시지가 표시됩니다.

자세한 내용은 URI 라우팅 문서의 “예약된 라우트” 섹션을 참조하세요.

메소드 호출 리맵핑

위에서 언급한 바와 같이 URI의 두 번째 세그먼트는 일반적으로 컨트롤러에서 호출될 메소드를 결정합니다. CodeIgniter는 _remap() 메소드를 사용하여 이 동작을 재정의할 수 있습니다:

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

중요

컨트롤러에 _remap()이라는 메소드가 포함되어 있으면 URI에 관계없이 항상 호출됩니다. URI가 어떤 메소드를 호출할지 결정하는 일반적인 동작을 재정의하여 자신만의 메소드 라우팅 규칙을 정의할 수 있습니다.

재정의된 메소드 호출(일반적으로 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();
}

출력 처리

CodeIgniter에는 최종 렌더링된 데이터를 자동으로 웹 브라우저에 전송하는 출력 클래스가 있습니다. 자세한 내용은 Output 클래스 페이지에서 확인할 수 있습니다. 하지만 경우에 따라 최종 데이터를 후처리하여 직접 브라우저에 전송하고 싶을 수 있습니다. CodeIgniter는 최종 출력 데이터를 받는 _output() 메소드를 컨트롤러에 추가할 수 있습니다.

중요

컨트롤러에 _output() 이라는 메소드가 포함되어 있으면 최종 데이터를 직접 에코하는 대신 출력 클래스에 의해 항상 호출됩니다. 메소드의 첫 번째 매개변수에 최종 출력이 포함됩니다.

다음은 예시입니다:

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

참고

_output() 메소드는 데이터를 최종 상태로 받는다는 점을 유의하세요. 벤치마크 및 메모리 사용량 데이터가 렌더링되고, 캐시 파일이 작성되며(캐싱이 활성화된 경우), 헤더가 전송된 후(해당 기능 을 사용하는 경우) _output() 메소드에 전달됩니다. 컨트롤러의 출력이 올바르게 캐시되려면 _output() 메소드에서 다음을 사용할 수 있습니다:

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

이 기능을 사용하면 추가 처리를 고려하지 않으므로 페이지 실행 타이머와 메모리 사용량 통계가 완벽하게 정확하지 않을 수 있습니다. 최종 처리가 완료되기 전에 출력을 제어하는 대안적인 방법은 Output 라이브러리 의 사용 가능한 메소드를 참조하세요.

프라이빗 메소드

경우에 따라 특정 메소드를 공개 접근에서 숨기고 싶을 수 있습니다. 이를 위해 메소드를 private 또는 protected로 선언하면 URL 요청으로 제공되지 않습니다. 예를 들어 다음과 같은 메소드가 있다면:

private function _utility()
{
        // some code
}

URL을 통해 접근하려고 시도하면 작동하지 않습니다:

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

참고

밑줄로 시작하는 메소드 이름도 호출되지 않습니다. 이는 하위 호환성을 위해 남겨진 레거시 기능입니다.

컨트롤러를 서브 디렉터리로 구성

대규모 애플리케이션을 구축하는 경우 컨트롤러를 서브 디렉터리로 계층적으로 구성하거나 구조화할 수 있습니다. CodeIgniter에서는 이것이 가능합니다.

메인 application/controllers/ 아래에 서브 디렉터리를 만들고 그 안에 컨트롤러 클래스를 배치하세요.

참고

이 기능을 사용할 때 URI의 첫 번째 세그먼트는 폴더를 지정해야 합니다. 예를 들어 여기에 컨트롤러가 있다고 가정해 봅시다:

application/controllers/products/Shoes.php

위의 컨트롤러를 호출하는 URI는 다음과 같습니다:

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

각 서브 디렉터리에는 application/config/routes.php 파일에 지정된 ‘default_controller’ 이름과 일치하는 컨트롤러가 URL에 서브 디렉터리만 포함된 경우 호출될 기본 컨트롤러를 포함할 수 있습니다.

CodeIgniter는 URI 라우팅 기능을 사용하여 URI를 다시 매핑할 수 있습니다.

클래스 생성자

컨트롤러에서 생성자를 사용하려면 다음 코드를 반드시 넣어야 합니다:

parent::__construct();

이 코드가 필요한 이유는 로컬 생성자가 부모 컨트롤러 클래스의 생성자를 재정의하므로 수동으로 호출해야 하기 때문입니다.

예시:

<?php
class Blog extends CI_Controller {

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

생성자는 일부 기본값을 설정하거나 클래스가 인스턴스화될 때 기본 프로세스를 실행하는 데 유용합니다. 생성자는 값을 반환할 수 없지만 기본 작업을 수행할 수 있습니다.

예약된 메소드 이름

컨트롤러 클래스는 메인 애플리케이션 컨트롤러를 확장하므로 해당 클래스에서 사용하는 메소드와 동일한 이름을 사용하지 않도록 주의해야 합니다. 그렇지 않으면 로컬 함수가 해당 메소드를 재정의합니다. 전체 목록은 예약된 이름 을 참조하세요.

중요

클래스와 동일한 이름을 가진 메소드는 절대 사용하지 마세요. 그렇게 하고 같은 클래스에 __construct() 메소드가 없으면 예를 들어 Index::index() 메소드가 클래스 생성자로 실행됩니다! 이는 PHP4 하위 호환성 기능입니다.

끝!

간단히 말하면, 이것이 컨트롤러에 대해 알아야 할 전부입니다.