글검색결과 [zend framework] : 38 개
- 2007/04/11 7.7. 규정된 모듈러 디렉토리 구조의 사용
- 2007/04/11 7.6. 플러그인
- 2007/04/06 7.5. 액션 컨트롤러
- 2007/04/05 7.4. 제공되는 서브 클래스군
- 2007/03/29 7.3. 서브 클래스화
- 2007/03/27 7.2. 시작하기
- 2007/03/27 7.1. Zend_Controller 빠른 시작
- 2007/03/20 6.4. Zend_Console_Getopt의 설정
- 2007/03/20 6.3. 옵션 및 인수의 취득
- 2007/03/19 6.2. Getopt 규칙의 선언
7.7. 규정된 모듈러 디렉토리 구조의 사용
Zend Framework/7. Zend_Controller | 2007/04/11 23:57
7.7.1. 소개
규정된 모듈러 디렉토리 구조(The Conventional Modular directory structure)에 의해, 다양한 MVC 애플리케이션을 독립적인 단위로 정리할 수 있습니다. 또, 그것을 다양한 프론트 컨트롤러로 재사용할 수 있게 됩니다. 이 디렉토리 구조는 다음과 같이 됩니다.
docroot/
index.php
application/
controllers/
IndexController.php
FooController.php
blog/
controllers/
IndexController.php
models/
views/
news/
controllers/
IndexController.php
ListController.php
models/
views/
이 패러다임에서는 모듈명이 컨트롤러의 접두사로써 사용됩니다. 위의 예는 세 개의 모듈 컨트롤러 'Blog_IndexController', 'News_IndexController' 및 'News_ListController'를 포함하고 있습니다. 또한, 두 개의 글로벌 컨트롤러 'IndexController'와 'FooController'도 정의되어 있습니다. 이들은 네임스페이스에 속하지 않습니다. 이 디렉토리 구조는 이 장에서 예제를 위해 사용됩니다.
그러면, Zend Framework의 MVC 컴포넌트를 사용해 이러한 디렉토리 배치를 구현하려면 어떻게 하면 좋을까요?
7.7.2. 모듈 컨트롤러 디렉토리의 지정
모듈을 사용하기 위해 먼저, 프론트 컨트롤러에서 컨트롤러 디렉토리 목록의 설정 방법을 변경하는 것입니다. 기본적인 MVC계열에서는, setControllerDirectory()로 배열이나 문자열을 넘기거나, 또는 addControllerDirectory()로 경로를 넘겨주고 있었습니다. 모듈을 사용할 때는, 이러한 메소드 호출을 살짝 변경할 필요가 있습니다.
setControllerDirectory()에서는 연관 배열을 넘겨 줄 필요가 있습니다. 연관 배열의 키에는 모듈명, 그 값에는 디렉토리의 경로를 지정합니다. 특별한 키 'default'는 글로벌 콘트롤러(모듈 네임스페이스를 필요로 하지 않는 것)를 사용할 것입니다. 모든 엔트리는, 단일 경로를 가리키는 문자열 키를 포함해야만 합니다. 다음의 예와 같습니다.
$front->setControllerDirectory(array(
'default' => '/path/to/application/controllers',
'blog' => '/path/to/application/blog/controllers'
));
addControllerDirectory()에서는, 옵션의 두번째 인수를 받아들입니다. 모듈을 사용할 때, 두번째 인수로써 모듈명을 넘겨줍니다. 지정하지 않으면, 경로는 기본 네임스페이스에 추가됩니다. 다음의 예와 같습니다.
$front->addControllerDirectory('/path/to/application/news/controllers', 'news');
7.7.3. 모듈로 경로 지정
Zend_Controller_Router_Rewrite의 기본 경로는 Zend_Controller_Router_Route_Module형의 객체입니다. 이 경로는 다음의 경로 지정 스키마들 중 하나를 선택합니다.
:module/:controller/:action/*
:controller/:action/*
바꾸어 말하면, 그들 자신이나 접두어로 쓰인 모듈에 의해 컨트롤러와 액션을 일치시킵니다. 이 규칙은, 프론트 컨트롤러와 디스패처에게 넘겨진 컨트롤러 디렉토리 배열에서 동일한 이름의 키가 존재할 경우에만 모듈은 일치될 것이라는 것을 의미합니다.
7.7.4. 모듈 또는 글로벌 기본 컨트롤러
기본 라우터에서는, 컨트롤러가 URL에 지정되지 않았던 경우에는 기본 컨트롤러(특히 지정하지 않으면 IndexController)를 사용합니다. 모듈 컨트롤러를 가지고, 만약 모듈은 지정했지만 컨트롤러를 지정하지 않았으면, 디스패처는 먼저 모듈 경로내의 기본 컨트롤러를 찾습니다. 그리고나서, 글로벌 네임스페이스 'default'에 있는 기본 컨트롤러를 찾습니다.
만약 여러분이 글로벌 네임스페이스에 항상 default로 하고 싶으면, 프론트 컨트롤러에서 useGlobalDefault 매개변수를 지정합니다.
$front->setParam('useGlobalDefault', true);
7.6. 플러그인
Zend Framework/7. Zend_Controller | 2007/04/11 23:50
7.6.1. 소개
컨트롤러 구조는, 컨트롤러 처리 중에 어떤 이벤트가 발생할 때 사용자가 만든 코드를 호출할 수 있는, 플러그인 시스템을 포함하고 있습니다. 프론트 컨트롤러는, 플러그인 브로커에 사용자의 플러그인을 등록합니다. 그리고, 이벤트 메소드가 호출 되었을 때, 프론트 컨트롤러에 등록되어 있는 각 플러그인을 플러그인 브로커가 실행합니다.
이벤트 메소드는 추상 클래스 Zend_Controller_Plugin_Abstract로 정의되어 있습니다. 사용자 플러그인 클래스는 이것을 상속받습니다.
routeStartup()은 Zend_Controller_Front가 경로에 대한 요청(request)의 평가를 시작하기 전에 호출 됩니다.
routeShutdown()은 Zend_Controller_Front가 라우터로부터 빠져나올 때, Zend_Controller_Router가 종료한 후에 호출됩니다.
dispatchLoopStartup()은 Zend_Controller_Front가 디스패치 루프에 들어가기 전에 호출됩니다.
preDispatch()는 액션이 Zend_Controller_Dispatcher에 의해 디스패치 되기 전에 호출됩니다. 이 콜백은 프럭시나 필터 행동을 준비합니다. 요청(request)의 내용을 변경하고 디스패치 플래그를 리셋(Zend_Controller_Request_Abstract::setDispatched(false)를 사용합니다) 하는 것으로, 현재의 액션을 건너띄게 할 수 있습니다.
postDispatch()는 액션이 Zend_Controller_Dispatcher에 의해 디스패치 된 후에 호출됩니다. 이 콜백은 프럭시나 필터 행동을 준비합니다. 요청(request)의 내용을 변경하고 디스패치 플래그를 리셋(Zend_Controller_Request_Abstract::setDispatched(false)를 사용합니다), 새로운 액션을 디스패치 하도록 지정할 수 있습니다.
dispatchLoopShutdown()은 Zend_Controller_Front가 디스패치 루프를 종료하기 전에 호출됩니다.
7.6.2. 플러그인 쓰기
플러그인 클래스를 쓰려면, 단지 추상 클래스 Zend_Controller_Plugin_Abstract를 인클루드 해서 그것을 상속받으면 됩니다.
<?php
require_once 'Zend/Controller/Plugin/Abstract.php';
class MyPlugin extends Zend_Controller_Plugin_Abstract
{
// ...
}
Zend_Controller_Plugin_Abstract에는 추상 메소드는 없습니다. 즉, 위에 나타낸 이벤트 메소드를 플러그인 클래스에서 반드시 구현해야 하는 것은 아닙니다. 플러그인을 쓰는 사람이 필요한 것만을 선택해 구현할 수 있습니다.
또한, Zend_Controller_Plugin_Abstract는 getRequest() 메소드 및 getResponse() 메소드를 사용해서, 요청(request) 객체나 응답(response) 객체를 컨트롤러 플러그인에서 유용하게 사용할 수 있습니다.
7.6.3. 플러그인의 사용법
플러그인 클래스들은 디스패치 하기 전에 Zend_Controller_Front::registerPlugin()로 등록됩니다. 다음의 예는 컨트롤러 체인으로 플러그인을 사용하는 방법을 나타내는 것입니다.
<?php
require_once 'Zend/Controller/Front.php';
require_once 'Zend/Controller/Router.php';
require_once 'Zend/Controller/Plugin/Abstract.php';
class MyPlugin extends Zend_Controller_Plugin_Abstract
{
public function routeStartup()
{
$this->getResponse()->appendBody('<p>routeStartup() called</p>');
}
public function routeShutdown($request)
{
$this->getResponse()->appendBody('<p>routeShutdown() called</p>');
}
public function dispatchLoopStartup($request)
{
$this->getResponse()->appendBody('<p>dispatchLoopStartup() called</p>');
}
public function preDispatch($request)
{
$this->getResponse()->appendBody('<p>preDispatch() called</p>');
}
public function postDispatch($request)
{
$this->getResponse()->appendBody('<p>postDispatch() called</p>');
}
public function dispatchLoopShutdown()
{
$this->getResponse()->appendBody('<p>dispatchLoopShutdown() called</p>');
}
}
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('/path/to/controllers')
->setRouter(new Zend_Controller_Router())
->registerPlugin(new MyPlugin());
$response = $controller->dispatch();
echo $response;
7.5. 액션 컨트롤러
Zend Framework/7. Zend_Controller | 2007/04/06 23:55
7.5.1. 소개
Zend_Controller_Action은 모델 - 뷰 - 컨트롤러(MVC) 패턴에 의거한 웹애플리케이션을 개발할 때, 프론트 컨트롤러로 사용하는 액션 컨트롤러를 구현하기 위한 추상 클래스입니다.
Zend_Controller_Action를 사용하려면 , 실제 액션 컨트롤러내에 서브 클래스(또는 액션 컨트롤러를 위해 여러분 자신의 base 클래스를 생성하기 위한 서브 클래스)가 필요합니다. 가장 기본적인 운용은, 우선 서브 클래스를 생성하고, 여러분의 사이트에서 처리하고 싶은 다양한 액션에 대응하는 액션 메소드를 생성하는 것입니다. Zend_Controller의 경로 지정과 디스패치 처리는, 잠재적인 컨트롤러 액션으로써 여러분의 클래스 내에서 끝부분에 'Action'이라고 붙은 메소드를 자동으로 발견합니다.
예를 들어, 다음과 같이 정의된 클래스에 대해 얘기해 봅시다.
class FooController extends Zend_Controller_Action
{
public function barAction()
{
// 처리할 내용
}
public function bazAction()
{
// 처리할 내용
}
}
위의 FooController 클래스 ('foo' 컨트롤러)는 두 개의 액션, 'bar'와 'baz'를 정의하고 있습니다.
물론 이외에도 많은 기능이 있습니다. 예를 들어 커스텀 초기화 액션, 액션이 지정되지 않을 경우(혹은 무효인 액션을 지정했을 경우)에 호출되는 기본 액션, 디스패치의 전후에 실행되는 훅, 다양한 도움말 메소드 등이 있습니다. 이 장에서는 액션 컨트롤러 기능의 개요를 설명합니다.
7.5.2. 객체의 초기화
여러분은 항상 액션 컨트롤러의 생성자를 오버라이드(override) 할 수도 있지만, 이것을 추천하지 않습니다. Zend_Controller_Action::__construct()는, 요청(request) 객체나 응답(response) 객체를 등록하는 등의 중요한 작업을 실시합니다. 또한, 프론트 컨트롤러로부터 넘겨받은 커스텀 호출 인수들의 처리도 수행합니다. 만약 생성자를 오버라이드(override) 해야만 한다면, 반드시 parent::__construct($request, $response, $invokeArgs)를 호출하시기 바랍니다.
초기화 작업을 커스터마이즈하기 위한 보다 적절한 방법은, init() 메소드를 사용하는 것입니다. 이것은, __construct()의 마지막 작업으로 일컬어 집니다. 예를 들어, 초기화시에 데이타베이스에 접속하고 싶으면 다음과 같이 합니다.
class FooController extends Zend_Controller_Action
{
public function init()
{
$this->db = Zend_Db::factory('Pdo_Mysql', array(
'host' => 'myhost',
'username' => 'user',
'password' => 'XXXXXXX',
'dbname' => 'website'
));
}
}
7.5.3. 디스패치 전후의 상태
Zend_Controller_Action에는, 요청된 액션에 대한 책꽂이라고 불리는 두 개의 메소드, preDispatch()와 postDispatch()가 있습니다. 이것은 다양한 방법으로 활용할 수 있습니다. 예를 들면, 액션을 실행하기 전에 인증 정보나 ACL를 조사하거나(preDispatch() 내의 _forward()를 호출하면, 그 액션은 건너뜁니다), 생성된 컨텐츠를 전사이트의 템플릿으로 배치하거나(postDispatch()) 등을 할 수 있습니다.
7.5.4. 접근자
다양한 객체나 변수가 객체에 등록되어 있어 각각 접근자가 준비되어 있습니다.
요청(request) 객체 : getRequest()는 액션을 호출하는 데 사용하는 요청(request) 객체를 취득하는데 사용합니다.
응답(response) 객체 : getResponse()는 마지막 응답(response) 내용을 집계하는 응답(response) 객체를 취득하는데 사용합니다. 전형적인 사용법은 다음과 같습니다.
$this->getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);
호출 인수 : 프론트 컨트롤러는 라우터, 디스패처, 그리고 액션 컨트롤러에 매개변수를 보냅니다. 이러한 매개변수를 취득하려면, getInvokeArg($key)를 사용합니다. 또는, 모든 매개변수를 취득하려면 getInvokeArgs()를 사용합니다.
요청(request) 매개변수 : 요청(request) 객체는 _GET나_POST와 같은 요청(request) 매개변수, 또는 URL의 경로 정보에 설정된 매개변수도 수집합니다. 이것들을 취득하려면, _getParam($key) 또는 _getAllParams()를 사용합니다. _setParam()를 사용해서 요청(request) 매개변수를 설정할 수도 있습니다. 이것은, 추가적인 액션을 전송할 때 유용합니다.
매개변수가 존재하는지 아닌지를 조사할 경우(조건 분기 시에 유용), _hasParam($key)를 사용합니다.
7.5.5. 유틸리티 메소드
접근자 외에도, Zend_Controller_Action에는, 액션 메소드 내로부터 (또는 디스패치 전후로 부터) 공통 작업을 수행하기 위한 몇 개의 유틸리티 메소드가 준비되어 있습니다.
_forward($action, $controller = null, $module = null, array $params = null) : 다른 액션을 실행합니다. preDispatch() 내에서 호출되면, 현재 요청된 액션은 건너뛰고 새로운 액션을 실행합니다. 그 이외의 경우는, 현재의 액션의 처리를 끝마친 후에, _forward()에서 요청된 액션을 실행합니다.
_redirect($url, $code = 302) : 다른 위치로 리디렉트(redirect) 합니다. 이 메소드는 URL과 옵션인 HTTP 상태 코드를 가집니다. 리디렉트는 즉시 실행되고, 프로그램의 실행은 거기서 정지합니다.
상태 코드를 지정했을 경우는, 리디렉트시에 PHP header() 명령어로 넘겨집니다.
7.4. 제공되는 서브 클래스군
Zend Framework/7. Zend_Controller | 2007/04/05 23:51
7.4.1. 소개
Zend Framework에서는, 기본으로 제공되는 클래스 이외의 선택사항도 준비해 있습니다. 예를 들어, 요청(request) 객체, 라우터, 그리고 응답(response) 객체 등에 대해서 다른 선택사항이 있습니다.
7.4.2. Zend_Controller_Request_Http
7.4.2.1. 소개
Zend_Controller_Request_Http 는 HTTP 환경에서 사용하는 요청(request) 객체를 제공합니다. Zend_Controller_Request_Http는 기본 요청(request) 클래스이며, Zend_Controller_Dispatcher로 이용됩니다.
7.4.2.2. 요청(request) 데이터에 접근하기
컨트롤러와 액션 라우터 변수의 키 이름과 값, URI로부터 구문 분석된 모든 추가 매개변수의 값 등, 이런 관련된 값에 접근하는 것을 Zend_Controller_Request_Http는 캡슐화합니다. Zend_Controller_Request_Http에 위임함으로써, public member 변수로써 superglobals에 포함되어 있는 값에 접근하거나 현재의 기본 URL이나 요청(request) URI를 관리할 수도 있습니다. superglobal 값은 요청(request)에 설정할 수 없습니다. 그 대신에 setParam/getParam 메소드를 사용해서 매개변수를 설정하거나 취득합니다.
superglobal 데이터Zend_Controller_Request_Http 의 public member 속성을 사용해서 superglobal 데이터에 접근 할 때에 주의해야 할 점은, 속성명(superglobal 배열의 키)은 다음의 우선 순위로 정해집니다. 1. GET, 2. POST, 3. COOKIE, 4. SERVER, 5. ENV.
특정 superglobal은 대안으로 public 메소드를 사용해서 접근할 수 있습니다. 예를 들어, $_POST['user']의 값은 요청(request) 객체에 getPost('user')로 호출함으로써 취득할 수 있습니다.
7.4.2.3. 기본 URL 및 하위 디렉토리
Zend_Controller_Request_Http 는 하위 디렉토리로 Zend_Controller_Router_Rewrite를 사용할 수 있습니다. Zend_Controller_Request_Http는 자동적으로 기본 URL를 검출해, 그것을 적절하게 설정합니다.
예를 들어, index.php를 웹서버의 하위 디렉토리인 /projects/myapp/index.php에 두었을 경우, 기준 URL(고쳐쓰기 기준이 되는)은 /projects/myapp로 설정되어야만 합니다. 일치하는 경로를 찾기 전에, 이 문자열은 경로의 선두로부터 제거됩니다. 이것은 여러분은 어떠한 경로라도 불필요한 문자를 추가할 필요가 없게 해줍니다. 경로 'user/:username'와 같은 경우에는, http://localhost/projects/myapp/user/kkal3는 http://example.com/user/kkal3에 대응합니다.
URL의 검출은 대문자/소문자를 구별합니다 자 동적인 기준 URL의 검출 처리는 대문자/소문자를 구별합니다. 그 때문에, URL은 파일 시스템의 하위 디렉토리명과 확실히 일치시킬 필요가 있습니다 (비록 Windows 기반이라도). 만약 대문자/소문자가 일치하지 않으면, 경로없는(noRoute) 액션이 호출될 것입니다.
기준 URL의 검출에 실패하는 경우는, Zend_Controller_Request_Http 또는 Zend_Controller_Front 클래스의 setBaseUrl() 메소드를 사용해 기준 경로로 고쳐쓰기를 지정할 수 있습니다. 제일 간단한 방법은 Zend_Controller_Front로 설정하는 것입니다. 이 설정은 요청(request) 객체에 위임합니다. 커스텀 기준 URL를 설정하는 예를 나타냅니다.
/**
* Zend_Controller_Front로 커스텀 기준 URL을 지정한 요청(request)을 디스패치
*/
$router = new Zend_Controller_Router_Rewrite();
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('./application/controllers')
->setRouter($router)
->setBaseUrl('/projects/myapp'); // set the base url!
$response = $controller->dispatch();
7.4.3. Zend_Controller_Router_Rewrite
7.4.3.1. 소개
Zend_Controller_Router_Rewrite 는 표준 프레임워크 라우터입니다. 경로 지정(routing)이란, URI(기준 URL로부터 취득한 URI의 일부) 종점을 받아서, 매개변수를 분해하여, 어느 컨트롤러와 그 컨트롤러의 어느 액션이 요청(request)을 처리하는지를 결정하는 처리입니다. 컨트롤러, 액션, 그리고 다른 매개변수의 값은 Zend_Controller_Request_Http 객체에 넣습니다.
그러면, Zend_Controller_Dispatcher_Standard에 의해 처리됩니다. 경로 지정(routing)은 단 한 번만 일어납니다. 즉, 최초로 요청(request)를 받아서 첫 컨트롤러가 디스패치 되기 전입니다.
Zend_Controller_Router_Rewrite 는, 순수 PHP 구조를 사용해서 mod_rewrite와 같은 기능이 가능하도록 설계되어 있습니다. 이 처리는 Ruby on Rails의 경로 지정 처리를 다소 참고하고 있으며, 웹서버의 URL 고쳐쓰기에 관한 전제 지식을 필요로 하지 않습니다. 다음의 싱글 아파치 mod_rewrite 규칙(의 어느쪽이든)으로 동작하도록 설계되어 있습니다.
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
또는
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
Rewrite 라우터를 IIS 웹서버에서 사용하려면, Isapi_Rewrite를 Isapi 확장 모듈로서 인스톨 합니다. 그리고 다음과 같은 규칙을 사용합니다.
RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css)$)[\w\%]*$)? /index.php [I]
IIS Isapi_Rewrite IIS 를 사용하면, $_SERVER['REQUEST_URI']가 존재하지 않거나 빈 문자열로 설정됩니다. 이러한 경우, Zend_Controller_Request_Http는 Isapi_Rewrite 확장 모듈에 의해 설정되는 $_SERVER['HTTP_X_REWRITE_URL']의 값을 사용합니다.
Lighttpd를 사용한다면, 다음과 같은 규칙을 사용합니다.
url.rewrite-once = ( ".*\.(js|ico|gif|jpg|png|css)$" => "$0", "" => "/index.php")
7.4.3.2. 라우터의 사용법
Rewrite 라우터를 적절히 사용하려면, 우선 라우터의 인스턴스를 생성하고, 정의된 경로에 사용자를 추가한 다음, 그것을 콘트롤러에 주입해야만 합니다.
/* 라우터 생성 */
$router = $ctrl->getRouter(); // returns a rewrite router by default
$router->addRoute(
'user',
new Zend_Controller_Router_Route('user/:username', array('controller' => 'user', 'action' => 'info'))
);
7.4.3.3. 기본적인 경로 지정
RewriteRouter 의 핵심은 사용자 정의 경로 지정입니다. 경로 지정은 RewriteRouter의 addRoute 메소드를 호출해서 Zend_Controller_Router_Route의 새로운 인스턴스에 넘김으로써 생성됩니다.
$router->addRoute('user', new Zend_Controller_Router_Route('user/:username'));
최초의 매개변수는 경로의 이름입니다. 그것은 현재 쓰는 것는 중복이지만, 나중에 여러분의 뷰에서 쉽게 URL을 생성할 수 있도록 URL 뷰 도움말에서 사용될 것입니다. 만약 여러분이 사전에 설정한 경로를 사용할 필요가 있다면, RewriteRouter의 getRoute 메소드를 사용해서 검색할 수가 있습니다. 두번째 매개변수는 Zend_Controller_Router_Route의 인스턴스입니다.
Zend_Controller_Router_Route의 생성자의 첫번째 매개변수는 그 URL과 일치하는 경로입니다. 예를 들면, 위의 경로는 http://example.com/user/kkal3에 대응합니다. 경로에 콜론은 URL 변수를 의미합니다. 경로 지정에 성공한 후, 정의된 변수들의 모든 값들은 Zend_Controller_Request에 넣습니다. 그 다음은 Zend_Controller_Request::getParam나 Zend_Controller_Action::_getParam 메소드로 접근 할 수 있게 됩니다. 이번 예에서는, username이라는 매개변수에'kkal3'이라고 하는 값을 설정합니다.
역순 일치경로는 역순으로 일치하기 때문에, 여러분의 가장 일반적인 경로는 첫번째 정의되도록 주의하시기 바랍니다.
문자 사용현재의 구현에서는, 변수의 식별자로서 슬래시(/)를 제외한 모든 문자를 사용할 수 있지만, 가능한 한 PHP 변수로 사용할 수 있는 범위의 문자만을 사용하는 것을 강하게 추천합니다. 장래 이 구현은 변경될 예정이므로, PHP의 변수로 사용할 수 없는 문자를 사용한다면 버그가 발생할 가능성이 있습니다.
경로에 사용될 수 있는 ':controller'와 ':action'이라고 하는 두 개의 특별한 변수가 있습니다. 이들 특별 변수는 URL에서 선택된 컨트롤러와 액션을 찾기 위해 사용됩니다. ':action' 변수는 경로나 기본 매개변수로서 항상 정의되어 있어야만 합니다. 만약 ':controller' 변수가 정의되어 있지 않으면 기본값으로 IndexController가 사용됩니다.
특수 변수들이러한 특수 변수들의 이름은 Zend_Controller_Request_Http의 setControllerKey나 setActionKey 메소드를 사용해서 변경할 수도 있습니다.
$router->addRoute(
'user', new Zend_Controller_Router_Route(':controller/:action')
);
만약 여러분이 브라우저로 'http://example.com/news/latest'로 지정하면, Zend_Controller_Dispatcher는 NewsController 클래스의 latestAction 메소드를 호출합니다.
7.4.3.4. 변수의 기본값
경로 내의 모든 변수는 기본값을 설정할 수 있습니다. 기본값을 설정하려면, Zend_Controller_Router_Route의 생성자의 두번째 매개변수를 사용합니다. 이 매개변수는 변수명을 키, 설정하기 원하는 기본값을 값으로 하는 배열입니다.
$router-addRoute(
'archive', new Zend_Controller_Router_Route('archive/:year', array('year' = 2006))
);
명백하게 보이지 않을지 모르지만, 위 경로는 'http://example.com/archive/2005' 및 'http://example.com/archive'와 같은 URL과 일치합니다. 후자의 경우, 변수 year는 2006의 값을 가집니다.
위의 예는 단지 요청(request)에 year 변수를 넣은 결과입니다. 컨트롤러나 액션 매개변수를 설정하지 않았기 때문에, 경로 지정은 일어나지 않습니다. 이 예를 보다 쓸모있게 만들려면, 올바른 컨트롤러와 올바른 액션의 기본값을 설정해야만 합니다.
$router-addRoute(
'archive',
new Zend_Controller_Router_Route('archive/:year', array('year' = 2006, 'controller' = 'archive', 'action' = 'show')
);
이 경로는 ArchiveController의 showAction를 실행합니다.
7.4.3.5. 변수의 요구조건
Zend_Controller_Router_Route 생성자에 세번째 매개변수를 추가해, 변수의 요구조건을 설정할 수 있습니다. 이것은 정규 표현으로 설정합니다.
$router-addRoute(
'archive',
new Zend_Controller_Router_Route('archive/:year', array('year' = 2006), array('year' = 'd+'))
);
경로 지정 행동Ruby on Rails와는 달리, ZF의 RewriteRouter는 경로를 일치시키고, 세번째 매개변수를 만나지 못했을 때 기본값을 사용합니다. 그래서, 'http://example.com/archive/test'의 URL은 위 경로를 일치시키고, year는 2006으로 설정됩니다. 이 기능은 장래 변경될 예정으로, 이 메뉴얼을 쓰고 있는 시점에서는 아직 논의 중입니다.
7.4.3.6. 기준 URL 및 하위 디렉토리
Rewrite 라우터는 하위 디렉토리에서도 사용할 수 있습니다. 기준 URL은 자동으로 Zend_Controller_Request_Http에 의해 검출됩니다.
기준 URL의 검출에 실패하는 경우에는, Zend_Controller_Request_Http의 setBaseUrl() 메소드를 사용해서 기준 경로를 오버라이드할 수 있습니다.(7.4.2.3.장 "기준 URL 및 하위 디렉토리"를 참조해 주십시오)
7.4.3.7. 기본 경로
Zend_Controller_Router_Rewrite 는 하나의 기본값이 미리 정의되어 있습니다. 그것은 'controller/action' 형식으로 URI에 일치합니다. 게다가, 모듈명을 첫 경로 요소로 지정할 수도 있습니다. 즉, 'module/controller/action 형식의 URI를 사용할 수 있습니다. 또한, URI에 추가된 어떠한 부가적인 매개변수라도 기본값에 의해 일치합니다.
다음 예들은 그런 경로가 어떻게 일치하는지 보여주고 있습니다.
// 다음과 같이 가정합니다:
// $ctrl->setControllerDirectory(array(
// 'default' => '/path/to/default/controllers',
// 'news' => '/path/to/blog/controllers',
// 'blog' => '/path/to/blog/controllers'
// ));
Module only:
http://example/news
module == news
잘못된 모듈과 컨트롤러와의 대응:
http://example/foo
controller == foo
Module + controller:
http://example/blog/archive
module == blog
controller == archive
Module + controller + action:
http://example/blog/archive/list
module == blog
controller == archive
action == list
Module + controller + action + params:
http://example/blog/archive/list/sort/alpha/date/desc
module == blog
controller == archive
action == list
sort == alpha
date == desc
기본 경로는 어떠한 기본값도 없이 생성된 Zend_Controller_Router_Route_Module 객체입니다.
// 라우터 v1과의 호환성을 위한 경로
$compat = new Zend_Controller_Router_Route_Module();
$this->addRoute('default', $compat);
일치하는 URI Zend_Controller_Router_Rewrite 는 과거와의 호환성을 고려해 설정되어 있습니다. 그것은 자동적으로 부가적인 매개변수를 가진 controller/action 형식의 URI와 일치합니다. 기본값이나 변수 요구조건을 가져야 하는 것이 아닌 한, 추가적인 매개변수에 대해 새로운 경로를 추가할 필요는 없습니다. 이러한 추가적인 매개변수는 Zend_Controller_Action::_getParam() 메소드로부터 접근할 수 있습니다.
만약 여러분의 경로지정 계획에 기본 경로를 사용하고 싶지 않으면, removeDefaultRoutes() 메소드를 사용해서 삭제합니다.
// 기본 호환 경로를 삭제합니다
$router-removeDefaultRoutes();
7.4.3.8. 정적인 루트
위의 모든 예들은 동적인 경로를 사용했습니다. 즉, 특정의 것에 일치하는 패턴들을 포함하는 경로였습니다. 그러나, 때로는 경로를 고정으로 설정하고, 정규 표현 엔진을 사용하고 싶지 않은 경우가 있을 겁니다. 그럴 경우에 정적인 경로를 사용합니다.
$loginRoute = new Zend_Controller_Router_Route_Static('login', array('controller' = 'login', 'action' = 'form'));
$router-addRoute('login', $static);
7.4.3.9. RewriteRouter를 가진 Zend_Config의 사용법
때때로 코드를 수정하는 것보다 새로운 경로를 가진 설정 파일을 수정하는 것이 편리할 경우가 있습니다. 이럴 경우에는 addConfig() 메소드를 사용합니다. 기본적으로, 여러분은 Zend_Config 호환 설정을 만들고, 그것을 코드에서 불러 RewriteRouter에 넘겨줍니다.
/**
* /path/to/config.ini에 위치한 예제용 INI파일
*
* [production]
*
* routes.archive.route = "archive/:year/*"
* routes.archive.defaults.controller = archive
* routes.archive.defaults.action = show
* routes.archive.defaults.year = 2000
* routes.archive.reqs.year = "d+"
*
* routes.news.type = "Zend_Controller_Router_Route_Static"
* routes.news.route = "news"
* routes.news.defaults.controller = "news"
* routes.news.defaults.action = "list"
*/
$config = new Zend_Config_Ini('/path/to/config.ini', 'production');
$router = new Zend_Controller_Router_Rewrite();
$router-addConfig($config, 'routes');
위의 예에서는, 라우터가 경로 지정을 위해 사용하도록 INI 파일의 'routes' 섹션을 사용하고 있습니다. 이 섹션의 각 첫번째 레벨 키가 경로명을 정의하는 데 사용됩니다. 위의 예에서는 경로 'archive'와 'news'를 정의하고 있습니다. 각 경로는 최소한 'route' 엔트리와 하나 이상의 'defaults' 엔트리가 필요합니다. 옵션으로, 하나 이상의 'reqs'('required'의 줄임말)도 지정할 수 있습니다. 여기서 지정한 것이 Zend_Controller_Router_Route_Interface 객체에 제공되는 세 개의 인수에 대응합니다. 옵션 키 'type'은 특정 경로로 사용하는 경로 클래스의 형태를 지정하는 데 사용될 수 있습니다. 기본값에 의해, 그것은 Zend_Controller_Router_Route를 사용합니다. 위의 예에서 'news' 경로는 Zend_Controller_Router_Route_Static을 사용도록 정의되어 있습니다.
7.4.4. Zend_Controller_Response_Http
Zend_Controller_Response_Http 는 HTTP 환경에서 사용하기 적합한 응답(response) 객체입니다. 이 객체는 헤더의 설정, 취득, 삭제에 대한 메소드를 포함하고 있습니다. 또, __toString() 메소드는 응답(response) 내용을 반환하기 전에 한 번에 모든 헤더를 보냅니다.
setHeader()는 헤더 형식과 헤더 값이라고 하는 두 개의 인수를 받습니다. 만약 세번째, 옵션 매개변수를 넘기고 true로 하면, 동일한 형식을 가지고 등록된 어떤 다른 헤더라도 새로운 헤더로 강제로 교체해 버립니다.
7.4.5. Zend_Controller_Response_Cli
Zend_Controller_Response_Cli 는 CLI 환경에서 사용하기 적합한 응답(response) 객체입니다. 헤더를 처리하기 위한 메소드는 없고, __toString()이 호출될 때 단순히 모든 본문 내용을 반환합니다.
7.3. 서브 클래스화
Zend Framework/7. Zend_Controller | 2007/03/29 23:55
7.3.1. 소개
Zend_Controller 시스템은 확장성을 고려해 구축되었습니다. 확장 방법으로서는, 기존의 클래스를 상속받거나, 또는 Zend_Controller_Router_Interface와 Zend_Controller_Dispatcher_Interface를 구현하거나, Zend_Controller_Request_Abstract, Zend_Controller_Response_Abstract, 그리고 Zend_Controller_Action을 상속받아 새로운 클래스를 만들 수도 있습니다.
클래스를 확장하는 이유는 다음과 같은 것을 생각할 수 있습니다.
기존의 URI 경로 지정 시스템이 어떠한 이유로 적합하지 않는 경우. 예를 들면, 기존의 웹사이트와 통합할 예정이지만, 거기서 채용하고 있는 규약이 Zend Framework의 경로 지정 방식과 일치하지 않는 경우 등.
여러분은 완전히 다른 어떤 경로 지정 방식을 구현할 필요가 있습니다. Zend_Controller_Router 클래스는 URI만을 다룹니다. 콘솔이나 GUI 애플리케이션 등과 같은, 다른 형식의 프로그램에도 MVC 패턴을 사용하기를 원할 것입니다. 콘솔 애플리케이션의 경우라면, 커스텀 요청(request) 객체는 명령행 매개변수를 처리할 수 있을 것입니다.
Zend_Controller_Dispatcher의 제공하는 기능이 적합하지 않는 경우. 기본 구성에서는, 컨트롤러는 클래스이며, 액션은 그 클래스의 메소드인 것을 전제로 하고 있습니다. 그러나, 이외에도 여러가지 방식이 있을 것입니다. 예를 들면, 디렉토리를 컨트롤러, 디렉토리 내의 파일을 액션이라고 생각할 수도 있습니다.
모든 컨트롤러에서 사용하기 위한 기능을 추가하고 싶은 경우. 예를 들면, 기본값에서는 Zend_Controller_Action은 Zend_View와 통합되어 있지 않습니다. 그러나, 컨트롤러를 상속받은 클래스에서 이 기능을 갖게 할 수 있습니다. 그러면, 원래의 Zend_Controller_Router나 Zend_Controller_Dispatcher를 수정할 필요가 없습니다.
애플리케이션에서 예외가 발생할 때 로그를 남기고, 공통의 에러 페이지로 연결시키고 싶은 경우. 기존의 Zend_Controller_Response_Http를 확장해서, __toString()을 수정함으로써, 등록된 예외의 확인과 그 로그의 기록, 에러 페이지로의 연결이 가능해집니다.
시스템의 주요한 부분을, 특히 디스패처, 오버라이드(override) 할 때 충분히 주의하시기 바랍니다. Zend_Controller를 사용하는 이점의 하나는 구축하는 애플리케이션을 위한 공통의 규약을 설정할 수 있는 점입니다. 만약 기본 행동을 너무 변경해 버리면, 이 이점이 없어져 버립니다. 그렇지만, 세상에는 다양한 수요가 있는 법이고, 하나의 솔루션으로 모든 것을 해결할 수 없는 일입니다. 그래서, 필요하다면 변경할 수 있도록 하고 있습니다.
7.3.2. 규약
Zend_Controller 클래스를 상속받는 경우는, 그 파일의 명명법이나 저장은 가능한 한 다음의 규약에 따르도록 해주시기 바랍니다. 그렇게 함으로써, Zend Framework에 친숙한 다른 프로그래머가, 당신의 프로젝트 내용을 간단하게 이해할 수 있게 됩니다.
7.3.2.1. 접두어(prefix)
Zend Framework에 포함되는 모든 클래스의 이름은 접두어 "Zend_"를 붙여서 만드는 규약을 따릅니다. 이것이 접두어(prefix)입니다. 여러분이 만드는 클래스도 같은 방식으로 하시길 권장합니다. 예를 들면, 만약 여러분이 소속된 회사명이 Widget, Inc. 라면, 접두어를 "Widget_"로 합니다.
7.3.2.2. 디렉토리 구성
Zend_Controller 클래스들은 다음과 같이 라이브러리 디렉토리에 저장됩니다.
/library
/Zend
/Controller
Action.php
Dispatcher.php
Router.php
Zend_Controller 클래스를 상속받는 경우는, 새로운 클래스가 여러분 붙인 접두어 하에서 동일한 구조로 저장되는 것을 추천 합니다. 이렇게 함으로써 여러분의 프로젝트 코드를 리뷰하는 사람들이 그것을 쉽게 찾을 수 있을겁니다.
예를 들면 Widget, Inc.의 프로젝트가 커스텀 라우터만을 구현했을 경우는, 다음과 같이 될 것입니다.
/library
/Zend
/Widget
/Controller
Router.php
README.txt
이 예에서는, Widget/Controller/ 디렉토리가 Zend/Controller/ 디렉토리와 동일한 구조로 되어 있는 것에 주의합시다. 이 경우에서는, Widget_Controller_Router라는 클래스를 제공합니다. 이 클래스는 Zend_Controller_Router를 상속받거나, 또는 Zend_Controller_Router_Interface를 구현한 Zend_Controller_Router를 위한 독자적인 클래스가 됩니다.
또, 위의 예로 Widget/Controller/ 디렉토리에 있는 README.txt 파일을 주의해 주십시오. 여러분의 프로젝트를 고객에게 제공할 때, 거기에 관한 단위 테스트와 문서도 작성하도록, Zend는 강하게 추천 합니다. 그러나, 그 정도까지는 아니더라도 디렉토리에 간단한 README.txt 파일을 두어, 여러분의 수정사항과 동작 내용을 간단히 설명해 두기를 바랍니다.
7.3.3. 프론트 컨트롤러
Zend_Controller_Front는 프론트 컨트롤러를 구현한 것입니다. 게다가 이것은 싱글톤 클래스이기도 합니다. 즉, 어느 시점에 있어서나 인스턴스는 하나 밖에 존재하지 않는다는 것을 의미합니다.
이 서브 클래스를 작성하기 위해서 최소한 필요한 것은 getInstance() 메소드를 오버라이드(override) 하는 것입니다.
class My_Controller_Front extends Zend_Controller_Front
{
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
}
getInstance() 메소드를 오버라이드(override) 하는 것은, Zend_Controller_Front::getInstance()의 다음 호출 시에 Zend_Controller_Front 인스턴스 대신 여러분이 만든 새로운 서브클래스의 인스턴스를 반환하는 것을 확실하게 합니다. 이것은 특히 선택적인 라우터와 도움말 보기에 유용할 것입니다.
getInstance() 이외에 다른 많은 메소드를 오버라이드(override) 할 수 있습니다.
/**
* 싱글톤 인스턴스의 모든 객체 프로퍼티를 리셋
*
* 주로 테스팅의 목적으로 사용; 프론트 컨트롤러를 연결하는 데 사용 가능
*
* @return void
*/
public function resetInstance();
/**
* 편리한 특성, setControllerDirectory()->setRouter()->dispatch()로 호출합니다.
*
* PHP 5.1.X의 경우, 정적 메소드에서 호출로 $this를 결코 사용할 수 없습니다.
* 그래서, 프론트 컨트롤러를 설정한 후에 실제로 run()이 호출됩니다.
*
* @param string|array $controllerDirectory Path to Zend_Controller_Action
* controller classes or array of such paths
* @return void
* @throws Zend_Controller_Exception if called from an object instance
*/
static public function run($controllerDirectory);
/**
* 컨트롤러 디렉토리 스택에 컨트롤러 디렉토리를 추가합니다.
*
* 만약 $args가 존재하고 문자열이면, 지정된 디렉토리와 매핑을 위한 배열키로 사용합니다.
*
* @param string $directory
* @param mixed $args Optional argument; 만약 문자열 값이면, 배열키 매핑에 사용
* @return Zend_Controller_Front
*/
public function addControllerDirectory($directory, $args = null);
/**
* 컨트롤러 디렉토리를 설정합니다.
*
* 디스패처에 넘길 컨트롤러 디렉토리를 저장합니다.
* 디렉토리들의 배열이나 단일 디렉토리를 포함하는 문자열이 매개변수로 지정가능합니다.
* Stores controller directory to pass to dispatcher. May be an array of
* directories or a string containing a single directory.
*
* @param string|array $directory Path to Zend_Controller_Action controller
* classes or array of such paths
* @return Zend_Controller_Front
*/
public function setControllerDirectory($directory);
/**
* 컨트롤러 디렉토리를 취득합니다.
*
* 저장되어 있는 컨트롤러 디렉토리를 취득합니다.
*
* @return string|array
*/
public function getControllerDirectory();
/**
* 기본 컨트롤러를 설정합니다. (비형식화 문자열)
*
* @param string $controller
* @return Zend_Controller_Front
*/
public function setDefaultController($controller);
/**
* 기본 컨트롤러를 취득합니다. (비형식화 문자열)
*
* @return string
*/
public function getDefaultController();
/**
* 기본 액션을 설정합니다. (비형식화 문자열)
*
* @param string $action
* @return Zend_Controller_Front
*/
public function setDefaultAction($action);
/**
* 기본 액션을 취득합니다. (비형식화 문자열)
*
* @return string
*/
public function getDefaultAction();
/**
* 요청(request) 클래스/객체를 설정합니다.
*
* 요청(request) 객체를 설정합니다. 요청(request)은 요청(request) 환경을 보유합니다.
*
* 만약 클래스명이 제공되면, 그 클래스에서 객체를 생성합니다.
*
* @param string|Zend_Controller_Request_Abstract $request
* @throws Zend_Controller_Exception if invalid request class
* @return Zend_Controller_Front
*/
public function setRequest($request);
/**
* 요청(request) 객체를 반환합니다.
*
* @return null|Zend_Controller_Request_Abstract
*/
public function getRequest();
/**
* 라우터 클래스/객체를 설정합니다.
*
* 라우터 객체를 설정합니다. 라우터는 요청(request)을 컨트롤러와 액션으로 매핑합니다.
*
* 만약 클래스명이 제공되면, {@link setParam()} 또는 {@link setParams()}를 통해 등록된
* 어떤 매개변수를 가진 라우터를 생성합니다.
*
* @param string|Zend_Controller_Router_Interface $router
* @throws Zend_Controller_Exception if invalid router class
* @return Zend_Controller_Front
*/
public function setRouter($router);
/**
* 라우터 객체를 반환합니다.
*
* 만약 현재 라우터가 설정되어 있지 않으면, Zend_Controller_Router 객체를 생성합니다.
*
* @return null|Zend_Controller_Router_Interface
*/
public function getRouter();
/**
* 요청(request)를 위해 사용할 기준 URL을 설정합니다.
*
* PATH_INFO 등을 결정할 때 사용하기 위하여
* REQUEST_URI의 기준 URL 세그먼트를 설정하는 데 사용합니다.
* 예제:
* - /admin
* - /myapp
* - /subdir/index.php
*
* URL은 전체 URI를 포함하면 안된다는 것에 주의하시기 바랍니다.
* 다음과 같이 사용할 수 없습니다.
* - http://example.com/admin
* - http://example.com/myapp
* - http://example.com/subdir/index.php
*
* 만약 NULL 값이 넘겨지면, 자동 검색(기본값)으로 사용됩니다.
*
* @param string $base
* @return Zend_Controller_Front
* @throws Zend_Controller_Exception for non-string $base
*/
public function setBaseUrl($base = null);
/**
* 현재 설정된 기준 URL를 취득합니다.
*
* @return string
*/
public function getBaseUrl();
/**
* 디스패처 객체를 설정합니다. 디스패처는 Zend_Controller_Request_Abstract 객체를 취득하고,
* 컨트롤러를 생성하고, 그리고 컨트롤러의 액션 메소드를 호출합니다.
*
* @param Zend_Controller_Dispatcher_Interface $dispatcher
* @return Zend_Controller_Front
*/
public function setDispatcher(Zend_Controller_Dispatcher_Interface $dispatcher);
/**
* 디스패처 객체를 반환합니다.
*
* @return Zend_Controller_DispatcherInteface
*/
public function getDispatcher();
/**
* 응답(response) 클래스/객체를 설정합니다.
*
* 응답(response) 객체를 설정합니다. 응답(response)은 액션 응답과 헤더을 위한 컨테이너입니다.
*
* 만약 클래스명이 제공되면, 그 클래스로부터 응답(response) 객체를 생성합니다.
*
* @param string|Zend_Controller_Response_Abstract $response
* @throws Zend_Controller_Exception if invalid response class
* @return Zend_Controller_Front
*/
public function setResponse($response);
/**
* 응답(response) 객체를 반환합니다.
*
* @return null|Zend_Controller_Response_Abstract
*/
public function getResponse();
/**
* 액션 컨트롤러를 인스턴스화 할 때 사용하기 위한 매개변수를 추가하거나 수정합니다.
*
* @param string $name
* @param mixed $value
* @return Zend_Controller_Front
*/
public function setParam($name, $value);
/**
* 액션 컨트롤러 생성자에게 넘길 매개변수를 설정합니다.
*
* @param array $params
* @return Zend_Controller_Front
*/
public function setParams(array $params);
/**
* 컨트롤러 매개변수 스택으로부터 단일 매개변수를 취득합니다.
*
* @param string $name
* @return mixed
*/
public function getParam($name);
/**
* 액션 컨트롤러 인스턴스 생성 매개변수를 취득합니다.
*
* @return array
*/
public function getParams();
/**
* 컨트롤러 매개변수 스택을 초기화 합니다.
*
* 기본값에 의해, 모든 매개변수를 초기화 합니다. 만약 매개변수명이 주어지면,
* 그 매개변수만 초기화 합니다. 만약 매개변수명의 배열이 제공되면, 각각 초기화 합니다.
*
* @param null|string|array single key or array of keys for params to clear
* @return Zend_Controller_Front
*/
public function clearParams($name = null);
/**
* 플러그인을 등록합니다.
*
* @param Zend_Controller_Plugin_Abstract $plugin
* @return Zend_Controller_Front
*/
public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin);
/**
* 플러그인의 등록을 해지합니다.
*
* @param Zend_Controller_Plugin_Abstract $plugin
* @return Zend_Controller_Front
*/
public function unregisterPlugin(Zend_Controller_Plugin_Abstract $plugin);
/**
* 디스패치 루프에서 발생되는 예외를 처리하거나 응답(response) 객체에서 잡을 지 여부를 설정합니다.
*
* 기본 행동은 응답(response) 객체에서 예외를 잡는 것입니다. 이 메소드를 호출해서 예외를 처리합니다.
*
* @param boolean $flag Defaults to true
* @return boolean Returns current setting
*/
public function throwExceptions($flag = null);
/**
* {@link dispatch()}가 최초 렌더링 출력을 하지 않고 응답(response)을 반환할 지 여부를 설정합니다.
* 기본값에 의해, 출력은 렌더링되고, dispatch()는 반환값이 없습니다.
*
* @param boolean $flag
* @return boolean Returns current setting
*/
public function returnResponse($flag = null);
/**
* HTTP 요청(request)을 컨트롤러/액션으로 디스패치합니다.
*
* @param Zend_Controller_Request_Abstract|null $request
* @param Zend_Controller_Response_Abstract|null $response
* @return void|Zend_Controller_Response_Abstract 만약 returnResponse()가 true이면,
* 응답(response) 객체를 반환합니다.
*/
public function dispatch(Zend_Controller_Request_Abstract $request = null,
Zend_Controller_Response_Abstract $response = null);
프론트 컨트롤러의 목적은, 요청(request) 환경을 설정하고, 들어오는 요청(request)의 경로를 지정하고, 그리고나서 발견된 액션을 디스패치 하는 것입니다. 마지막으로 응답(response)를 취득하고 그것을 반환하는 것입니다.
프론트 컨트롤러를 확장하는 주된 이유는, 접근용 메소드의 논리를 변경(예를 들어, 다른 기본 라우터나 디스패처를 읽어들이거나 컨트롤러 디렉토리의 처리 방법을 지정하는 등)하거나 경로 지정이나 디스패치 처리를 변경하기 위해서입니다.
7.3.4. 요청(request)의 추상화
추상 클래스 Zend_Controller_Request_Abstract는 몇 개의 메소드를 정의하고 있습니다.
/**
* @return string
*/
public function getControllerName();
/**
* @param string $value
* @return self
*/
public function setControllerName($value);
/**
* @return string
*/
public function getActionName();
/**
* @param string $value
* @return self
*/
public function setActionName($value);
/**
* @return string
*/
public function getControllerKey();
/**
* @param string $key
* @return self
*/
public function setControllerKey($key);
/**
* @return string
*/
public function getActionKey();
/**
* @param string $key
* @return self
*/
public function setActionKey($key);
/**
* @param string $key
* @return mixed
*/
public function getParam($key);
/**
* @param string $key
* @param mixed $value
* @return self
*/
public function setParam($key, $value);
/**
* @return array
*/
public function getParams();
/**
* @param array $array
* @return self
*/
public function setParams(array $array);
/**
* @param boolean $flag
* @return self
*/
public function setDispatched($flag = true);
/**
* @return boolean
*/
public function isDispatched();
}
요청(request) 객체는 요청(request) 환경의 컨테이너가 됩니다. 컨트롤러 체인은 실제로 컨트롤러, 액션, 옵션 매개변수 및 디스패치된 상황을 설정하거나 취득하는 방법만 알면 됩니다. 기본값에 의해, 컨트롤러나 액션 키를 이용하여, 컨트롤러와 액션을 결정하기 위해, 요청(request)은 자신의 매개변수를 검색합니다.
7.3.5. 라우터의 인터페이스
인터페이스 Zend_Controller_Router_Interface는 단지 하나의 메소드에 대한 정의를 제공합니다.
<?php
/**
* @param Zend_Controller_Request_Abstract $request
* @throws Zend_Controller_Router_Exception
* @return Zend_Controller_Request_Abstract
*/
public function route(Zend_Controller_Request_Abstract $request);
?>
경로 지정(routing)이 발생하는 것은 시스템이 최초로 요청(request)을 받았을 때입니다. 라우터의 역할은, 요청(request) 환경을 기초로 컨트롤러, 액션 그리고 옵션 파라미터를 결정해서, 그것을 요청(request)으로 설정하는 것입니다. 그 후, 요청(request) 객체를 디스패처에 넘깁니다. 만약 루트를 디스패처 토큰에 매핑할 수 없다면, 라우터는 요청(request) 객체에 대해 아무것도 하지 않습니다.
7.3.6. 디스패처 인터페이스
Zend_Controller_Front는, 먼저 라우터를 호출하고, 요청(request)내에서 최초로 디스패치 할 수 있는 액션을 결정합니다. 그 후, 디스패치 루프에 들어갑니다.
루프 내에서, 우선 요청(request) 객체의 디스패치된 플래그를 설정하고, 그리고나서 요청(request)을 디스패치 합니다.(컨트롤러의 인스턴스를 생성해서, 액션을 호출합니다.) 만약 액션 메소드(또는 pre/postDispatch 플러그인)가 요청(request)의 디스패치된 플래그를 리셋하면, 요청(request) 객체 내에서 액션이 현재 설정된 내용을 기초로 해, 프론트 컨트롤러가 디스패치 루프내의 다음 처리를 실행합니다. 이것은 모든 작업이 종료될 때까지 액션이 순차적으로 처리되도록 해줍니다.
인터페이스 Zend_Controller_Dispatcher_Interface는 두 개의 메소드에 대한 정의를 제공합니다.
<?php
/**
* @param Zend_Controller_Request_Abstract $request
* @return boolean
*/
public function isDispatchable(Zend_Controller_Request_Abstract $request);
?>
isDispatchable()은 요청(request)이 디스패치 가능한 지를 조사합니다. 디스패치가 가능한 경우에 TRUE, 그 이외의 경우에 FALSE를 반환합니다. 디스패치가 가능한 지를 판단하는 기준은, 인터페이스를 구현한 클래스에서 기술합니다. 기본 구현인 Zend_Controller_Dispatcher의 경우에, 컨트롤러의 파일이 존재하는지, 그 파일 내에 클래스가 존재하는지, 그리고 그 클래스에서 액션 메소드가 존재하는지를 조사합니다.
<?php
/**
* @param Zend_Controller_Request_Abstract $route
* @return Zend_Controller_Request_Abstract
*/
public function dispatch(Zend_Controller_Request_Abstract $request);
?>
dispatch()는 실제 처리를 실시하는 곳입니다. 이 메소드는 컨트롤러의 액션을 실행해야만 합니다. 또 요청(request) 객체를 반환해야만 합니다.
7.3.7. 액션 컨트롤러
액션 컨트롤러는 애플리케이션의 다양한 액션을 처리합니다. 이 추상 클래스는 다음의 메소드를 제공합니다.
/**
* @param Zend_Controller_Request_Abstract $request Request object
* @param Zend_Controller_Response_Abstract $response Response object
* @param array $args 구성/환경 설정들의 옵션 연관 배열
*/
public function __construct(Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response, array $args = array());
/**
* @return void
*/
public function init();
/**
* @return Zend_Controller_Request_Abstract
*/
public function getRequest();
/**
* @param Zend_Controller_Request_Abstract $request
* @return self
*/
public function setRequest(Zend_Controller_Request_Abstract $request);
/**
* @return Zend_Controller_Response_Abstract
*/
public function getResponse();
/**
* @param Zend_Controller_Response_Abstract $response
* @return self
*/
public function setResponse(Zend_Controller_Response_Abstract $response);
/**
* @return array
*/
public function getInvokeArgs();
/**
* @return mixed
*/
public function getInvokeArg($name);
public function preDispatch();
public function postDispatch();
/**
* @param string $methodName
* @param array $args
*/
public function __call($methodName, $args);
/**
* @param null|Zend_Controller_Request_Abstract $request 사용할 옵션 요청(request) 객체
* @param null|Zend_Controller_Response_Abstract $response 사용할 옵션 응답(response) 객체
* @return Zend_Controller_Response_Abstract
*/
public function run(Zend_Controller_Request_Abstract $request = null,
Zend_Controller_Response_Abstract $response = null);
생성자는 요청(request) 객체, 응답(response) 객체, 그리고 추가 구성 인수들의 배열을 등록합니다. 이 배열은 프론트 컨트롤러의 setParam()나 setParams() 메소드로 등록된 매개변수들로 구성되어 있습니다. 등록한 후에, 생성자는 처리를 init()에 넘깁니다.
여러분이 생성자를 오버라이드(override)하더라도, 요청(request)과 응답(response) 객체들이 적절히 등록될 수 있도록 init()으로 초기화 처리 하기를 추천합니다.
생성자에게 넘겨진 구성 인수들은, 이후에 getInvokeArg() 및 getInvokeArgs()를 사용해서 접근할 수 있습니다. 권장하는 방법은 뷰, 인증/권한 부여, 또는 레지스트리 객체와 같은 객체들에서 넘겨지는 호출 인수들을 사용하는 것입니다. 예를 들면:
$front = Zend_Controller_Front::getInstance();
$front->setParam('view', new Zend_View())
->setControllerDirectory($config->controller->directory);
$response = $front->dispatch();
// 예제 액션 컨트롤러:
class FooController extends Zend_Controller_Action
{
protected $_view = null;
public function init()
{
$this->_view = $this->getInvokeArg('view');
}
}
액션이 디스패치 될 때, preDispatch()와 postDispatch() 메소드 각각을 이용해서 액션의 전후 처리가 수행됩니다. 기본값에 의해, 이들 메소드는 빈 값이며 아무 것도 하지 않습니다.
__call() 메소드는 클래스 내에서 등록되지 않은 액션을 처리합니다. 기본값에 의해, 만약 액션이 정의되지 않으면, 예외를 발생합니다. 이것은, 기본 액션 메소드가 정의되어 있지 않은 경우에만 발생합니다.
액션 메소드의 기본 명명 규약은 lowercaseAction입니다. 'lowercase' 부분에 액션명을 지정하고, 'Action' 부분에서 이것이 액션 메소드인 것을 지정합니다. 즉, http://framework.zend.com/foo/bar는 FooController::barAction()을 호출합니다.
액션 컨트롤러는 페이지 컨트롤러로서 사용할 수도 있습니다. 전형적인 사용법은, 다음과 같습니다.
$controller = new FooController(
new Zend_Controller_Request_Abstract(),
new Zend_Controller_Response_Abstract()
);
$controller->run();
프론트 컨트롤러/액션 컨트롤러의 사용 페이지 컨트롤러 방식이 아닌 프론트 컨트롤러/페이지 컨트롤러를 조합한 방식을 사용하는 것을 추천합니다. 이것에 의해, 상호 운용 가능한 애플리케이션을 쓸 수 있게 됩니다.
7.3.8. 응답(response) 객체
응답(response) 객체는, 호출된 다양한 액션으로부터 내용이나 헤더를 수집해, 그것을 클라이언트에 반환합니다. 다음과 같은 메소드가 있습니다.
/**
* @param string $name Header name
* @param string $value Header value
* @param boolean $replace 객체에 이미 등록된 동일한 이름을 가진 헤더를 교체할 지에 대한 여부
* @return self
*/
public function setHeader($name, $value, $replace = false);
/**
* @return array
*/
public function getHeaders();
/**
* @return void
*/
public function clearHeaders();
/**
* Sends all headers
* @return void
*/
public function sendHeaders();
/**
* @param string $content
* @return self
*/
public function setBody($content);
/**
* @param string $content
* @return self
*/
public function appendBody($content);
/**
* @return string
*/
public function getBody();
/**
* echoes body content
* @return void
*/
public function outputBody();
/**
* @param Exception $e
* @return self
*/
public function setException(Exception $e);
/**
* @return null|Exception
*/
public function getException();
/**
* @return boolean
*/
public function isException();
/**
* @param boolean $flag
* @return boolean
*/
public function renderExceptions($flag = null);
/**
* @return string
*/
public function __toString();
setBody()는, 모든 본문 내용을 옮겨놓습니다. 이 메소드 대신에 appendBody()를 사용하는 것을 추천 합니다. __toString()은 내용을 렌더링 해 모든 헤더를 전송합니다.
응답(response) 객체는 또한, 액션 컨트롤러에서 발생한 예외가 최종적으로 포착, 등록되는 곳이기도 합니다.(Zend_Controller_Front::throwExceptions()가 유효하게 되어 있는 경우를 제외한다) isException()는 예외가 발생했는지를 나타내는 부울린값을 반환합니다. renderExceptions()는 예외를 포착했을 때 __toString()이 예외 출력을 렌더링하는지를 나타내는 데 사용합니다.
7.2. 시작하기
Zend Framework/7. Zend_Controller | 2007/03/27 23:29
7.2.1. 소개
Zend_Controller 시스템은 확장성을 고려해 구축되었습니다. 즉, 기존의 클래스들을 상속받거나 컨트롤러 패밀리 클래스의 기반이 되는 추상 클래스들과 다양한 인터페이스의 구현을 통해 새로운 클래스를 만들 수 있습니다.
7.2.2. 서버의 설정
Zend_Controller는 팬시 URI(쿼리 문자열이 붙지 않거나 거의 없는)를 가진 최신의 웹사이트를 지원하도록 구축됩니다. 따라서, 이런 추천 설정은, 모든 요청(request)들을 단일 파일(여기서는 "index.php", 이것은 단순히 Zend_Controller_Front를 호출할 뿐입니다)로 연결해주는 URI 고쳐쓰기(rewriting) 방식이 웹서버로부터 지원되어야만 합니다. 아파치 웹서버에서는 mod_rewrite라고 하는 옵션 모듈에 의해 지원되고 있습니다.
서버를 설정하기 위한 첫걸음은 성공적으로 인스톨을 하고 mod_rewrite를 유효하게 합니다. 다음으로 .htaccess와 index.php의 두 개의 파일을 문서 루트(document root)에 배치합니다. .htaccess는 아파치가 사용하는 파일로, 모든 요청(request)을 index.php로 연결시키기 위해 mod_rewrite 룰을 이 파일에 기술합니다.
개발중이라면, 특정 확장자를 가진 파일 이외의 모든 요청(request)을 index.php로 연결시키는, 단순한 룰을 설정해두면 됩니다. 예를 들면 다음과 같이 됩니다.
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
위의 예에서는, 지정한 확장자(extension) 이외의 모든 파일에 대한 요청(request)이 index.php로 넘겨집니다. 개발 중에는 이것으로 충분하지만, 실제 운용 환경에서는, 이외의 디렉토리를 차단하는 고쳐쓰기(rewrite) 룰이 기술된 파일들도 필요합니다.
기동용 파일의 장소 기동용 파일은 문서 루트에 저장하는 유일한 PHP 파일이어야 합니다.
Zend_Controller의 기본 기능으로서 쿼리 매개변수를 포함하는 URL도 지원하고 있습니다. 예를 들어 index.php?controller=foo&action=bar와 같은 형식입니다. 게다가 또 다른 라우터인 Zend_Controller_RewriteRouter는 mod_rewrite 같은 기능이 없는 경우를 포함한 많은 환경에서 동작합니다. 만약 mod_rewrite를 사용할 수 없는 경우라도, 여러분의 사이트에서 Zend_Controller를 사용할 수 있습니다.
7.2.3. 기동용 파일
.htaccess 파일의 설정이 끝나면, index.php 라고 하는 새로운 파일을 만듭니다. 이것이 기동용 파일이 됩니다. index.php의 목적은 단지 Zend_Controller_Front를 기동하기 위해서 사용합니다. Zend_Controller_Front는 문서 루트의 밖에 배치합니다.
주의 기동용 파일은 문서 루트에 저장하는 유일한 PHP 파일이어야 합니다.
보안의 목적상, 웹서버(문서 루트의 하위)로부터 접근할 수 있는 디렉토리에 다른 PHP 파일을 저장하지 않도록, Zend는 강하게 추천합니다. 비록 공유 호스팅 환경 같은 모든 경우에서 가능한 것은 아니지만, 가능한 한 추천 설정에 따르기를 바랍니다.
Zend_Controller_Front를 기동하기 위해 문서 루트에 index.php 파일을 만듭니다.
<?php
require_once 'Zend/Controller/Front.php';
Zend_Controller_Front::run('/path/to/your/controllers');
?>
/path/to/your/controllers의 부분에 관해서는 다음 장을 참조해 주십시오. README.txt에 기술되고 있듯이, Zend Framework library의 디렉토리는 include_path로 설정되어야만 합니다. 만약 include_path가 php.ini로 설정되어 있지 않은 경우에는, 이 index.php 파일에서 require_once() 하기 전에 set_include_path()를 사용해서 설정할 수도 있습니다.
7.2.4. 디렉토리 구조
Zend Framework로 구축하는 웹사이트는 공통의 디렉토리 구조를 공유하는 것을 추천합니다. 비록 이것이 모든 경우에 가능하지는 않지만, 가능한 한 이 구조에 맞춰주시길 바랍니다. 그렇게 함으로써, Zend Framework의 규약에 익숙해 있는 사람들에게 여러분의 코드를 보다 쉽게 이해할 수 있게 합니다.
추천하는 구조는, (Zend 및 그 외의) 라이브러리용 디렉토리와 애플리케이션 디렉토리를 따로 나누는 것입니다.
/application
/models
/views
/controllers
/document_root
/images
/styles
.htaccess
index.php
/library
/Zend
주의 이 장은 아직 미완성입니다. 현재 작성중이며, 향후 바뀔 가능성이 있습니다.
7.2.5. 기본 컨트롤러
모든 사이트는 기본 컨트롤러를 반드시 정의해야 합니다. 아래 URI처럼, URI에 컨트롤러가 지정되지 않는 경우, 이 기본 컨트롤러가 사용됩니다.
http://framework.zend.com/
초기 설정에서는, 기본 컨트롤러는 IndexController라고 정의되고, IndexController.php라는 파일로 정의되어야만 합니다. 내부적으로는, 'index' 컨트롤러로서 참조됩니다.
프론트 컨트롤러나 디스패처 객체로 setDefaultController() 메소드를 호출해서 프론트 컨트롤러를 디스패치 하기 전에, 기본 컨트롤러를 변경할 수 있습니다. 그렇게 할 때에는, 내부 명명 규약을 사용합니다. 즉, 클래스 HomeController(HomeController.php 파일에 있는)가 home으로써 참조될 것입니다.
컨트롤러는 Zend_Controller_Action 클래스를 상속받아, 컨트롤러 디렉토리에 위치해야 합니다.
<?php
require_once 'Zend/Controller/Action.php';
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
echo 'Hello from IndexController';
}
public function noRouteAction()
{
$this->_redirect('/');
}
}
?>
기본 컨트롤러와 액션에 대한 보다 상세한 내용, 그리고 액션 컨트롤러 클래스의 작성 방법에 대해서는 이후의 장에서 설명합니다.
주의 이 장은 아직 미완성입니다. 현재 작성중이며, 향후 바뀔 가능성이 있습니다.
7.1. Zend_Controller 빠른 시작
Zend Framework/7. Zend_Controller | 2007/03/27 22:51
7.1.1. 소개
Zend_Controller는 Zend Framework's MVC 시스템의 핵심입니다. MVC는 모델 - 뷰 - 컨트롤러이고, 응용 로직과 디스플레이 로직을 분리하는 데 목적을 둔 디자인 패턴입니다. Zend_Controller_Front는 Front Controller 패턴을 구현하고, 요청된 URL을 바탕으로 front controller가 모든 요청을 받아서 각각의 Action Controllers에 넘겨 처리합니다.
Zend_Controller 시스템은 확장성을 고려하여 제작되었습니다. 즉, 기존의 클래스를 상속받아, 컨트롤러류 클래스들의 토대를 형성하는 다양한 인터페이스와 추상 클래스를 구현하는 새로운 클래스를 작성하거나, 시스템의 기능성을 늘리거나 처리하기 위한 플러그인이나 액션 도우미를 작성할 수 있습니다.
7.1.2 빠른 시작
만약 보다 상세한 정보가 필요하면, 다음 장들을 보세요. 단지 빨리 실행시켜 보고 싶으면, 계속 읽어 보세요.
7.1.2.1. 파일시스템 레이아웃 만들기
첫번째 단계는 파일 시스템 레이아웃을 만드는 것입니다. 전형적인 레이아웃은 다음과 같습니다.
application/
controllers/
IndexController.php
models/
views/
scripts/
index/
index.phtml
helpers/
filters/
html/
.htaccess
index.php
7.1.2.2. 문서 루트 디렉토리 설정
여러분의 웹서버에서, 위의 파일 시스템 레이아웃의 html 디렉토리로 문서 루트를 설정합니다.
7.1.2.3. rewrite 규칙 만들기
html/.htaccess 파일을 다음과 같이 수정합니다.
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
위의 규칙들은 어떠한 비자원(이미지 파일/ 스타일시트 파일)의 요청들도 front controller로 보냅니다. 만약, 프론트 컨트롤러로부터 제외하고 싶은 다른 확장자들이 있으면(PDF, 텍스트 파일, 기타등등), 그 확장자들을 분기로 추가하던지, 여러분 자체 rewrite 규칙을 만들기 바랍니다.Zend_Controller의 흐름 처리(workflow)는 몇 개의 컴포넌트들로 구현됩니다. 시스템에서 사용하는 이러한 모든 컴포넌트를 완벽하게 이해할 필요는 없지만, 처리에 대한 실용적 지식을 가지는 것은 유용합니다.
Zend_Controller_Front는 Zend_Controller 시스템의 흐름 처리(workflow) 전체를 조율합니다. Zend_Controller_Front는 FrontController 패턴을 설명하는 역할입니다. Zend_Controller_Front는 서버로부터 받은 모든 요청(request)을 처리해서, 최종적으로 그 요청(request)을 ActionController(Zend_Controller_Action)에 전달합니다.
Zend_Controller_Request_Abstract는 요청(request) 환경을 나타내고, 컨트롤러명과 액션명 그리고 요청(request) 매개변수를 설정하거나 검색하는 메소드를 제공합니다. 게다가 액션이 Zend_Controller_Dispatcher에 의해 디스패치 되었는지를 추적하는 기능도 있습니다. 이 추상 요청(request) 객체를 확장해서, 전체 요청(request) 환경을 캡슐화하는 데 사용할 수 있고, 컨트롤러명와 액션명을 설정하기 위해 요청(request) 환경으로부터 라우터에게 정보를 전송하는 할 수 있습니다.
기본값에 의해, Zend_Controller_Request_Http가 이용되고, 이것은 HTTP 요청(request) 환경 전체에 접근 기능을 제공합니다.
Zend_Controller_Router_Interface는 라우터를 정의하는 데 사용됩니다. 경로 지정(Routing)은, 요청(request)을 받는 컨트롤러와 그 컨트롤러의 액션이 어느 것인지 결정하기 위해 요청(request) 환경을 검사하는 처리입니다. 그 다음에, 이 컨트롤러, 액션, 그리고 선택 매개변수들이 Zend_Controller_Dispatcher_Standard에 의해 처리되는 요청(request) 객체에 설정됩니다. 경로 지정(Routing)은 단 한 번만 발생합니다. 즉, 최초로 요청(request)을 받고 첫 컨트롤러가 디스패치 되기 전입니다.
기본 라우터는 Zend_Controller_Router_Rewrite입니다.
기본 라우터인 Zend_Controller_Router_Rewrite는, Zend_Controller_Request_Http로 지정된 URI 종점을 받아서, 그것을 URL에 포함된 경로 정보를 기반으로 컨트롤러, 액션, 그리고 매개변수로 분해시킵니다. 예를 들어, http://localhost/foo/bar/key/value와 같은 URL의 경우, foo가 컨트롤러, bar가 액션, 그리고 value의 값을 가진 매개변수 key로 분해됩니다.
또한, Zend_Controller_Router_Rewrite는 임의의 경로를 지정하는 데 사용될 수도 있습니다. 보다 상세한 사항은 Rewrite Router의 문서를 참조해 주십시오.
Zend_Controller_Dispatcher_Interface는 디스패처를 정의하는 데 사용됩니다. 디스패치란, 컨트롤러와 액션을 요청(request) 객체로부터 받아, 그것을 컨트롤러 클래스에 있는 실제 컨트롤러 파일/클래스와 액션 메소드에 대응시키는 처리입니다. 컨트롤러나 액션이 존재하지 않는 경우에는, 기본 컨트롤러나 액션에 디스패치 합니다.
실제 디스패치 처리에서는, 컨트롤러 클래스의 인스턴스를 생성하고 그 클래스에서 액션 메소드를 호출하는 것으로 구성되어 있습니다. 단지 한 번만 발생하는 경로 지정(Routing)과 달리, 디스패치는 반복해서 발생합니다. 요청(request) 객체의 디스패치 상태가 어느 지점에서 리셋되면, 루프가 반복되며, 현재 요청(request) 객체에서 설정되어 있는 액션이 호출됩니다. 요청(request) 객체의 디스패치 상태가 (true로) 설정되어 처음으로 루프가 종료하면, 처리가 종료됩니다.
기본 디스패처는 Zend_Controller_Dispatcher_Standard 입니다. 이것은, CamelCasedClasses 형식으로 단어의 마지막에 Controller를 붙여서 Controller를 정의하고, 액션 메소드는 camelCasedMethods 형식으로 단어의 끝에 Action을 붙여서 정의합니다. 예를 들어, SomeFooController::barAction 같은 경우, 컨트롤러는 somefoo, 액션은 bar가 됩니다.
Zend_Controller_Action은 기본 컨트롤러 컴퍼넌트입니다. 각 컨트롤러는 이 Zend_Controller_Action 클래스를 상속받는 단일 클래스이고, 이 클래스는 액션 메소드를 가집니다.
Zend_Controller_Response_Abstract는 액션 컨트롤러로부터 응답(response) 내용을 수집하고 반환하는 데 사용되는 기본 응답(response) 클래스입니다. 이것은 헤더와 본문 양쪽 모두를 수집합니다. 왜냐하면 __toString()을 구현하기 때문에, 한 번에 모든 헤더와 본문을 송신하기 위해 직접 출력될 수도 있기 때문입니다.
기본 응답(response) 클래스는 Zend_Controller_Response_Http로, 이것은 HTTP 환경에서 사용하기에 적절합니다.
Zend_Controller의 흐름 처리(workflow)는 비교적 간단합니다. Zend_Controller_Front가 요청(request)을 받아, 어느 컨트롤러 (그리고 그 컨트롤러 내의 액션)로 디스패치 할 지 결정하기 위해 차례로 Zend_Controller_Router_Rewrite를 호출합니다.
Zend_Controller_Router_Rewrite는 요청(request)으로부터 컨트롤러명과 액션명을 설정하기 위해 URI를 분해합니다. 그 후, Zend_Controller_Front는 디스패치 루프에 들어갑니다. 우선 Zend_Controller_Dispatcher_Standard를 호출해서 거기에 요청(request)을 넘겨주고 요청(request)에서 지정된 컨트롤러와 액션(또는 기본값을 사용)을 취득합니다. 컨트롤러가 종료한 후에 컨트롤러는 Zend_Controller_Front로 돌아옵니다. 만약 요청(request)의 디스패치 상태가 리셋되어 다른 컨트롤러를 디스패치하도록 지시받았을 경우에는, 루프가 계속되어 또 다른 디스패치가 수행됩니다. 그 외의 경우에는 처리가 종료합니다.
7.1.2. 요청(request) 객체
요청(request) 객체는 Zend_Controller_Front와 라우터, 디스패처, 그리고 컨트롤러 클래스의 사이에 교환되는 단순한 값을 가진 객체입니다. 이것은 액션으로 넘겨지게 되는, 컨트롤러, 액션, 그리고 매개변수들, 뿐만 아니라 요청(request) 환경(HTTP, CLI, PHP-GTK 등)의 나머지를 정의하는 패키지입니다.
컨트롤러명은 getControllerName()와 setControllerName()에 의해 접근할 수 있습니다.
컨트롤러내에서 호출되는 액션의 이름은 getActionName()와 setActionName()에 의해 접근할 수 있습니다.
액션으로 넘겨지는 매개변수는 키/값으로 된 한쌍의 연관 배열로, getParams()와 setParams()에 의해 접근할 수 있습니다. 또는 그 개개의 데이터에는 getParam()와 setParam()에 의해 접근할 수 있습니다.
요청(request)의 형식에 따라서는, 그 이외의 메소드도 사용할 수 있습니다. 예를 들어, 기본 요청(request)으로 사용되는 Zend_Controller_Request_Http에서는, 요청(request) URI, 경로 정보, $_GET 및 $_POST 매개변수들 등을 검색하기 위한 메소드가 있습니다.
요청(request) 객체는 프론트 컨트롤러에게 넘겨집니다. 만약 요청(request) 객체가 없는 경우에는, 경로 지정이 발생하기 전에, 디스패치 처리의 시작에서 인스턴스가 생성됩니다. 이것은, 디스패치 체인 내의 모든 객체에게 넘겨집니다.
게다가 요청(request) 객체는 테스트 시에 특히 유용합니다. 개발자가 컨트롤러, 액션, 매개변수, URI 등을 포함한 요청(request) 환경을 공들여 만들어서, 애플리케이션의 흐름을 테스트하기 위해 프론트 컨트롤러에 요청(request) 객체를 전송할 수 있습니다. 응답(response) 객체와 조합해 사용하면, MVC 애플리케이션의 정밀하고 정확한 단위 테스트가 가능해집니다.
7.1.3. 경로 지정 처리
첫 컨트롤러를 만들기 전에, 경로 지정(routing) 처리가 Zend_Controller_Router_Rewrite로 어떻게 구현되고 있는지 이해할 필요가 있습니다. 처리 순서는 한 번만 발생하는 경로 지정(routing)과 반복해서 발생하는 디스패치로 나누어 진다는 점을 기억해 두시기 바랍니다.
Zend_Controller_Front는 Zend_Controller_Router_Rewrite (또는 따로 등록된 라우터)를 호출해서, URI를 컨트롤러와 컨트롤러 내에 있는 액션에 대응시킵니다. Zend_Controller_Router_Rewrite는 요청(request) 객체로부터 URI를 검색하여, 체인 내의 라우트 객체에 넘깁니다. 기본값에 의해, 입력 URL을 맞추기 위해 Zend_Controller_Router_Route_Module을 사용합니다. 라우트 객체는 컨트롤러, 액션, 그리고 경로에 포함된 URL 매개변수를 결정하기 위해 URL을 분해합니다. 그리고 나서, 라우터 자신이 이들을 요청(request) 객체에 할당합니다.
Zend_Controller_Router_Route_Module는 컨트롤러명과 컨트롤러 내의 액션명을 결정하기 위해 매우 간단한 매핑법을 사용합니다.
http://framework.zend.com/controller/action/
위의 예로, 첫번째 부분이 항상 컨트롤러의 이름이 되고, 두번째 부분이 항상 액션의 이름이 됩니다.
옵션으로, 컨트롤러에 넘겨지는 매개변수를 URI에 포함할 수 있습니다. 이것은 키/값으로 된 한쌍의 형식이 됩니다.
http://framework.zend.com/controller/action/key1/value1/
컨트롤러나 액션이 URI 패스에 포함되지 않는 경우는, Zend_Controller_Dispatcher_Standard는 요청(request) 객체의 매개변수로부터 값을 검색할려고 합니다. 그것도 발견되지 않는 경우는, 기본값을 사용합니다. 기본값은 컨트롤러도 액션도 "index"가 됩니다. 이러한 예를 아래에서 보여줍니다.
http://framework.zend.com/roadmap/future/
Controller: roadmap
Action : future
http://framework.zend.com/roadmap/
Controller: roadmap
Action : index
http://framework.zend.com/
Controller: index
Action : index
유연성보다 유연한 기능을 사용하고 싶은 경우는, Rewrite Router의 문서를 참고하시기 바랍니다.
컨트롤러명, 컨트롤러 내의 액션명, 그리고 옵션의 매개변수는 요청(request) 객체에 설정되어 있습니다. Zend_Controller_Front가 디스패치에 들어가면, 요청(request) 객체는 Zend_Controller_Dispatcher_Standard에게 넘겨집니다.
7.1.4. 디스패치 처리
디스패치 처리는, Zend_Controller_Request_Abstract인 요청(request) 객체를 받아, 거기에 포함된 컨트롤러명, 액션명 및 옵션의 매개변수를 추출해서, 컨트롤러의 인스턴스를 생성해 그 컨트롤러의 액션을 호출합니다. 컨트롤러나 액션이 발견되지 않는 경우는, 기본값을 사용합니다. Zend_Controller_Dispatcher_Standard에서는, 컨트롤러와 액션의 기본값은 각각 index입니다. 그러나, 개발자는 setDefaultController()와 setDefaultAction() 메소드를 사용해서 변경할 수도 있습니다.
디스패치 처리는 프론트 컨트롤러의 루프 안에서 발생합니다. 디스패치 처리를 하기 전에, 사용자가 지정한 컨트롤러, 액션, 그리고 추가 매개변수를 찾기 위해 요청(request)으로부터 경로를 찾습니다. 그리고나서, 디스패치 루프로 들어가 요청(request)을 디스패치 합니다.
각 루프의 시작 지점에서, 요청(request) 객체에 액션이 디스패치 되었다는 것을 나타내는 플래그를 설정합니다. 액션이나 pre/postDispatch() 플러그인이 그 플래그를 리셋하면, 디스패치 루프는 계속하고 다시 요청(request)을 디스패치 할려고 시도할 것입니다. 요청(request) 내의 컨트롤러나 액션을 변경해 플래그를 리셋하는 것으로, 다양한 요청(request)을 계속해서 실행시킬 수 있습니다.
그런 디스패치 처리를 제어하는 액션 컨트롤러 메소드가 _forward()입니다. 새로운 액션에 보내고 싶은 컨트롤러, 액션, 부가적인 매개변수를 포함해서, pre/postDispatch()나 액션 메소드에서 이 _forward() 메소드를 호출합니다.
public function myAction()
{
// 어떤 처리를 합니다...
// 현재 모듈 내의 또다른 액션 FooController::barAction()로 전송합니다
$this->_forward('bar', 'foo', null, array('baz' => 'bogus'));
}
7.1.5. 응답(response) 객체
응답(response) 객체는 요청(request) 객체와 논리적으로 한 쌍입니다. 그 목적은 내용이나 헤더를 수집해서, 그것을 한 묶음으로 반환하는 것입니다. 게다가 프론트 컨트롤러가 어떤 예외를 잡으면, 개발자가 우아하게 예외를 처리하도록, 응답(response) 객체에 넘깁니다. 이 상관 관계는 Zend_Controller_Front::throwExceptions(true)로 설정함으로써 오버라이드 될 수 있습니다.
$front->throwExceptions(true);
헤더를 포함한 응답(response) 출력을 보낼려면, sendOutput()을 사용합니다.
$response->sendOutput();
개발자는 액션 컨트롤러 내에 있는 응답(response) 객체를 사용해야만 합니다. 출력을 직접 렌더링하거나 직접 헤더를 전송하는 것이 아니라, 그것들을 응답(response) 객체에 설정합니다.
//액션 컨트롤러의 액션내에서:
//헤더를 설정합니다
$this->getResponse()
->setHeader('Content-Type', 'text/html')
->appendBody($content);
이렇게 함으로써, 모든 헤더를 한 번에 송신하고 바로 그 후에 내용을 출력할 수 있습니다.
애플리케이션에서 예외가 발생했는지를 조사하려면, 응답(response) 객체의 isException() 플래그를 확인합니다. 예외를 취득하려면 getException()을 사용합니다. 더욱이 에러 페이지로 연결하거나, 예외 메시지의 로그 출력하거나, (개발 환경을 위해서) 예외 메시지의 알기쉬운 형식으로 만들거나 하는 등의 커스텀 응답(custom response) 객체를 만들 수도 있습니다.
응답(response) 객체는 프론트 컨트롤러의 dispatch()로부터 받거나, 또는 출력을 렌더링하지 않은 상태의 응답(response) 객체를 프론트 컨트롤러로부터 받을 수도 있습니다.
// 프론트 컨트롤러 dispatch() 후에 취득합니다.
$front->dispatch();
$response = $front->getResponse();
if ($response->isException()) {
// log, mail, etc...
}
// 또는, 프론트 컨트롤러 dispatch()의 반환값을 사용합니다.
$front->returnResponse(true);
$response = $front->dispatch();
// 어떤 처리를 합니다...
// 마지막으로, 응답을 표시합니다.
$response->sendResponse();
기본값에 의해, 예외 메세지는 표시되지 않습니다. 이 행동을 renderExceptions() 메소드를 호출하거나, 또는 위에서 설명한 것처럼 프론트 컨트롤러로 throwExceptions()을 유효하게 함으로써 오버라이드 될 수 있습니다.
$response->renderExceptions(true);
$front->dispatch($request, $response);
// 또는:
$front->returnResponse(true);
$response = $front->dispatch();
$response->renderExceptions();
$response->sendOutput();
// 또는:
$front->throwExceptions(true);
$front->dispatch();
6.4. Zend_Console_Getopt의 설정
Zend Framework/6. Zend_Console_Getopt | 2007/03/20 23:57
6.4.1. 옵션 규칙들의 추가
addRules() 메소드를 사용하여, Zend_Console_Getopt 생성자에서 지정된 옵션들을 이외에 추가로 옵션의 규칙들을 지정할 수 있습니다. addRules()에 넘기는 인수는, 클래스 생성자의 첫번째 인수와 같습니다. 그것은 짧은 형식의 옵션 지정을 나타내는 문자열 또는 긴 형식의 옵션 지정을 나타내는 연관 배열이 됩니다. 옵션을 지정하는 구문의 상세한 것은, Getopt 규칙의 선언을 참조해 주십시오.
예제 6.7. addRules()의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$opts->addRules(
array(
'verbose|v' => 'Print verbose output'
)
);
?>
위의 예제는 생성자로 정의한 옵션들의 집합에 "-v"의 앨리어스(alias)를 가진 "--verbose" 옵션을 추가하는 것을 보여주고 있습니다. Zend_Console_Getopt의 동일한 인스턴스에서 짧은 형식의 옵션과 긴 형식의 옵션이 공존할 수 있는 것을 주의합시다.
6.4.2. 도움말 메세지의 추가
긴 형식의 옵션 규칙을 선언할 때 도움말 문자열을 지정하는 것뿐만 아니라, setHelp() 메소드를 사용하여 옵션 규칙들을 가진 도움말 문자열을 연관지을 수 있습니다. setHelp() 메소드의 인수는 연관 배열로, 키가 플래그명 값이 대응하는 도움말 문자열이 됩니다.
예제 6.8. setHelp()의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$opts->setHelp(
array(
'a' => '이 옵션은 사과를 선택합니다. 매개변수는 불필요합니다',
'b' => '이 옵션은 바나나를 선택합니다. 정수 매개변수가 필수입니다',
'p' => '이 옵션은 배를 선택합니다. 옵션으로 문자열 매개변수를 지정합니다'
)
);
?>
앨리어스(alias)를 가진 옵션을 선언했을 때, 연관 배열의 키로써 어떤 앨리어스(alias)라도 사용할 수 있습니다.
짧은 구문으로 옵션을 선언했을 경우, setHelp() 메소드가 도움말 문자열을 설정하기 위한 유일한 수단이 됩니다.
6.4.3. 옵션 앨리어스(alias) 추가
setAliases 메소드를 사용하여 옵션의 앨리어스(alias)를 선언할 수 있습니다. 인수는 연관 배열로, 키는 방금 전에 선언한 플래그 문자열이고, 값은 그 플래그의 새로운 앨리어스(alias)입니다. 이들 앨리어스(alias)는 기존의 앨리어스(alias)들과 병합됩니다. 바꾸어 말하면, 이전에 선언했던 앨리어스(alias)도 여전히 유효하다는 것입니다.
앨리어스(alias)는 한 번 밖에 선언할 수 없습니다. 기존의 앨리어스(alias)를 재정의하려고 하면, Zend_Console_Getopt_Exception이 발생합니다.
예제 6.9. setAliases() 의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$opts->setAliases(
array(
'a' => 'apple',
'a' => 'apfel',
'p' => 'pear'
)
);
?>
위의 예에서는, 이들 앨리어스(alias)를 선언한 후, "-a"를 "--apple" 및 "--apfel"로 서로에게 앨리어스(alias) 설정을 한 것입니다. "-p"와 "--pear"로 서로에게 앨리어스(alias) 설정을 하고 있습니다.
짧은 구문으로 옵션을 선언했을 경우, setAliases() 메소드가 앨리어스(alias)를 정의하는 유일한 방법입니다.
6.4.4. 인수 리스트의 추가
기본값에 의해, Zend_Console_Getopt는 $_SERVER['argv']의 배열을 사용해 명령행 인수를 구문 분석 합니다. 또한 생성자의 두번째의 인수로서 인수를 포함한 다른 배열을 지정할 수도 있습니다. 마지막으로 addArguments() 메소드를 사용해서 기존에 사용하던 인수에 또다른 인수를 추가하거나, setArguments() 메소드를 사용해서 현재 인수의 배열을 대체할 수도 있습니다.
예제 6.10. addArguments() 및 setArguments()의 사용법
// 기본값에 의해, 생성자는 $_SERVER['argv']를 사용합니다
$opts = new Zend_Console_Getopt('abp:');
// 기존의 인수에 배열을 추가합니다.
$opts->addArguments(array('-a', '-p', 'p_parameter', 'non_option_arg'));
// 새로운 배열로 기존의 인수를 설정합니다
$opts->setArguments(array('-a', '-p', 'p_parameter', 'non_option_arg'));
?>
6.4.5. 설정의 추가
Zend_Console_Getopt 생성자의 세번째 인수는 설정 옵션의 배열입니다. 반환되는 객체 인스턴스의 행동을 설정하는 것입니다. 또한, setOptions() 메소드를 사용해서 설정 옵션들을 지정할 수 있습니다. 또는 setOption() 메소드를 사용해서 개별 옵션을 설정할 수도 있습니다.
"옵션"이라고 하는 용어에 대해 여기서 말하는 "옵션"은, 다른 경우에 사용되는 전문용어와 부합되는, Zend_Console_Getopt 클래스의 설정을 위해 사용되는 것을 가리키고 있습니다. 이 용어는 Zend_Console_Getopt 클래스에 의해 구문 분석되는 명령행 옵션과 동일한 의미가 아닙니다.
현재 지원하고 있는 옵션은 클래스에서 상수로 정의되고 있습니다. 옵션과 거기에 대응하는 상수 식별자(괄호 내의 문자 값을 포함해서)를 아래에서 설명합니다.
Zend_Console_Getopt::CONFIG_DASHDASH("dashDash")를 true로 하면, 플래그의 종료를 나타내는 특수 플래그 "--"를 유효하게 합니다. 이중 대시의 뒤에 이어지는 명령행 인수는, 비록 인수가 대시로 시작하지만, 옵션으로써 해석되지 않습니다. 이 설정 옵션의 기본값은 true입니다.
Zend_Console_Getopt::CONFIG_IGNORECASE("ignoreCase")를 true로 하면, 대문자 소문자만 다를 경우에, 플래그를 서로 앨리어스(alias)로서 취급합니다. 즉 ,"-a"와 "-A"는 동일한 플래그로 간주합니다. 이 설정 옵션의 기본값은 false입니다.
Zend_Console_Getopt::CONFIG_RULEMODE("ruleMode")는 Zend_Console_Getopt::MODE_ZEND("zend") 또는 Zend_Console_Getopt::MODE_GNU("gnu") 값을 가집니다. 특별한 구문 형식을 가진 클래스를 확장하는 것이 아니면, 이 옵션을 사용할 필요는 없습니다. 기본 Zend_Console_Getopt 클래스에서 지원되는 두 가지 방식은 명백합니다. 문자열을 지정하면 클래스는 MODE_GNU, 그 이외의 경우는 MODE_ZEND로 간주합니다. 만약 클래스를 확장해 다른 구문 형식을 추가한다면, 이 옵션을 사용해서 그 방식을 지정할 필요가 있습니다.
앞으로, 보다 더 많은 설정 옵션이 이 클래스에 추가될 예정입니다.
setOption() 메소드에 넘겨주는 두 가지 인수는 설정 옵션명과 그 옵션값입니다.
예제 6.11. setOption()의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$opts->setOption('ignoreCase', true);
?>
setOptions() 메소드에 넘겨주는 인수는 연관 배열입니다. 이 배열의 키는 설정 옵션명이고, 값은 설정값이 됩니다. 또한, 이것은 클래스 생성자에서 사용되는 배열 형식입니다. 지정한 설정값이 기존의 설정과 합쳐지므로, 모든 옵션을 지정할 필요는 없습니다.
예제 6.12. setOptions()의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$opts->setOptions(
array(
'ignoreCase' => true,
'dashDash' => false
)
);
?>
6.3. 옵션 및 인수의 취득
Zend Framework/6. Zend_Console_Getopt | 2007/03/20 23:41
Zend_Console_Getopt 객체가 인지한 옵션들을 선언한 후, 명령행 또는 배열로부터 인수들을 받으면, 프로그램의 주어진 명령행 호출에서 사용자가 지정한 옵션들을 찾아내도록 객체를 질의할 수 있다. 이 클래스는 매직 메소드를 구현하고 있으므로, 옵션의 이름을 지정해 질의할 수 있습니다.
옵션이 주어졌는지 찾아내기 위해 Zend_Console_Getopt 객체에 대해 최초의 질의가 구문을 분석하기 전까지 데이터의 구문 분석은 연기됩니다. 즉, 구문을 분석하기 전에 몇 개의 메소드로 옵션, 인수, 도움말 문자열, 그리고 설정 항목을 변경할 수 있습니다.
6.3.1. Getopt의 예외 처리
사용자가 명령행으로 잘못된 인수를 지정하면, 구문 분석 함수는 Zend_Console_Getopt_Exception을 발생합니다. 이 예외는 애플리케이션의 코드에서 처리해야 합니다. 객체에 인수의 구문을 분석시키기 위해 parse() 메소드를 사용할 수 있습니다. try 구문 내에서 parse()를 실행할 수 있으므로 편리합니다. 구문분석이 성공하면, 그 이후에 다시 예외가 발생될 일은 없습니다. 발생된 예외는 커스텀 메소드 getUsageMessage()를 사용할 수 있습니다. 이것은 선언되어 있는 모든 옵션에 대한 사용법을 설명한 문자열을 반환합니다.
예제 6.3. Getopt의 예외 처리
<?php
try {
$opts = new Zend_Console_Getopt('abp:');
$opts->parse();
} catch (Zend_Console_Getopt_Exception $e) {
echo $e->getUsageMessage();
exit;
}
?>
예외가 발생하는 것은, 다음과 같은 경우입니다.
지정한 옵션을 인식할 수 없는 경우
매개변수가 필요한 옵션이지만, 매개변수가 주어지지 않는 경우
옵션의 매개변수가 잘못된 형식인 경우. 예를 들어 정수형을 요구하는 옵션에 비수치 문자열이 주어졌을 경우 등
6.3.2. 이름에 의한 옵션의 취득
옵션의 값을 질의하기 위해 getOption() 메소드를 사용할 수 있습니다. 그 옵션이 매개변수를 가지고 있으면, 이 메소드는 매개변수의 값을 반환합니다. 옵션이 매개변수를 가지고 있지 않지만, 사용자가 명령행으로 매개변수를 지정한다면, 이 메소드는 true를 반환합니다. 그 이외의 경우 이 메소드는 null을 반환합니다.
예제 6.4. getOption()의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$b = $opts->getOption('b');
$p_parameter = $opts->getOption('p');
?>
또는, 마치 클래스의 멤버 변수인 것처럼 옵션의 값을 검색하기 위해 매직 __get() 함수를 사용할 수도 있습니다. __isset() 매직 메소드도 구현되고 있습니다.
예제 6.5. 매직 메소드 __get() 및 __isset()의 사용예
<?php
$opts = new Zend_Console_Getopt('abp:');
if (isset($opts->b)) {
echo "I got the b option.\n";
}
$p_parameter = $opts->p; // null if not set
?>
옵션에 앨리어스(alias)가 지정되어 있는 경우는, 위의 방법으로 그 앨리어스(alias)를 사용할 수도 있습니다.
6.3.3. 옵션의 보고
사용자가 명령행으로 입력한 모든 옵션을 보고하기 위한 몇 가지 방법들이 있습니다.
문자열로써 : toString() 메소드를 사용합니다. 옵션들은 "flag=value" 형식의 공백으로 분리된 문자열로써 반환됩니다. 매개변수를 가지지 않는 옵션의 값은 리터럴(literal) 문자열 "true"가 됩니다.
배열로써 : toArray() 메소드를 사용합니다. 옵션들은 문자열의 단순형 정수 인덱스를 가진 배열로 반환됩니다. 만약 있으면, 플래그 문자열 뒤에 매개변수 문자열이 붙습니다.
JSON 데이터를 포함한 문자열로써 : toJson() 메소드를 사용합니다.
XML 데이터를 포함한 문자열로써 : toXml() 메소드를 사용합니다.
위에 언급된 모든 출력 메소드에서, 앨리어스(alias)들에 대응하는 목록에서 첫번째 문자열이 플래그 문자열이 됩니다. 예를 들어, 옵션의 앨리어스(alias)가 "verbose| v"와 같이 선언되었다면, 첫 문자열인 "verbose"를 옵션의 기본적인 이름으로 사용합니다. 옵션 플래그의 이름은 선두의 대시를 포함하지 않습니다.
6.3.4. 비옵션 인수들의 취득
옵션 인수 및 그 매개변수를 명령행으로부터 구문 분석한 후에도, 아직 추가의 인수가 남아 있을지도 모릅니다. 이러한 인수들에 대한 질의는 geRemainingArgs() 메소드를 사용합니다. 이 메소드는, 어느 옵션에도 속하지 않는 문자열의 배열을 반환합니다.
예제 6.6. getRemainingArgs()의 사용법
<?php
$opts = new Zend_Console_Getopt('abp:');
$opts->setArguments(array('-p', 'p_parameter', 'filename'));
$args = $opts->getRemainingArgs(); // array('filename')를 반환
?>
Zend_Console_Getopt는 '이중 대시로 된 인수는 옵션들의 마지막으로 간주한다'라는 GNU 규약을 제공합니다. 그 이후에 이어지는 인수는 비옵션 인수로서 취급해야만 합니다. 이것은, 옵션이 아닌 인수가 대시로 시작되는 경우 등에 유용합니다. 예를 들면, "rm -- -filename-with-dash"와 같은 경우입니다.
6.2. Getopt 규칙의 선언
Zend Framework/6. Zend_Console_Getopt | 2007/03/19 21:46
Zend_Console_Getopt 클래스의 생성자는 하나로부터 세 개의 인수를 받습니다. 첫 인수는 이 애플리케이션에 의해 지원되는 옵션을 선언합니다. 이 클래스는 옵션을 선언하기 위한 또 하나의 구문도 지원하고 있습니다. 아래 섹션에서 이러한 구문에 대한 서식이나 사용법을 참조해 주십시오.
생성자는 또한 두 개의 인수를 받습니다. 이들 두 개는 옵션입니다. 두번째 인수는 명령행 인수들을 포함합니다. 기본값은 $_SERVER['argv'] 입니다.
생성자의 세번째 인수는 Zend_Console_Getopt의 행동을 커스터마이즈하기 위한 설정 옵션을 포함합니다. 사용 가능한 옵션에 대해서는 메뉴얼의 "6.4.5 설정의 추가"를 참조해 주십시오.
6.2.1. 짧은 형식의 옵션 선언
Zend_Console_Getopt는, GNU Getopt에서 사용되는 것과 유사한 형식의 간결한 구문을 지원하고 있습니다 (http://www.gnu.org/software/libc/manual/html_node/Getopt.html를 참조해 주십시오). 이 구문은, 한 문자의 플래그에서만 사용할 수 있습니다. 애플리케이션에 의해 지원되는 플래그들에 대응하는 문자를, 하나의 문자열로 합쳐서 지정합니다. 문자의 뒤에 콜론 문자(":")가 붙어 있으면, 매개변수를 요구하는 플래그라는 것을 의미합니다.
예제 6.1. 짧은 형식의 구문 사용
<?php
require_once 'Zend/Console/Getopt.php';
$opts = new Zend_Console_Getopt('abp:');
?>
위의 예는, Zend_Console_Getopt를 이용해서, 사용하는 옵션을 "-a","-b", 또는 "-p"라고 선언하는 것을 보여주고 있습니다. 마지막 플래그에는 매개변수가 필요합니다.
짧은 구문을 사용할 수 있는 것은, 한 문자의 플래그에 한정됩니다. 앨리어스(alias)나 매개변수형, 도움말 문자열은 짧은 구문에서는 지원하지 않습니다.
6.2.2. 긴 형식의 옵션 선언
보다 특징있는 다른 구문도 지원하고 있습니다. 이 구문에서는, 플래그에 앨리어스(alias)를 설정하거나 옵션 매개변수의 형태를 지정하거나 사용자에게 사용법을 나타내는 도움말 문자열을 지정할 수 있습니다. 짧은 구문의 옵션을 선언하는 경우에는 문자열을 사용했지만, 긴 구문의 경우는 연관 배열을 사용합니다. 이것을 생성자의 첫 인수로서 지정합니다.
연관 배열의 각 요소의 키는, 플래그의 이름과 앨리어스(alias)를 파이프 기호("|")로 연결한 문자열이 됩니다. 그 옵션이 매개변수를 필요로 하면, 플래그에 이어 등호("=")를 쓰고 그 뒤에 매개변수의 형식을 나타내는 문자를 붙입니다.
"=s"는 문자열 매개변수를 나타냅니다.
"=w"는 워드 매개변수(공백을 포함하지 않는 문자열)을 나타냅니다.
"=i"는 정수 매개변수를 나타냅니다.
만약 그 매개변수가 옵션인 경우는, 등호 대신에 대시("-")를 사용합니다.
연관 배열에서 각 요소의 값은, 사용자에게 프로그램의 사용법을 설명하는 도움말 문자열입니다.
예제 6.2. 긴 형식의 구문 사용
<?php
require_once 'Zend/Console/Getopt.php';
$opts = new Zend_Console_Getopt(
array(
'apple|a' => 'This option chooses apple, with no parameter',
'banana|b=i' => 'This option chooses banana, with required integer parameter',
'pear|p-s' => 'This option chooses pear, with optional string parameter'
)
);
?>
위의 예에서는 세 종류의 옵션을 선언하고 있습니다. "--apple" 및 "-a"는 같은 의미를 가지는 앨리어스(alias)로, 이 옵션은 매개변수를 받지 않습니다. "--banana" 및 "-b"는 같은 의미를 가지는 앨리어스(alias)로, 이 옵션은 정수의 매개변수가 필수가 됩니다. 마지막에 "--pear" 및 "-p"는 같은 의미를 가지는 앨리어스(alias)로, 이 옵션은 임의로 문자열 매개변수를 받을 수 있습니다.




