'분류 전체보기'에 해당되는 글 31건
- 2015.05.11 테스트 데이터 생성
- 2015.05.08 [CakePHP] Controller - Components
- 2015.05.08 [CakePHP] Controller - PageController
- 2015.05.08 [CakePHP] Controller - Scaffolding
- 2015.05.07 [CakePHP] CakeResponse
- 2015.05.07 [CakePHP] CakeRequest 요청 객체
- 2015.05.06 cakePhp- controller
- 2015.04.29 HAProxy 설치
- 2015.04.29 keepalived 로드 밸런서의 이중화
- 2015.04.29 Javascript 템프릿
컴포넌트
컴포넌트는 컨트롤러간에 공유되는 로직의 패키지입니다. 만약 컨트롤러간에 복사 및 붙여 넣기를 하고 싶은 부분이 있다면 몇 가지 기능을 컴포넌트로 랩핑 할 수 있을지도 모릅니다.
또한 CakePHP는 다음과 같은 목적으로 사용할 수있는 훌륭한 핵심 컴포넌트가 준비되어 있습니다. :
- 보안
- 세션
- 액세스 제어
- 이메일
- 쿠키
- 인증
- 요청 처리
- 페이지 전환
각 핵심 컴포넌트의 자세한 것은 각 장에서 설명합니다. 여기에서 독자적인 컴포넌트를 만드는 방법을 소개합니다. 컴포넌트를 작성함으로인해 컨트롤러의 코드가 깨끗한 상태로 유지되고 프로젝트에서 코드를 재사용하기 쉬워집니다.
컴포넌트의 설정
핵심 컴포넌트의 대부분은 설정을 필요로하고 있습니다. 컴포넌트가 설정을 필요로하고있는 예는 인증 과 Cookie 등입니다. 이러한 컴포넌트와 일반 컴포넌트의 설정은 대부분의 경우 $components 배열이나 컨트롤러의 beforeFilter() 메소드에서 이루어집니다. :
class PostsController extends AppController {
public $components = array(
'Auth'=> array(
'authorize'=> array( 'controller')
'loginAction'=> array( 'controller'=> 'users', 'action'=> 'login')
),
'Cookie'=> array( 'name'=> 'CookieMonster')
);
이것은 $components 배열 요소를 설정하는 예입니다. 모든 핵심 컴포넌트는 이 방법으로 설정할 수 있습니다. 또한 컨트롤러의 beforeFilter() 메소드에서도 설정할 수 있습니다. 이것은 함수의 결과를 컴포넌트의 프로퍼티에 설정할 때 유용합니다. 위의 예는 다음과 같이 작성됩니다. :
public function beforeFilter() {
$this -> Auth -> authorize = array( 'controller');
$this -> Auth -> loginAction = array( 'controller'=> 'users', 'action'=> 'login');
$this -> Cookie -> name = 'CookieMonster';
}
그러나 컴포넌트의 옵션을 컨트롤러의 beforeFilter()
가 실행되기 전에 설정하는 것이 가능한 경우도 있습니다. 즉, 컴포넌트 중에는 $components
배열에 옵션을 설정할 수있는 것이 있습니다. :
public $components = array(
'DebugKit.Toolbar'=> array( 'panels'=> array( 'history', 'session'))
);
각 컴포넌트가 어떤 설정 옵션을 제공하는지는 관련 문서를 참조하십시오.
공통 설정 중 하나에 className 옵션이 있습니다. 이 옵션을 사용하면 컴포넌트에 별명을 붙일 수 있습니다. 이 기능은 $this-> Auth 및 기타 컴포넌트의 참조를 자체적으로 구현하여 대체하고 싶을 때 유용합니다. :
// app/Controller/PostsController.php
class PostsController extends AppController {
public $components = array(
'Auth'=> array(
'className'=> 'MyAuth'
)
);
}
// app/Controller/Component/MyAuthComponent.php
App :: uses( 'AuthComponent', 'Controller/Component');
class MyAuthComponent extends AuthComponent {
// 코어 AuthComponent를 덮어쓸 코드를 추가
}
위의 예에서는 컨트롤러에서 MyAuthComponent에 $this-> Auth라는 별명을 달고 있습니다.
별명을 붙인 컴포넌트는 컴포넌트가 사용하는 모든 곳의 인스턴스를 바꿉니다. 이것은 다른 컴포넌트의 내부를 포함합니다.
컴포넌트의 사용
일단 컴포넌트를 컨트롤에서 읽어 들였다면 사용하는 것은 매우 간단합니다. 사용중인 각 컴포넌트는 컨트롤러의 속성처럼 보입니다. 만일 SessionComponent 와 CookieComponent 를 컨트롤러로 읽어 들인 경우 다음과 같이 액세스 할 수 있습니다. :
class PostsController extends AppController {
public $components = array( 'Session', 'Cookie');
public function delete() {
if($this -> Post -> delete($this -> request -> data( 'Post.id')) {
$this -> Session -> setFlash( 'Post deleted.');
return $this -> redirect(array( 'action'=> 'index'));
}
}
모델과 컴포넌트 모두가 컨트롤러에 속성으로 추가되므로, 그들은 같은 ‘네임 스페이스’를 공유합니다. 컴포넌트와 모델에 같은 이름을 사용하지 않도록 주의하십시오.
컴포넌트의 동적 로딩
모든 컨트롤러 액션에서 모든 컴포넌트를 사용할 수 있도록 할 필요는 없을지도 모릅니다. 이러한 상황에서는 런타임에 컴포넌트 컬렉션을 사용하여 컴포넌트를 로드 할 수 있습니다. 컨트롤러 내부에서 다음과 같이 할 수 있습니다. :
$this -> OneTimer = $this -> Components -> load( 'OneTimer');
$this -> OneTimer -> getTime();
컴포넌트가 동적으로 로드 된 경우 초기화 메소드가 실행되지 않는 것을 기억하십시오. 이 메소드에서 읽어 들인 경우 로드 된 후 수동으로 실행해야합니다.
컴포넌트의 콜백
컴포넌트는 또한 몇 가지 요청 라이프 사이클에 요청 라이프 사이클을 늘릴 수 있는 콜백을 제공합니다. 컴포넌트가 제공하는 컴포넌트에 대한 자세한 내용은 컴포넌트 API 의 기본을 참조하십시오.
컴포넌트를 만들
응용 프로그램의 다양한 부분에서 복잡한 수학적 처리를 필요로하는 온라인 응용 프로그램을 가정합니다. 이제 컨트롤러의 곳곳에서 사용하기위한 공유 로직을 통합하기위한 컴포넌트를 만듭니다.
먼저, 새로운 컴포넌트 파일과 클래스를 만듭니다. /app/Controller/Component/MathComponent.php
에 파일을 작성하십시오. 컴포넌트의 기본 구조는 다음과 같습니다. :
App :: uses( 'Component', 'Controller');
class MathComponent extends Component {
public function doComplexOperation($amount1 $amount2) {
return $amount1 + $amount2;
}
}
모든 컴포넌트는 Component 를 상속해야합니다. 상속되지 않은 경우, 예외가 발생합니다.
컨트롤러에서 컴포넌트를 로드
일단 컴포넌트가 완성되고 나면 컨트롤러의 $components 배열에있는 요소 이름(Component의 부분을 제거하는)을 대체하여 사용할 수있게합니다. 컨트롤러는 그 컴포넌트에 유래하는 새로운 속성을 자동으로 부여되는 것입니다. 그 속성을 통해 인스턴스에 액세스 할 수 있습니다. :
/* 표준 $this-> Session뿐만 아니라 새로운 요소를 $this-> Math에서 사용할 수있게합니다. * /
public $components = array( 'Math', 'Session');
AppController
에서 선언 된 컴포넌트는 다른 컨트롤러에서 선언 된 컴포넌트와 병합됩니다. 동일한 컴포넌트를 두 번 선언 할 필요는 없습니다.
컨트롤러에서 컴포넌트를 읽어 들일 때 컴포넌트의 생성자에 전달 파라메타를 선언 할 수 있습니다. 이 매개 변수는 컴포넌트에 의해 처리됩니다. :
public $components = array(
'Math'=> array(
'precision'=> 2,
'randomGenerator'=> 'srand'
),
'Session', 'Auth'
);
위의 예에서는 precision와 randomGenerator를 포함한 배열이 MathComponent :: __ construct()의 두 번째 인수로 전달됩니다. 컴포넌트의 공용 속성이나 인수로 전달되는 설정은 배열에 따라 값입니다.
컴포넌트에서 다른 컴포넌트를 사용
작성중인 컴포넌트에서 다른 컴포넌트를 사용하고 싶을 때이 가끔 있습니다. 그 경우 작성중인 컴포넌트에서 다른 컴포넌트를 로드 할 수 있으며, 그 방법은 컨트롤러에서 $components 변수를 사용하여 가져 오는 경우와 동일합니다. :
// app/Controller/Component/CustomComponent.php
App :: uses( 'Component', 'Controller');
class CustomComponent extends Component {
// 구현중인 컴포넌트를 사용하는 다른 컴포넌트
public $components = array( 'Existing');
public function initialize(Controller $controller) {
$this -> Existing -> foo();
}
public function bar() {
// ...
}
}
// app/Controller/Component/ExistingComponent.php
App :: uses( 'Component', 'Controller');
class ExistingComponent extends Component {
public function foo() {
// ...
}
}
컨트롤러에서 가져온 컴포넌트와 달리 컴포넌트에서 컴포넌트를 가져온 경우 콜백이 불리지 않는 점에 유의하십시오.
컴포넌트 API
class
Component
컴포넌트의 기본 클래스는 ComponentCollection
통해 공통의 핸들링 설정을 처리하도록 다른 컴포넌트를 지연로드 하기위한 여러 가지 방법을 제공합니다. 또한 컴포넌트의 모든 콜백의 프로토 타입을 제공합니다.
Component :: __construct
(ComponentCollection $collection, $settings = array())
기본 컴포넌트 클래스의 생성자입니다. 모든 $settings
또는 공용 속성은 $settings
에서 일치하는 값으로 변경됩니다.
콜백
Component :: initialize
(Controller $controller)
initialize 메소드는 컨트롤러의 beforeFilter 전에 호출됩니다.
Component :: startup(Controller $controller)
startup 메소드는 컨트롤러의 beforeFilter 후 컨트롤러의 현재의 액션 핸들러 전에 호출됩니다.
Component :: beforeRender(Controller $controller)
beforeRender 메소드는 컨트롤러가 요청한 액션의 로직을 실행 한 후 뷰와 레이아웃이 그려지기 전에 호출됩니다.
Component :: shutdown(Controller $controller)
shutdown 메소드는 출력 결과가 브라우저로 전송되기 전에 호출됩니다.
Component :: beforeRedirect(Controller $controller $url, $status = null $exit = true)
beforeRedirect 메서드는 컨트롤러 redirect 메소드가 불려 때 다른 액션보다 먼저 불려집니다. 이 메소드가 false를 반환 할 때 컨트롤러는 Request 리디렉션을 중단합니다. $url, $status와 $exit 변수는 컨트롤러의 메소드와 같은 의미입니다. 또한 리디렉션 URL 문자열을 반환하거나 ‘url’와 ‘status’와 ‘exit’를 키로 가지는 연관 배열을 반환 할 수 있습니다. ‘status’와 ‘exit’는 선택 사항입니다.
'PHP' 카테고리의 다른 글
CakePHP - 뷰 - 테마 (0) | 2015.05.13 |
---|---|
CakePHP - View (0) | 2015.05.12 |
[CakePHP] Controller - PageController (0) | 2015.05.08 |
[CakePHP] Controller - Scaffolding (0) | 2015.05.08 |
[CakePHP] CakeResponse (0) | 2015.05.07 |
페이지 컨트롤러
CakePHP는 기본 컨트롤러 PagesController.php
를 제공합니다. 이것은 정적 콘텐츠를 제공하기위한 간단하고 보조적인 컨트롤러입니다. 설치 직후의 홈페이지는 컨트롤러를 사용해 생성되어 있습니다. 만약 app/View/Pages/about_us.ctp
는 뷰 파일을 만들면 http://example.com/pages/about_us
라는 URL로 액세스 할 수 있습니다. Pages Controller는 필요에 따라 언제든지 수정할 수 있습니다.
CakePHP 콘솔 유틸리티 “bake”을 사용하여 새 응용 프로그램을 굽는하면 PagesController는 app/Controller/
폴더에 만들어집니다. 또한 lib/Cake/Console/Templates/skel/Controller/PagesController.php
에서 파일을 복사 할 수 있습니다.
버전 2.1에서 변경 : CakePHP 2.0 Pages Controller는 lib/Cake의 일부였습니다. 2.1에서 Pages Controller는 코어의 일부가 없으며 app 폴더에 제공되게되었습니다.
미래 핵심이 업데이트되었을 때 문제를 피하기 위해 lib/Cake 폴더에있는 모든 파일도 직접 편집하지 마십시오.
'PHP' 카테고리의 다른 글
CakePHP - View (0) | 2015.05.12 |
---|---|
[CakePHP] Controller - Components (0) | 2015.05.08 |
[CakePHP] Controller - Scaffolding (0) | 2015.05.08 |
[CakePHP] CakeResponse (0) | 2015.05.07 |
[CakePHP] CakeRequest 요청 객체 (0) | 2015.05.07 |
Scaffolding
응용 프로그램의 스캐 폴딩(scaffolding)은 개발자가 객체를 생성, 검색, 업데이트, 삭제 등 기본적인 어플리케이션을 정의, 생성하는 테크닉 입니다. CakePHP의 스캐 폴딩은 개체들이 서로 어떻게 관련되어 있는지를 정의하고 그 연결의 생성 및 삭제가 가능합니다.
scaffold를 만들려면 모델과 컨트롤러가 필요합니다. 컨트롤러에 $scaffold 변수를 설정하는 것만으로 동작합니다.
CakePHP의 스캐 폴딩은 꽤 훌륭합니다. 기본적인 CRUD 애플리케이션을 몇 분 안에 만들어 움직일 수 있습니다. 너무 좋기 때문에 프로덕션 환경에서 사용하고 싶을지도 모릅니다. 정말 좋은 것입니다만, 스캐 폴딩은 어디 까지나 단순한 발판에 불과하다는 것을 명심 하십시오. 발판은 프로젝트의 초기 단계에서 어쨌든 빨리 움직이게 하기 위해 거친 구조로되어 있습니다. 유연성이보다는 어쨌든 움직이기위한 일시적인 방법이라고 말할 수 있겠지요. 만약 로직과 뷰를 직접 정의하고 싶습니다 시작하면 코드를 작성하는 발판을 사용하는 것을 그만 둘 타이밍이라고 말할 수 있습니다. 다음 장에서 설명하는 CakePHP의 Bake 콘솔은 굉장한 다음 한걸음이며, 현재의 발판과 같은 결과가 되는 코드를 생성합니다.
스캐 폴딩은 web 어플리케이션 개발 초기에 필요한 코드를 얻을 수있는 좋은 방법입니다. 설계 초기 단계에서 데이터베이스 스키마 변경은 흔히 있는 일입니다. 그러나 이 것은 web 개발자는 확정 되지 않고 어떻게 사용될지 모르는 단계에서 입력 양식 만드는 것을 싫어한다는 단점이 발생합니다. 개발자의 부담을 경감시키기 위해 CakePHP는 스캐 폴딩 기능을 제공합니다. 스캐 폴딩은 데이터베이스 테이블을 분석하여 추가, 삭제, 편집 버튼이 붙어있는 표준 목록 편집을위한 표준 양식 데이터베이스의 1 레코드를보기위한 표준 뷰를 만듭니다.
스캐 폴딩을 추가하기 위해 컨트롤러에서 $scaffold 변수를 추가하십시오. :
class CategoriesController extends AppController {
public $scaffold;
}
/app/Model/Category.php 기본적인 Category 모델 클래스를 이미 작성했다고하면 준비는 이상입니다. 새로운 발판을 보기 위하여 http://example.com/categories 를 방문해보세요.
발판이 만들어진 컨트롤러 메소드를 작성하면 생각대로의 결과가 나오지 않을 때가 있습니다. 예를 들어, 발판이 만들어진 컨트롤러에 index () 메소드를 작성한 경우 index 메소드는 스캐 폴딩 기능보다 우선적으로 그려집니다.
스캐 폴딩은 모델 사이의 관계에 대한 지식을 제공합니다. 만약 Category 모델이 User에 종속 (belongsTo)하고 있었을 경우, Category 목록에 관련있는 User의 ID가 표시되는 것입니다. 스캐 폴딩은 모델 사이의 관계에 대해 “알고”있습니다 만, 수동으로 모델의 관계를 나타내는 코드를 추가 할 때까지는 발판 뷰에 관련 레코드가 표시되지 않습니다. 예를 들어, 만약 Group이 여러 User를 가지고 (hasMany), User가 Group에 종속 (belongsTo)하는 경우 다음 코드를 User와 Group 모델에 수동으로 추가해야합니다. 이 코드를 추가하기 전에이라고 User 추가 양식 Group에 대한 select 박스가 공백으로 표시됩니다. :
// In Group.php
public $hasMany = 'User';
// In User.php
public $belongsTo = 'Group';
만약 ID가 아닌 다른 것 (예를 들어 사용자 이름 등)을 표시 할 경우 $displayField 변수를 모델로 설정하십시오. 그럼 스캐 폴딩에서 ID 대신 이름으로 카테고리에 관련한 사용자가 표시되도록 User 클래스에 $displayField을 설정하자. :
class User extends AppModel {
public $name = 'User';
public $displayField = 'first_name';
}
Scaffolding을 사용하여 간단한 관리 인터페이스를 작성하기
만약 app/Config/core.php에서 관리 라우팅을 유효하도록 할 경우, Configure::write(‘Routing.prefixes’, array(‘admin’));로하는 것으로 관리자 인터페이스를 생성하기 위해 검사 폴딩을 사용할 수있게됩니다.
일단 관리 라우팅을 활성화 한 후 스캐 폴딩 변수에 admin 접두어를 설정하십시오. :
public $scaffold = 'admin';
이상으로 관리 발판 액션에 액세스 할 수 있습니다. :
http://example.com/admin/controller/index
http://example.com/admin/controller/view
http://example.com/admin/controller/edit
http://example.com/admin/controller/add
http://example.com/admin/controller/delete
이것은 간단한 백엔드 인터페이스를 빠르게 만들 수있는 간단한 방법입니다. 그러나 관리용 및 비 관리용 스케폴딩의 메소드를 동시에 사용할 수 없다는 것을 기억하십시오. 보통의 스케폴딩에서는 개별 메소드를 덮어 쓰거나 자체 구현으로 대체 할 수 있습니다. :
public function admin_view ($id = null) {
// custom code here
}
일단 발판 액션을 옮기게 되면 액션과 동일한 뷰 파일을 작성해야 합니다.
Scaffold 뷰의 커스트마이징
만약 발판으로 생성 된 뷰에 약간의 차이가 발견 것 같으면 템플릿을 만들 수 있습니다. 프로덕션 환경에서 이 기술을 사용하는 것은별로 추천하지 않지만, 프로토 타입 개발 사이라면 여기에서 소개하는 커스트마이즈는 도움이 됩니다.
특정 컨트롤러 (예 PostsController)에 대한 자신의 발판 뷰는 다음과 같이 대체한다. :
/app/View/Posts/scaffold.index.ctp
/app/View/Posts/scaffold.form.ctp
/app/View/Posts/scaffold.view.ctp
모든 컨트롤러에 대한 자신의 스케폴딩 뷰는 다음과 같이 대체해야 합니다. :
/app/View/Scaffolds/index.ctp
/app/View/Scaffolds/form.ctp
/app/View/Scaffolds/view.ctp
'PHP' 카테고리의 다른 글
[CakePHP] Controller - Components (0) | 2015.05.08 |
---|---|
[CakePHP] Controller - PageController (0) | 2015.05.08 |
[CakePHP] CakeResponse (0) | 2015.05.07 |
[CakePHP] CakeRequest 요청 객체 (0) | 2015.05.07 |
cakePhp- controller (0) | 2015.05.06 |
CakeResponse
CakeResponse 는 CakePHP의 기본 응답 클래스입니다. 일부 기능과 HTTP 응답의 생성을 캡슐화합니다. 또한 전송 예정 헤더를 조사하기 위해 모의와 스텁으로 테스트 할 수있게합니다. CakeRequest 처럼 CakeResponse 은 Controller 와 RequestHandlerComponent 및 Dispatcher에 이전부터있는 많은 방법을 강화합니다. 오래된 메소드는 폐지되고 CakeResponse 의 사용이 권장됩니다.
CakeResponse 는 다음과 같은 일반적인 응답을 포장하기위한 인터페이스를 제공합니다. :
- 리디렉션을 위해 헤더를 보내는 것.
- 컨텐츠 유형 헤더를 보내는 것.
- 헤더를 보내는 것.
- 응답 본문을 보내는 것.
Response 클래스 변경하기
CakePHP는 기본적으로 CakeResponse 을 사용합니다. CakeResponse 는 유연하고 투명하게 클래스가 사용됩니다. 그러나이 클래스를 응용 프로그램 고유의 클래스로 대체해야하는 경우 CakeResponse 을 무시하고 자신의 클래스로 대체 할 수 있습니다. 그것은 app / webroot / index.php에서 CakeResponse 을 대체하여 제공합니다.
이 대체 의해 모든 컨트롤러가 CakeResponse 대신 CustomResponse을 사용할 수있게됩니다. 또한 컨트롤러에서 $this-> response로 설정하여 응답 인스턴스를 대체 할 수 있습니다. 응답 개체의 재정은 header() 와 상호 작용하는 방법을 스텁 화 쉽게하기 때문에 테스트에서 사용하기 쉽습니다. 자세한 내용은 CakeResponse 및 테스트 를 참조하십시오.
콘텐츠 형식을 취급
CakeResponse::type()을 사용함으로써 어플리케이션 응답의 Content-Type을 제어 할 수 있습니다. 만약 CakeResponse에 포함되지 않은 콘텐츠 유형을 처리해야하는 경우는 다음과 같이 CakeResponse::type()을 사용하여 설정할 수 있습니다.
// vCard 유형을 추가
$this -> response -> type(array('vcf'=> 'text / v-card'));
// 응답의 Content-Type을 card로 설정
$this -> response -> type('vcf');
대부분의 경우, 추가 콘텐츠 형식은 컨트롤러의 beforeFilter()
의 콜백 내에서 설정하고 싶어하기 때문에 RequestHandlerComponent
가 제공하는 뷰의 자동 전환 기능을 활용할 수 있습니다.
파일 쓰기
요청에 대한 응답으로 파일을 보내고 싶은 경우가 있습니다. 버전 2.3 이전에는 MediaView를 사용할 수있었습니다. 2.3 이상에서 MediaView 는 비추천되며 CakeResponse::file()을 사용하여 파일을 전송합니다. :
public function sendFile($id){
$file = $this -> Attachment -> getFile($id);
this -> response -> file($file ['path']);
// Response 객체를 반환하면 컨트롤러가 뷰의 렌더링을 중단합니다
return $this -> response;
}
위의 예제처럼 메소드에 파일의 경로를 전달해야합니다. CakePHP는 CakeResponse::$_mimeTypes에 등록 된 잘 알려진 파일 형식이면 올바른 컨텐츠 유형 헤더를 보냅니다. CakeResponse::file()을 부르기 전에 CakeResponse::type() 메소드를 사용하여 새로운 유형을 추가 할 수 있습니다.
만약 당신이 원한다면 옵션을 명기하여 브라우저에 표시하는 대신 파일을 다운로드 하도록 할 수 있습니다. :
$this -> response -> file(
$file['path']
array('download'=> true 'name'=> 'foo')
);
문자열을 파일로 쓰기(다운로드)
동적으로 생성 된 pdf 나 ics처럼 디스크에 존재하지 않는 파일을 반환 할 수 있습니다. :
public function sendIcs(){
$icsString = $this -> Calendar -> generateIcs();
$this -> response -> body($icsString);
$this -> response -> type('ics');
// 임의의 다운로드 파일 이름을 지정할 수 있습니다
$this -> response -> download('filename_for_download.ics');
// 응답 객체를 반환하면 컨트롤러가 뷰의 렌더링을 중단합니다
return $this -> response;
}
헤더를 설정
헤더의 설정은 CakeResponse::header()에서 이루어집니다. 이 메서드는 조금 다른 파라미터 설정과 함께 불립니다. :
// 헤더를 하나 설정
$this -> response -> header('Location', 'http://example.com');
// 여러 헤더를 설정
$this -> response -> header( array(
'Location'=> 'http://example.com'
'X-Extra'=> 'My header'
));
$this -> response -> header( array(
'WWW-Authenticate::Negotiate'
'Content-type::application / pdf'
));
같은 헤더를 여러 번 설정하면 보통 header 호출과 같이 이전 값을 덮어 쓰게 됩니다. CakeResponse::header() 가 호출되지 않으면 헤더는 전송되지 않습니다. 이 헤더는 응답이 실제로 보내질 때까지 버퍼링됩니다.
버전 2.4에서 추가.
CakeResponse::location() 를 사용하면 직접 리디렉션 헤더의 설정 및 복원이 가능합니다.
브라우저 캐시와 상호 작용
때때로 컨트롤러 액션의 결과를 캐시하지 않도록 브라우저를 설정 해야 할 경우 있습니다. CakeResponse::disableCache()는 이러한 목적으로 사용됩니다. :
public function index(){
// do something.
$this -> response -> disableCache();
}
경고
Internet Explorer에 파일을 보내려고하는 경우 SSL 도메인에서의 다운로드와 함께 disableCache()를 사용하는 것을 오류로 할 수 있습니다.
또한 CakeResponse::cache() 를 사용하여 클라이언트에 응답을 캐시 하도록 할 수 있습니다. :
public function index(){
// do something
$this -> response -> cache('-1 minute', '+5 days');
}
위의 예에서는 방문자의 체감 속도 향상을 위해 클라이언트에 응답 결과를 5일 캐시하도록 전하고 있습니다. CakeResponse::cache() 는 첫 번째 인수에 Last-Modified 헤더 값을 설정합니다. 두 번째 인수에 Expires 헤더 값과 max-age 지시어 값을 설정합니다. Cache-Control의 public 지시어도 설정됩니다.
HTTP 캐시를 튜닝
응용 프로그램의 속도를 개선하기위한 간단하고 좋은 방법 중 하나는 HTTP 캐시를 사용하는 것입니다. 이 캐시 모델은 원래 modified time, response entity tag 등 일부 헤더를 설정하여 응답의 캐시 된 복사본을 사용할지 여부를 클라이언트가 결정하도록 도울 수 있어야합니다.
캐시와 데이터가 변경 될 때 비활성화(업데이트)하는 로직 코드를 가지는 것이 아니라, HTTP는 두 모델 expiration과 validation을 사용합니다. 이들은 대부분의 경우 자신의 캐시를 관리하는 것보다 상당히 간단합니다.
CakeResponse::cache() 와 독립하여 HTTP 캐시 헤더를 튜닝하기위한 다양한 방법을 사용할 수 있습니다. 이 점에 관해서 브라우저 또는 리버스 프록시 캐시보다 유리하다고 할 수 있습니다.
Cache Control 헤더
버전 2.1에서 추가.
캐시 제어 헤더는 expiration 모델 하에서 사용되며, 여러 지침이 포함되어 있습니다. 브라우저와 프록시가 어떻게 캐시 된 콘텐츠를 취급할지를 지시, 변경할 수 있습니다. Cache-Control 헤더는 다음과 같습니다. :
Cache-Control: private, max-age = 3600, must-revalidate
CakeResponse 의 일부 유틸리티 메소드를 이용함으로써 최종적으로 유효한 Cache-Control 헤더를 생성합니다. 첫째는 CakeResponse::sharable()
메소드입니다. 이 방법은 다른 사용자와 클라이언트간에 공유 할 수있는 것을 고려한 응답인지의 여부를 나타냅니다. 이 메소드는 실제로는 이 헤더가 public 또는 private의 어느 쪽인가를 제어 할 수 있습니다. private에 응답을 설정하는 것은 응답의 전체 또는 일부가 특정 사용자용임을 보여줍니다. 공유 캐시의 장점을 살리기 위해서는 제어 지시문을 public으로 설정해야합니다.
이 메서드의 두 번째 매개 변수는 캐시의 max-age를 지정하는 데 사용됩니다. 이 매개 변수는 응답이 이전 버전으로 보이도록 초를 표시합니다. :
public function view(){
...
// Cache-Control을 3600 초 동안 public으로 설정
$this -> response -> sharable(true, 3600);
}
public function my_data(){
...
// Cache-Control을 3600 초 동안 private로 설정
$this -> response -> sharable(false, 3600);
}
CakeResponse 는 Cache-Control 헤더에서 각 구성 요소를 설정하기 위해 분할 된 메소드를 공개하고 있습니다.
Expiration 헤더
버전 2.1에서 추가.
Expires 헤더에 응답이 오래된 것으로 간주되도록 시간을 설정할 수 있습니다. 이 헤더는 CakeResponse::expires() 메소드를 사용하여 설정됩니다. :
public function view(){
$this -> response -> expires('+ 5 days');
}
또한이 방법은 DateTime 인스턴스와 DateTime 클래스에 의해 구문 분석 가능한 문자열을 받아들입니다.
Etag 헤더
버전 2.1에서 추가.
HTTP의 캐시 검증은 콘텐츠가 정기적으로 변화하는 경우에 사용되며, 오래된 캐쉬로 보여질 경우에만 응답 콘텐츠가 생성되는 것을 어플리케이션에게 요구합니다. 이 모델 하에서 클라이언트는 페이지를 직접 사용하는 대신 캐시에 저장하여 계속 어플리케이션에 매번 리소스가 변경되었는지 여부를 묻습니다. 이것은 이미지 및 기타 어셋 등의 정적 리소스에 사용되는 경우가 많습니다.
etab() 메소드(entity tag라고도 함)은 요구 된 자원을 식별하는 고유 한 문자열입니다. 대부분의 경우 파일의 체크섬과 같은 것으로, 자원이 일치하는지 여부를 확인하기 위해 캐시는 체크섬을 비교하는 것입니다.
실제로이 헤더를 사용할 때의 이점을 얻기 위해 수동으로 CakeResponse::checkNotModified() 메서드를 호출하거나 컨트롤러에 RequestHandlerComponent 을로드해야합니다. :
public function index(){
$articles = $this -> Article -> find('all');
$this -> response -> etag($this -> Article -> generateHash($articles));
if($this -> response -> checkNotModified($this -> request)){
return $this -> response;
}
...
}
Last Modified 헤더
버전 2.1에서 추가.
HTTP 캐시의 validation 모델 하에서는 자원이 마지막으로 수정 된 날짜와 시간을 나타 내기 위해 Last-Modified 헤더를 설정할 수 있습니다. 이 헤더를 설정하면 CakePHP가 캐시하고 있는 클라이언트에 응답이 변경된 것인지 여부를 대답하는 데 도움이됩니다.
실제로이 헤더를 사용할 때의 이점을 얻기 위해서는 CakeResponse::checkNotModified() 메서드를 호출하거나 컨트롤러에 RequestHandlerComponent를 로드해야합니다. :
public function view(){
$article = $this -> Article -> find('first');
$this -> response -> modified($article['Article']['modified']);
if($this -> response -> checkNotModified($this -> request)){
return $this -> response;
}
...
}
Vary 헤더
때로는 같은 URL로 다양한 내용을 제공하고 싶을지도 모릅니다. 이에 해당하는 경우는 다국어 지원 페이지가 있거나 브라우저마다 다른 HTML을 반환하는 경우 종종 발생합니다. 그런 상황에서 Vary
헤더를 사용할 수 있습니다. :
$this -> response -> vary ( 'User-Agent' );
$this -> response -> vary ( 'Accept-Encoding', 'User-Agent');
$this -> response -> vary ( 'Accept- Language' );
CakeResponse 및 테스트
컨트롤러와 컴포넌트의 테스트가 간단하게 가능했을 때 CakeResponse 를 사용하고있어 좋았다고 생각할지도 모릅니다. 여러 개체를 횡단하여 사용하는 메소드 대신 컨트롤러와 구성 요소가 CakeResponse 에 위임하고있는 것을 모방(mock)객체를 준비하기만하면 됩니다. 이 것으로 ‘단위’테스트를 만들기 쉬워지고 컨트롤러 테스트 실행이 쉬워집니다. :
public function testSomething (){
$this -> controller -> response = $this -> getMock ( 'CakeResponse' );
$this -> controller -> response -> expects ( $this -> once ()) -> method ( 'header' );
// ...
}
또한 CLI에서 헤더 설정을 시도 할 때 일어나는 ‘헤더 보내기’오류를 피하기 위해 모의를 사용할 수 있기 때문에 명령 줄에서 더 쉽게 테스트를 실행할 수 있습니다.
CakeResponse API
class
CakeResponse
CakeResponse는 클라이언트에 보내는 응답과 상호 작용에 도움이 되는 메소드를 많이 제공합니다.
CakeResponse::header($header = null , $value = null )
응답과 함께 전송되는 하나 이상의 헤더를 직접 설정할 수 있습니다.
CakeResponse::location($url = null )
응답과 함께 보내진다 리디렉션 헤더를 직접 설정할 수 있습니다. :
// Set the redirect location
$this -> response -> location ( 'http://example.com' );
// Get the current redirect location header
$location = $this -> response -> location ();
버전 2.4에서 추가.
CakeResponse::charset($charset = null )
응답에서 사용되는 문자 코드의 종류를 설정합니다.
CakeResponse::type($contentType = null )
응답 콘텐츠 형식을 설정합니다. 알려진 콘텐츠 형식의 별명 또는 콘텐츠 형식의 정식 명칭을 사용할 수 있습니다.
CakeResponse::cache($since , $time = ‘+1 day’ )
응답 캐시 헤더를 설정할 수 있습니다.
CakeResponse::disableCache()
응답 클라이언트의 캐시를 비활성화하는 헤더를 설정합니다.
CakeResponse::sharable($public = null , $time = null )
Cache-Control 헤더에 public 또는 private 를 설정하고 선택적으로 자원의 max-age 지시자를 설정합니다.
버전 2.1에서 추가.
CakeResponse::expires($time = null )
Expires 헤더에 특정 날짜를 설정할 수 있습니다.
버전 2.1에서 추가.
CakeResponse::etag($tag = null , $weak = false )
응답 자원을 고유하게 식별하는 Etag 헤더를 설정합니다.
버전 2.1에서 추가.
CakeResponse::modified($time = null )
Last-Modified 헤더에 특정 날짜를 올바른 형식으로 설정합니다.
버전 2.1에서 추가.
CakeResponse::checkNotModified(CakeRequest $request )
요청 객체 및 응답의 캐시 헤더를 비교하고 아직 캐시를 사용할 수 있는지 여부를 결정합니다. 만약 아직 유효한 경우 응답 내용은 삭제 된 304 Not Modified
헤더가 보내집니다.
버전 2.1에서 추가.
CakeResponse::compress()
응답 gzip 압축을 사용 시작합니다.
CakeResponse::download($filename )
첨부 파일로 응답을 보내 파일 이름을 설정할 수 있습니다.
CakeResponse::statusCode($code = null )
응답 상태 코드를 설정할 수 있습니다.
CakeResponse::body($content = null )
응답의 콘텐츠 몸을 설정합니다.
CakeResponse::send()
응답의 작성이 완료된 후 send()를 호출하는 것으로 Body와 같이 설정되어있는 모든 헤더가 보내집니다. 각 요청의 마지막에 Dispatcher
에 의해 자동으로 이루어집니다.
CakeResponse::file($path , $options = array() )
보기 또는 다운로드하는 파일의 Content-Disposition
헤더를 설정할 수 있습니다.
버전 2.3에서 추가.
'PHP' 카테고리의 다른 글
[CakePHP] Controller - Components (0) | 2015.05.08 |
---|---|
[CakePHP] Controller - PageController (0) | 2015.05.08 |
[CakePHP] Controller - Scaffolding (0) | 2015.05.08 |
[CakePHP] CakeRequest 요청 객체 (0) | 2015.05.07 |
cakePhp- controller (0) | 2015.05.06 |
요청(Request)과 응답(Reponse) 객체
CakePHP2.0에서 새롭게 요청과 응답 객체가 추가되었습니다. 이전 버전에서는 이러한 개체는 배열로 표현되고 있으며 관련 메소드는 RequestHandlerComponent, Router, Dispatcher, Controller 에 분산되어있었습니다. 따라서 요청에 어떤 정보가 포함되어 있는지를 정확히 나타내는 개체는 존재하지 않았습니다. 버전 2.0에서 CakeRequest 과 CakeResponse 는 위의 목적으로 사용됩니다.
CakeRequest
CakeRequest 는 CakePHP에서 사용되는 기본 요청 개체입니다. 요청 데이터에 대한 응답과 상호 작용이 핵심 기능입니다. 요청마다 CakeRequest는 하나씩 만들어져 요청 데이터를 사용하는 어플리케이션의 다양한 레이어에 참조가 전달됩니다. 기본적으로 CakeRequest 는 $this->request
에 설정된 컨트롤러, 뷰 헬퍼에서 사용할 수 있습니다. 또한 컨트롤러의 참조를 사용하여 컴포넌트 안에서도 액세스 할 수 있습니다. CakeRequest 의 역할은 다음과 같습니다. :
- GET, POST 그리고 FILES 배열을 익숙한 데이터 구조로 변환하는 작업을 수행합니다.
- 요청 관련 내성적 인 환경을 제공합니다. 전송 된 헤더와 클라이언트의 IP 주소, 서버가 실행되는 하위 도메인/도메인 정보 등이 포함됩니다.
- 요청 매개 변수에 액세스하는 방법을 인덱싱 된 배열과 객체의 속성이 모두 형식으로 제공합니다.
Request Parameter에 접근
CakeRequest는 요청 파라메터에 액세스하기 위해 몇 가지 인터페이스를 제공합니다. 첫 번째 방법으로는 색인화 된 배열입니다. 두 번째 방법은 $this->request->params
를 통해 접근하는 방법입니다. 세번째는 객체의 속성으로 액세스하는 방법입니다. :
$this -> request -> controller;
$this -> request ['controller'];
$this -> request -> params ['controller'];
위는 3가지 모두 같은 값에 액세스 할 수 있습니다. 파라메터에 액세스하는 방법이 여러이기 때문에 기존 어플리케이션에 이식하기 편해질지도 모릅니다. 모든 route-elements는이 인터페이스를 통해 액세스됩니다.
route-elements 이외에 passed-arguments나 named-parameters에 대한 액세스가 종종 필요합니다. 이들은 양쪽 모두 Request 오브젝트와 마찬가지로 사용할 수 있습니다. :
// 전달 된 인수
$this -> request -> pass;
$this -> request [ 'pass'];
$this -> request -> params [ 'pass'];
// 명명 된 매개 변수
$this -> request -> named;
$this -> request ['named'];
$this -> request -> params ['named'];
모든 전달 된 인수와 명명 된 매개 변수에 액세스하는 방법을 제공하고 있습니다. 이 가운데는 CakePHP 내부에서 사용하고있는 중요하고 유용한 변수가 존재며, 또한 Request 파라메터 안에서 모두 찾을 수 있습니다.
- plugin 요청을 처리하는 플러그인에서 플러그인이없는 경우는 null입니다.
- controller 현재 요청을 처리하는 컨트롤러입니다.
- action 현재 요청을 처리하는 작업입니다.
- prefix 현재 액션 접두사입니다. 자세한 내용은 prefix-routing보세요.
- bare 요청이 requestAction() 에서 시작 bare 옵션을 포함 할 때 정의됩니다. 원시 요청은 렌더링 된 레이아웃을지지 않습니다.
- requested 액션이 requestAction() 에서 시작될 때 정의 된 true가 설정됩니다.
쿼리 문자열 파라메터에 접근
쿼리 문자열 매개 변수는 CakeRequest::$query를 사용하여 읽을 수 있습니다. :
// url은 /posts/index?page=1&sort=title
$this -> request -> query ['page'];
// 배열을 통해 액세스 할 수 있습니다
// Note : 하위 호환 액세서입니다. 향후 버전에서는 비추천입니다.
$this -> request [ 'url'] [ 'page'];
$query 속성에 직접 액세스하거나 오류가 발생하지 않는 방법으로 URL 쿼리 배열을 읽기 위하여 CakeRequest::query()를 사용할 수 있습니다. 키가 존재하지 않으면 null이 반환됩니다. :
$foo = $ this -> request -> query ( 'value_that_does_not_exist');
// $ foo === null
POST 데이터에 액세스
모든 POST 데이터는 CakeRequest::$data를 사용하여 접근가능합니다. 양식 데이터가 data접두사를 포함하는 경우, 접두사는 제거 될 것입니다. 예를 들면 :
// name 속성이 'data [Post] [title]'였다 입력은 다음과 같이 사용합니다.
$this -> request -> data ['Post'] ['title'];
$data 속성에 직접 액세스하거나 오류가 발생하지 않는 방법으로 data 배열을 읽기 위해 CakeRequest::data()를 사용할 수 있습니다. 키가 존재하지 않으면 null이 반환됩니다. :
$foo = $this -> request -> data ( 'Value.that.does.not.exist');
//$foo == null
PUT 또는 POST 데이터에 액세스
버전 2.2에서 추가.
REST 서비스를 구축 할 때 PUT 및 DELETE 요청 데이터를 받아 들일경우가 많습니다. 2.2에서 application/x-www-form-urlencoded의 Request Body의 데이터는 PUT과 DELETE 요청에서 자동으로 구문이 해석 되어 $this -> data로 설정됩니다. 만약 JSON과 XML데이터를 받아들이는 경우 어떻게 Request Body에 액세스하면 좋을지에 대해서는 다음의 설명을 확인해 주세요.
XML 또는 JSON 데이터에 액세스
REST 를 사용하는 응용 프로그램에서 URL 인코딩되지 않은 post 형식으로 데이터를 교환하는 경우가 종종 있습니다. CakeRequest::input()을 사용하는 어떤한 형식이라도 입력 데이터를 읽어 들일 수 있습니다. 디코딩 함수가 제공되기때문에 직렬화 된 콘텐츠를 받아들일 수 있습니다. :
// PUT / POST 액션에 게시 된 데이터를 JSON 형식으로 인코딩해서 취득.
$data = $this -> request -> input('json_decode');
json_decode의 ‘as array’매개 변수와 XML을 DOMDocument 객체로 변환하고 싶을 때와 같이 직렬화 메소드에서 호출시 추가 매개 변수가 필요한 것이 있으므로 CakeRequest::input()은 추가 매개 변수를 전달할 수 있도록 되어 있습니다. :
// PUT / POST 액션에 게시 된 데이터를 Xml 인코딩해서 취득.
$ data = $ this -> request -> input ( 'Xml :: build', array ( 'return'=> 'domdocument'));
경로 정보에 접근
CakeRequest는 어플리케이션의 경로에 대한 유용한 정보를 제공하고 있습니다. CakeRequest::$base 와 CakeRequest: :$webroot 는 URL의 생성과 어플리케이션이 하위 디렉토리에 있는지의 여부를 결정하는 데 도움이됩니다.
요청을 조사
다양한 Request 상태를 감지하기 위해 이전에는 RequestHandlerComponent 를 사용해야했습니다. 이 메소드들은 CakeRequest 로 이동되어 호환성을 유지하면서 새로운 인터페이스를 제공하고 있습니다. 사용법은 다음과 같습니다. :
$this -> request -> is ('post');
$this -> request -> isPost (); // 비추천
양쪽 모두 같은 값을 반환합니다. RequestHandlerComponent 에서 그 방식을 사용할 수있게되었을 때,이 메소드는 폐지되고 최종 릴리스 전에 삭제 될지도 모릅니다. 또한 새로운 종류의 검출기(detector)를 만드는 데 CakeRequest:: addDetector()를 사용해서 Request 검출기를 쉽게 확장 할 수 있습니다. 4종류의 다른 검출기를 만들 수 있습니다. :
- 환경 변수의 비교 - 환경 변수의 비교, env() 에서 얻은 값과 기존의 값을 비교합니다. 환경 변수는 제공된 값에 대해 동등성을 확인합니다.
- 패턴 값의 비교 - 패턴 값의 비교에서는 env() 에서 얻은 값과 정규 표현식을 비교합니다.
- 옵션 기반의 비교 - 옵션 기반의 비교에서는 정규식을 만들기 위해 옵션의 목록을 사용합니다. 이미 정의 된 옵션 검출기를 추가하기 위해 호출 옵션을 병합하는 것입니다.
- 콜백 검출기 - 콜백 검출기는 체크를 처리하기 위해 ‘callback’유형을 제공합니다. 콜백은 파라메터로서만 요청 객체를 받습니다.
다음은 몇 가지 예를 보여줍니다. :
environment detector 추가
$this -> request -> addDetector (
'post',
array ( 'env'=> 'REQUEST_METHOD', 'value'=> 'POST')
);
// pattern value detector 추가
$this -> request -> addDetector (
'iphone',
array ( 'env'=> 'HTTP_USER_AGENT', 'pattern'=> '/ iPhone / i')
);
// option detector 추가
$this -> request -> addDetector ( 'internalIp', array (
'env'=> 'CLIENT_IP',
'options'=> array ( '192.168.0.101', '192.168.0.100')
));
// callback detector를 추가한다. 익명 함수 또는 정규 콜백이 지정 가능.
$this -> request -> addDetector (
'awesome',
array ( 'callback'=> function ($ request) {
return isset ($ request -> awesome);
})
);
CakeRequest 에는 CakeRequest::domain() ,CakeRequest::subdomains() 과 CakeRequest::host() 와 같은 하위 도메인을 처리 할수 있도록 해주는 함수가 있기 때문에 좀 더 쉽게 할 수 있습니다.
사용 가능한 내장 검출기는 다음과 같습니다. :
- is(‘get’) 현재 리퀘스트가 GET 여부를 확인합니다.
- is(‘put’) 현재 리퀘스트가 PUT 여부를 확인합니다.
- is(‘post’) 현재 리퀘스트가 POST 여부를 확인합니다.
- is(‘delete’) 현재의 리퀘스트가 DELETE에 있는지 여부를 확인합니다.
- is(‘head’) 현재 리퀘스트가 HEAD 여부를 확인합니다.
- is(‘options’) 현재 리퀘스트가 OPTIONS 여부를 확인합니다.
- is(‘ajax’) 현재 리퀘스트가 X-Requested-With = XMLHttpRequest에서 파생 된 것인지를 확인합니다.
- is(‘ssl’) 리퀘스트가 SSL을 통해 여부를 확인합니다.
- is(‘flash’) 리퀘스트에 Flash의 User-Agent가 있는지 확인합니다.
- is(‘mobile’) 리퀘스트에 모바일 에이전트의 공통 목록에 유래하고 있는지 여부를 확인합니다.
CakeRequest과 RequestHandlerComponent
CakeRequest가 제공하는 많은 기능은 이전 RequestHandlerComponent 속에 있었으므로, CakePHP2.0에 어떻게 들어가는지를 이해하기 위해 재고해야할 필요가 있습니다. 2.0에서 RequestHandlerComponent는 후원자(sugar daddy)에 해당합니다. CakeRequest가 제공하는 유틸리티 맨 위에 sugar 레이어를 제공하고 있습니다. 레이아웃 전환이나 콘텐츠 형식과 ajax를 바탕으로 한 뷰 등 sugar는 RequestHandlerComponent영역입니다. 유틸리티와 sugar 클래스를 분리함으로써 원하는 것들의 취사선택이 쉽게 될 것입니다.
요청의 다른 요소와 상호 작용
CakeRequest는 요청에 대한 다양한 것을 내관(introspect)하는 데 사용할 수 있습니다. 또한 검출기 따라 다양한 속성과 메소드에서 다른 정보를 찾을 수 있습니다.
- $this-> request-> webroot는 webroot 디렉토리를 포함합니다.
- $this-> request-> base는 기본 경로를 포함합니다.
- $this-> request-> here 현재 요청에 완전한 주소를 포함합니다.
- $this-> request-> query는 쿼리 문자열 매개 변수를 포함합니다.
CakeRequest API
class
CakeRequest
CakeRequest는 요청 파라미터의 처리를 캡슐화하고 내관 할 수 있습니다.
CakeRequest::domain($tldLength = 1)
응용 프로그램이 실행되는 도메인 이름을 반환합니다.
CakeRequest::subdomains($tldLength = 1)
응용 프로그램이 실행되는 하위 도메인을 배열로 돌려줍니다.
CakeRequest::host()
응용 프로그램의 호스트 이름을 반환합니다.
CakeRequest::method()
요청의 HTTP 메소드를 반환합니다.
CakeRequest::onlyAllow($methods)
허용 된 HTTP 메소드를 설정합니다. 만약 일치하지 않으면 MethodNotAllowedException을 던집니다. 405 응답은 통과 할 수있는 방법을 가지고 Allow 헤더가 포함됩니다.
버전 2.3에서 추가.
2.5 버전 철폐 : 대신 CakeRequest::allowMethod() 를 사용하십시오.
CakeRequest::allowMethod($methods)
허용 된 HTTP 메소드를 설정합니다. 만약 일치하지 않으면 MethodNotAllowedException을 던집니다. 405 응답은 통과 할 수있는 방법을 가지고 Allow 헤더가 포함됩니다.
버전 2.5에서 추가.
CakeRequest::referer ($local = false)
요청의 리퍼러를 반환합니다.
CakeRequest::clientIp ($safe = true)
현재 액세스하는 클라이언트의 IP 주소를 반환합니다.
CakeRequest::header ($name)
요청에 사용되는 HTTP_ * 헤더에 액세스 할 수 있습니다. :
$ this -> request -> header ( 'User-Agent');
이 경우 요청에 사용되는 사용자 에이전트가 반환됩니다.
CakeRequest::input ($callback [$options])
요청 및 디코딩 함수를 통해 전달 된 input 데이터를 가져옵니다. 요청 본문을 XML이나 JSON으로 교환 할 때 유용합니다. 디코딩 함수의 추가 매개 변수는 input()의 인수로 전달할 수 있습니다. :
$this -> request -> input ( 'json_decode');
CakeRequest::data($key)
요청 데이터에 닷 기법에 의한 액세스를 제공합니다. 요청 데이터 읽기 및 변경이 가능합니다. 또한 다음과 같이 연쇄 적으로 호출을 할 수 있습니다. :
// 요청 데이터를 수정하고 양식 필드를 생성 할 수 있습니다.
$ this -> request -> data ('Post.title', 'New post')
-> data ( 'Comment.1.author', 'Mark');
// 데이터 검색도 할 수 있습니다.
$ value = $ this -> request -> data ( 'Post.title');
CakeRequest::is ($check)
요청이 기준에 적합한 지 여부를 확인합니다. CakeRequest::addDetector() 에 추가 된 추가 규칙뿐만 아니라 내장의 검색 규칙을 사용할 수 있습니다.
CakeRequest::addDetector ($name, $callback)
CakeRequest::is() 와 함께 사용되는 검출기를 추가합니다. 자세한 내용은 요청을 검사 를 참조하십시오.
CakeRequest::accepts ($type = null)
클라이언트가 어떤 콘텐츠 유형을 허용 할 지 확인합니다. 또한 특정 콘텐츠 유형이 허용되는지 여부를 확인합니다.
모든 유형 가져 오기 :
$ this -> request -> accepts ();
특정 유형에 대해 알아 :
$ this -> request -> accepts ( 'application / json');
static
CakeRequest::acceptLanguage ($language = null)
클라이언트에 의해 접수되는 모든 언어를 가져옵니다. 또한 특정 언어가 접수 여부를 확인합니다.
접수되는 언어 목록을 검색 :
CakeRequest :: acceptLanguage ();
특정 언어가 접수되는지 여부를 확인 :
CakeRequest :: acceptLanguage ( 'es-es');
CakeRequest::param ($name)
$request-> params 값을 안전하게 읽습니다. 매개 변수의 값을 사용하기 전에 isset () 또는 empty ()를 호출 할 필요가 없습니다.
버전 2.4에서 추가.
property
CakeRequest::$data
POST 데이터의 배열입니다. CakeRequest::data() 를 사용하면 오류가 발생하지 않도록하면서 속성을 가져올 수 있습니다.
property
CakeRequest::$query
쿼리 문자열 매개 변수의 배열입니다.
property
CakeRequest::$params
루트 요소와 요청 파라미터의 배열입니다.
property
CakeRequest::$Here
현재 요청의 uri를 반환합니다.
property
CakeRequest::$base
응용 프로그램에 대한 기본 경로입니다. 응용 프로그램이 하위 디렉토리에 배치되지 않는 한, 보통은 /입니다.
property
CakeRequest::$Webroot
현재의 webroot 입니다
'PHP' 카테고리의 다른 글
[CakePHP] Controller - Components (0) | 2015.05.08 |
---|---|
[CakePHP] Controller - PageController (0) | 2015.05.08 |
[CakePHP] Controller - Scaffolding (0) | 2015.05.08 |
[CakePHP] CakeResponse (0) | 2015.05.07 |
cakePhp- controller (0) | 2015.05.06 |
ControllerCakePhp [ Cookbook2.x ]
컨트롤러는 MVC에서 'C'입니다. 라우팅이 적용된 후 컨틀롤러를 찾아 컨트롤러의 액션이 호출됩니다. 컨트롤러는 리퀘스트를 해석해서 적절한 모델(M)이 호출되는 것을 확인하고 알맞는 레스폰스 또는 뷰(V)를 출력합니다. 컨트롤러는 모델과 뷰의 소개자라고 볼 수 있습니다. 컨트롤러는 간단하고 심플하게 작성하고, 모델을 크게 하면 코드가 재사용하기 쉽고 비교적 테스트가 간단하게 가능합니다.
어플리케이션의 컨트롤러는 AppController 클래스를 상속하고 그것은 Controller를 상속하고 있습니다. AppController 클래스는 /app/Controller/AppController.php 에 정의하고, 어플리케이션의 컨트롤러들에서 전체적으로 공유해서 사용할만한 메소드를 포함하도록 합니다.
AppController
AppController 클래스는 모든 어플리케이션의 컨트롤러의 부모 클래스가 됩니다. AppController는 /app/Controller/AppController.php 에 다음과 같이 정의 합니다.class AppController extends Controller{
}
보통의 객체지향의 상속 룰이 적용되어있다면 CakePHP는 컨트롤러에 있는 특정의 변수가 지정된 경우 동작을 확장합니다. 컨트롤러에서 사용되는 컴포넌트와 헬퍼의 리스트는 특별하게 취급되어 이러한 변수는 AppController의 값과 자식 컨트롤러의 값이 병합됩니다.
보통의 자식 클래스의 변수는 AppController의 변수를 덮어쓰게 됩니다.
//CakePHP는 AppController와 어플리케이션의 컨트롤러의 다음 변수를 병합합니다.
$components
$helpers
$uses
AppController에서 $helpers 변수를 정의 하게 되면 기본적으로 Html 헬러와 Form 헬퍼가 추가 됩니다.
그리고 자식 컨트롤러의 콜백에서는 AppController의 콜백을 호출하는 것은 아래와 같이 하는 것을 추천합니다.
public function beforeFilter() {
parent::beforeFilter();
}
리퀘스트 파라메터
CakePHP 어플리케이션에서는 요청이 들어오면 Router 클래스와 Dispatcher클래스가 적절한 컨트롤러를 찾아 생성하기 위해 routes-configuration을 사용합니다. 리퀘스트 데이터는 리퀘스트 오브젝트 안에 캡슐화 되어 있습니다. CakePHP는 모든 중요한 리퀘스트정보를 $this->request 프로퍼티에 등록하고 있습니다. (CakeRequest 참조)컨트롤러의 액션
리퀘스트 요청, 요청에 따른 처리, 결과 변환, 전송합니다. CakePHP의 규약을 따름으로 인해 이 일련의 처리 프로세스를 자동화하여 실제로 코드를 작성하지 않고도 처리가 가능하도록 합니다. CakePHP는 규약에 따라 액션명과 뷰를 작성합니다. OnlineBakery의 샘플을 예로 설명하면 RecipesController는 view(), share(), search() 액션이 포함되어 있습니다. 이 컨트롤러는 /app/Controller/RecipesController.php에 있고 다음과 같습니다.# /app/Controller/RecipesController.php
class RecipesController extends AppController {
public function view($id) {
//action logic goes here..
}
public function share($customerId, $recipeId) {
//action logic goes here..
}
public function search($query) {
//action logic goes here..
}
}
이 액션들의 뷰는 app/View/Recipes/view.ctp, app/View/Recipes/share.ctp, app/View/Recipes/search.ctp 입니다. 규약에 따라 뷰의 화일명은 액션명명을 소문자로하여 언더스코아로 연결합니다.
보통 컨트롤러의 액션에서는 View클래스에서 뷰를 작성할때 사용할 컨텍스트를 만들기 위해 set()을 사용합니다.
CakePHP의 규약이 있으니 수동으로 뷰를 작성하거나 생성할 필요가 없습니다. 컨트롤러의 액션이 처리 완료되면 CakePHP는 뷰를 작성하고 전송합니다.
만일 기본 동작을 스킵하고 싶다면 다음과 같이 하면 뷰를 작성하는 기본 동작을 하지 않게 할 수 있습니다.
- 컨트롤러의 액션에서 문자열 혹은 문자열로 변환 가능한 오브젝트를 반환하도록 하면 반환된 문자열이 결과로 전송됩니다.
- 레스폰스로써 CakeResponse를 반환하는 것이 가능합니다.
class RecipesController extends AppController {
public function popular() {
$popular = $this->Recipe->popular();
if (!empty($this->request->params['requested'])) {
return $popular;
}
$this->set('popular', $popular);
}
}
위는 컨트롤러의 액션이 requestAction() 과 일반적인 리퀘스트에서 메소드락 어떤식으로 사용되는지에 대한 예입니다.
requestAction이 아닌 일반 리퀘스트에 배열 데이터를 반환 값으로 반환하면 에러의 원이이 되니 주의합니다.
(requestAction()의 보다 상세한 정보는 Controller::requestAction()을 참조)
어플리케이션의 컨트롤러의 효홀적으로 사용하기 위해 CakePHP의 컨트롤러가 제공하고 있는 몇가지 중요한 속성과 메소드를 설명하겠습니다.
리퀘스트 라이프 사이클 콜백
classController
CakePHP 컨트롤러는 리퀘스트 라이프 사이클 사이에 로직을 추가 할 수 있도록 콜백 함수가 준비되어 있습니다.Controller::beforeFilter()
이 함수는 컨트롤러명의 액선이 실행되기 전에 호출되어 실행됩니다. 액티브섹션닁 체크나 사용자 권한 체크시에 용이 합니다. beforeFilter()메소트와 액션이 존재하지않는 경우나 scaffold액션의 경우에도 호출 됩니다.Controller::beforeRender()
컨트롤러의 액션뒤에 뷰가 작성되기 전에 호출됩니다. 이 콜백은 그다지 사용되지 않을 수도 있지만 액션 마지막에 render()를 수동으로 호출할 경우 사용 할 경우가 있을 수도 있습니다.Controller::afterFilter()
컨트롤러의 액션 뒤에 뷰가 작성 완료된 뒤에 호출됩니다. 이 메소드는 컨트롤러의 맨 마지막에 실행되는 메소드입니다. 컨트롤러의 콜백과 더불어 컴포넌트도 같은 콜백을 제공합니다.뷰와의 관계
컨트롤러와 뷰는 서로 영향을 주고있습니다. 처음에 컨트롤러는 set()을 사용하여 뷰에 데이터의 전달이 가능합니다. 어떤 뷰 클래스를 사용할지, 어떤 뷰를 작성해야 하는지를 결정하는 것도 가능합니다.Controller::set(string $var, mixed $value)
set()메소드는 컨트롤러로 부터 뷰에 데이터를 전달하는 주된 방법입니다. 1번 set()을 사용하면 그 변수로 뷰 내부에서 접근 가능하게됩니다.// 먼저 컨트롤러로 부터 데이터를 전달합니다.
$this->set('color', 'pink');
// 전달한 데이터는 뷰에서 이용 가능하게 됩니다.
set() 메소드는 처음 파라메터에 배열도 지정 가능합니다. 이 방법은 데이터의 구조체를 간단히 뷰에 전달하는 방법으로 사용됩니다.
$data = array(
'color' => 'pink',
'type' => 'sugar',
'base_price' => 23.95
);
// 뷰에서 $color, $type, $base_price 의 변수로 사용할 수 있습니다.
$this->set($data);
$pageTitle 변수는 더이상 존재하지 않습니다. 타이틀을 설정하기 위해서는 set()을 사용해 주세요.
$this->set('title_for_layout', 'This is the page title');
Controller::render(string $view, string $layout)
render() 메소드는 각 액션의 마지막에 자동적으로 호출됩니다. 이메소드는 set()을 사용해서 전달한 데이터를 사용해서 모든 뷰 로직을 실행하고 뷰를 $layout 내에 배치하고 엔드유저에게 표시합니다. 렌러링에 사용되는 디폴트 뷰 파일은 규약에 따라 결정됩니다. RecipesController의 search() 액션이 리퀘스트 되면 /app/View/Recipes/search.ctp의 뷰 파일이 표시됩니다.class RecipesController extends AppController {
// ...
public function search() {
// /View/Recipes/search.ctp 의 뷰가 표시됩니다.
$this->render();
}
// ...
}
CakePHP는 ($this->autoRender 가 false로 설정되지 않는한) 액션 마지막에 자동적으로 렌더링 메소드를 호출합니다만, 컨트롤러에서 $view에 뷰 이름을 지정하여 다른 뷰 파일이 표시되도록 하는 것도 가능합니다.
$view가 '/'로 시작할 경우 /app/View 의 상태 패스에서 뷰 또는 엘리먼트를 찾으려고 합니다. 이렇게 엘리먼트를 직접 표시하는 것이 가능하여 Ajax 호출시에는 유용합니다.
// /View/Elements/ajaxreturn.ctp 의 뷰가 표시됩니다.
$this->render('/Elements/ajaxreturn');
$layout 파라메터는 뷰가 표시될 레이아웃을 지정할 수 있습니다.
지정한 뷰를 표시
컨트롤러에서는 규약에 따른 뷰 이외의 다른 뷰를 표시하기를 원할경우 render()를 직접 호출할 수있습니다. 1번이라도 render()를 호출하면 CakePHP는 재차 뷰를 표시하지 않습니다.class PostsController extends AppController{
public function my_action(){
$this.render('custom_file');
}
}
이것은 app/Posts/View/my_action.ctp 대신에 app/Posts/View/custom_file.ctp 를 표시합니다.
그리고 다음과 같은 형식으로 플러그인 내의 뷰를 표시하는 것도 가능합니다.
$this->render('PluginName.PluginController/custom_file');
예)
class PostsController extends AppController {
public function my_action() {
$this->render('Users.UserDetails/custom_file');
}
}
이것은 app/Plugin/Users/View/UserDetails/custom_file.ctp 을 표시합니다.
흐름 제어
Controller::redirect(mixed $url, integer $status, boolean $exit)
자주 사용되는 처리 흐름을 제어하는 메소드는 redirect()입니다. 첫번채 변수는 CakePHP의 상대 url을 지정합니다. 유저의 주문이 정사일 경우 영수증 화면으로 리다이렉트를 한다면.public function place_order(){
if($success){
return $this->redirect(array('controller' => 'order', 'action' => 'thanks'));
}
return $this->redirect(array('controller' => 'order', 'action' => 'confirm'));
}
$url에는 상대 URL 또는 절대 URL의 지정이 가능합니다.
$this->redirect('/orders/thanks'));
$this->redirect('http://www.example.com');
액션 데이터의 전달도 가능합니다.
$this->redirect(array('action' => 'edit', $id));
redirect() 의 2번째 파라메터는 리다이렉트시의 HTTP 상태 코드를 정의 할 수 있습니다. 보통 리다이렉트시 301(moved parmanently) 또는 303(see other)를 사용하는 것이 좋습니다.
이 메소드 3번째의 파라메터에 true를 지정하면 exit()를 호출합니다.
리퍼러 페이지에 리다이렉트 해야 할 경우 아래와 같이 지정합니다.
$this->redirect($this->referer());
이 메소드는 파라메터명과 값을 함께 전달할 수 있습니다. 예를 들면
http://www.example.com/orders/confirm/product:pizza/quantity:5 와 같은 URL에 리다이렉트 할 경우는 아래와 같이 사용합니다.
$this->redirect(array('controller' => 'orders', 'action' => 'confirm', 'product' => 'pizza', 'quantity' => 5));
리퀘스트 해쉬를 사용할 경우는 다음과 같이합니다.
$this->redirect(array('controller' => 'orders', 'action' => 'confirm', '?' => array('product' => 'pizza', 'quantity' => 5), '#' => 'top'));
생성된 URL은 다음과 같습니다. Controller::flash(string $message, string $url, integer $pause, string $layout)
redirect() 와 같이 flash() 메소드도 처리가 끝난 뒤에 유저에게 새로운 페이지로 유도하는데 사용됩니다. flash() 메소드는 다른 URL로 이동시키기 전에 메세지를 표시하는 점이 다르다고 할 수 있습니다. 첫번째 파라메터는 표시할 메세지를 지정하고, 두번째 파라메터는 CakePHP의 상대 URL을 지정합니다. CakePHP는 페이지를 리다이렉트 하기전에 $pause 의 초간 $message 를 표시합니다. 표시할 메세지의 특정 템플릿이 있다면 $layout 파라메터에 그 레이아웃 명을 지정합니다. 페이지내의 flash 메세지에 대해서는 SessionComponent"::setFlash() 메소드를 참조해주세요.콜백
리퀘스트 라이프 사이클 콜백에 추가하여 CakePHP는 scaffolding에 관련한 콜백도 서포트합니다.
Controller::beforScafoold($method)
$method는 예를 들면 index, edit등의 호출되어진 메소드명입니다.Controller::afterScaffoldSave($method)
$method는 edit나 update로 호출되어진 메소드명입니다.Controller::afterScaffoldSaveError($method)
$method는 edit나 update로 호출되어진 메소드명입니다.Controller::scaffoldError($method)
$method는 예를 들면 index, edit등의 호출되어진 메소드명입니다.그외 편리한 메소드
Controller::constructClasses()
이 메소드는 컨트롤러에 필요한 모델을 로드합니다. 모델을 로드하는 프로세스는 보통 CakePHP에서 실행 되지만 이 메소드는 다른 시점에서 컨트롤러에 액세스할때에 편리합니다. 커멘드라인 스립트 또는 다른 외부 프로그램을 CakePHP를 사용할 필요가 있을 경우 constructClasses()가 편리합니다.Controller::referer(mixed $default = null, boolean $local = false)
현재 리퀘스트에 대한 리퍼러URL을 반환합니다. $default 파라메터는 HTTP_REFERER가 리퀘스트 헤더에 없을 경우 디폴트 URL로 지정합니다. 다음과 같이 사용합니다.class UserController extends AppController{
public function delete($id){
//delete code goes here, and then ...
if($this->referer() != '/'){
return $this->redirect($this->referer());
}
return $this->redirect(array('action' => 'index'));
}
}
아래와 같이 가능합니다.
class UserController extends AppController{
public function delete($id){
return $this->redirect($this->referer(array('action' => 'index'));
}
}
$default 가 설정되지 않았을 경우 도메인의 루트 '/'를 티폴트로 반환합니다.
$local 파라메터에 true를 설정하면 로컬 서버에 대한 리퍼러URL을 제한합니다.
Controller::disableCache()
유저가 사용하고 있는 브라우저에 대하여 현재 페이지가 캐쉬되지 않도록 페이지 헤더에 캐쉬 클리어 설정을 합니다. 이것을 호출했을 경우 헤더에 아래와 같이 설정되어 결과 페이지가 전송됩니다.Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: [current datetime] GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Controller::postConditions(array $data, mixed $op, string $bool, boolean $exclusive)
POST된 모델 데이터(HtmlHelper와 호환성이 있는 입력 데이터)를 모델의 find 조건으로 설정 가능한 형태로 변환하는 메소드입니다. 이 함수는 검색 로직을 구축하는 단축키입니다. 예를 들어 관리 권한이있는 사용자가 어떤 제품을 출시 할 필요가 있는지를 알기 위해 주문을 검토하는 것이 좋습니다. 여기에서 Order 모델을 기반으로 양식을 만들기 위해 CakePHP의 FormHelper와 HtmlHelper를 사용할 수 있습니다. 이렇게 하면 컨트롤러의 액션은 입력 폼에서 post된 데이터를 find 조건을 만들기 위해 사용할 수 있습니다.public function index() {
$conditions = $this->postConditions($this->request->data);
$orders = $this->Order->find('all', compact('conditions'));
$this->set('orders', $orders);
}
$this->request->data['Order']['destination'] 가 "Old Towne Bakery" 이라면, postConditions는 그 조건을 Model->find()메소드에서 사용가능한 배열로 변환 합니다. 이 경우는 array('Order.destination' => 'Old Towne Bakery') 과 같은 형식이 됩니다.
만일 다른 SQL연산자를 사용하고 싶다면 그 연산자를 2번째 파라메터로 지정해 주세요.
/*
$this->request->data는 아래와 같은 형식입니다.
array(
'Order' => array(
'num_items' => '4',
'referrer' => 'Ye Olde'
)
)
*/
// 'Ye Olde'를 포함하고, 적어도 4개의 상품을 가지고 있는 주문
$conditions = $this->postConditions(
$this->request->data,
array(
'num_items' => '>=',
'referrer' => 'LIKE'
)
);
$orders = $this->Order->find('all', compact('conditions'));
3번째 파라메터는 조건의 결합시 어떤 조합을 사용할지를 지정 할 수 있습니다. ‘AND’, ‘OR’, ‘XOR’와 같은 문자열 입니다.
마지막 파라메터는 true로, $op 파라메터가 배열이라면 , $op에 포함되지 않은 항목은 이 함수에서 반환되는 조건에 포함되지 않습니다.
Controller::paginate()
이 메소드는 모델로 부터 취득한 결과를 페이징 처리 하기 위해 사용됩니다. 페이지 사이즈나 모델의 find 조건등을 지정할 수 있습니다. paginate의 보다 상세한 사용법은 pagination 섹션을 참조해 주세요.Controller::requestAction(string $url, array $options)
이 함수는 다른 곳에서 컨트롤러의 액션을 호출할때 액선으로 부터의 데이터를 반환합니다. $url에는 CakePHP의 상대 URL을 전달합니다.(controllername/actionname/params). 호출할 컨트롤러의 액션에 추가 데이터를 전달할 경우 %option배열을 지정해 주세요.작성된 뷰를 취득하기 위해서는
requestAction($url, array('return'));
와 같이 option에 'return'을 전달하여requestAction()
을 사용하는 것이 가능합니다.
requestAction()은 (캐쉬된)엘리먼트와의 조합으로 자주 사용됩니다. 렌더링전에 엘리먼트로 부타 데이터를 취득하기 위함입니다. 레이아웃 중에 "최근 코멘트"의 엘리먼트를 배치하기 위한 예제를 사용해 봅니다. 먼저 데이터를 반환하는 컨트롤러의 함수를 작성합니다.requestAction()을 캐쉬하지 않고 이용하면 성능이 저하 될 수 있습니다. 컨트롤러나 모텔에서는 드물게 사용됩니다.
// Controller/CommentsController.php
class CommentsController extends AppController {
public function latest() {
if (empty($this->request->params['requested'])) {
throw new ForbiddenException();
}
return $this->Comment->find('all', array('order' => 'Comment.created DESC', 'limit' => 10));
}
}
requestAction()에서 실행하고자 하는 메소드는 실제로 requestAction()에서 리퀘스트가 발행되었는지를 체크할 필요가 있습니다. 그렇지 않으면 그 메소드는 URL로 부터 직접적으로 접근가능하게 되어버립니다. 이것은 추천되지 않습니다.
위의 함수를 호출하는 간단한 엘리먼트를 작성하면:
// View/Elements/latest_comments.ctp
$comments = $this->requestAction('/comments/latest');
foreach ($comments as $comment) {
echo $comment['Comment']['title'];
}
어딘가 출력하고 싶은 곳에 방금 전의 엘리먼트를 배치 할 수 있습니다.
echo $this.element('latest_comments');
이 방법은 엘리먼트가 작성성될때마다 매번 데이터터를 가져오기 위해 컨트롤러에 요청을 만들어 데이터가 처리 되어 결과가 되돌아옵니다. 따라서 불필요한 처리를 방지하기 위해 엘리먼트의 캐쉬를 사용하는 것이 좋습니다.
echo $this->element('latest_comments', array(), array('cache' => true));
requestAction()의 호출은 캐쉬된 엘리먼트의 뷰파일이 존재하고 유효할 경우 요청은 발행되지 않습니다.
또한, requestAction()은 CakePHP형식의 URL배열을 인수로 취할 수 있습니다.
echo $this->requestAction(
array('controller' => 'articles', 'action' => 'featured'),
array('return')
);
이것은 requestAction()의 호출이 성능 향상이 가능한 Router::url()의 이용을 피하는 것이 가능합니다.
배열 기반의 URL은 다음 한가지를 제외하고 Htmlhelper:link()를 사용하는 것과 같습니다. 다른 점은 명명된 파라메터터나 GET으로 전달되는 파라메터를 사용할 경우 그것을 2번째 인수에 지정하여 적절한 키로 랩핑하지 않으면 안되는 것입니다. 이것은 requestAction() 가 명명된 파라메터의 배열(requestAction의 2번째의 인수)를 Controller:params 배열에 병합하여 명명된 파라메터에 대해 명시적으로 'named'과 같은 키를 지정하지 않기 때문입니다. $option 배열에 지정한 추가한 값은 요청된 액션의 Contoller::params 배열의 안에서 사용할 수 있습니다.
echo $this->requestAction('/articles/featured/limit:3');
echo $this->requestAction('/articles/view/5');
위의 경우 requestAction()
의 배열은 다음과 같습니다.
echo $this->requestAction(
array('controller' => 'articles', 'action' => 'featured'),
array('named' => array('limit' => 3))
);
echo $this->requestAction(
array('controller' => 'articles', 'action' => 'view'),
array('pass' => array(5))
);
requestAction()로 배열의 URL을 사용할 경우 요청한 액션에서 필요로 하는 모든 파라메터를 지정해야 합니다. 이것은 $this->request->data
와 같은 파라메터도 포함됩니다. 필요한 모든 매개 변수를 전달할뿐만 아니라 명명된 파라메터와 GET 파라메터도 위와 같이 2번째의 인수로 지정해야합니다.
Controller::loadModel(string $modelClass, mixed $id)
loadModel() 함수는 컨트롤러 디포드 모델 또는 과련된 모델 이외의 모델을 사용할 필요가 있을 경우 편리합니다.$this->loadModel('Article');
$recentArticles = $this->Article->find('all', array('limit' => 5, 'order' => 'Article.created DESC'));
$this->loadModel('User', 2);
$user = $this->User->read();
컨트롤러 변수
컨트롤러의 변수와 설명은 CakePHP API를 확인해주세요. http://api.cakephp.org/2.6/class-Controller.htmlproperty
Controller::$name
$name 변수는 컨트롤러명이 설정되어집니다. 보통 이것은 컨트롤러가 사용하는 메인 코델의 복수형입니다. 이 프로퍼티는 필수는 아닙니다.
// $name 변수의 사용 예
class RecipesController extends AppController {
public $name = 'Recipes';
}
$components와 $helpers와 $uses
다음 설명할 컨트롤러의 변수는 현재 컨트롤러 안에서 어떤 헬퍼, 컴포넌트, 코델을 사용할지를 CakePHP에 전달하는 역활을 합니다. 이 변수는 자주 사용됩니다. 이것들을 사용하여 $components나 $uses에 할당된 MVC 클래스는 컨트롤러의 안에서 클래스 변수로서 (예 $this->ModelName), 또는 $helpers에 할당된 클래스는 뷰의 안에서 오브젝트의 참조로(예를 들 Ethis->{$helpername}) 사용할 수 있습니다.각각의 컨트롤러는 기본적으로 이러한 클래스를 몇개 가지고 있어 사용 할 수 있는 상태입니다. 따라서 컨트롤러는 모두 설정 할 필요는 없습니다.
property
Controller::$uses
컨트롤러는 기본적으로 중효한 모텔에 접근 가능하도록 되어있습니다. RecipesController는 $this->Recipe에 접근 가능한 모델 클래스를 가지고 있으며 ProductsController 역시 $this->Product로 Product모델을 가지고 있습니다.
그리고 컨트롤러가 $uses 변수에 추가 모델ㅇ르 지정하여 그것들이 사용 가능하게 될때에 $uses에 현재의 컨트롤러의 모델 명도 포함하지 않으면 안됩니다. 이것에 대해서는 아래 예제에서 설명합니다.
컨트롤러에서 모델을 사용하고 싶지 않을 경우는 public $uses = array() 를 설정해 주세요. 이것으로 컨트롤러에 대응하는 모델 파일이 필요 없게 됩니다.
property
Controller::$helpers
SessionComponent와 같이 HtmlHelper, FormHelper, SessionHelper는 기본적으로 사용할 수 있습니다. 따라서 AppController에서 $helpers를 독자적으로 정의할 경우 HtmlHelper dhk FormHelper를 콘트롤러에서 사용할 수 있도록 하지 않으면 안됩니다. 그것들을 $helpers에 포함되도록 해주세요.
추가로 이용할 MVC 클래스들을 어떻게 CakePHP의 컨트롤러에 전달하는지 살펴봅니다.:
class RecipesController extends AppController{
public $uses = array('Recipe', 'User');
public $helpers = array('Js');
public $components = array('RequestHandler');
}
이 변수들은 상속한 값과 병합됩니다. 따라서 예를 들어 FormHelper나 AppController에 선언되어 있는 클래스를 다시 선언 할 필요가 없습니다.
property
Controller::$components
components 배열은 컨트롤러에서 사용하는 컴포넌트를 설정합니다. $helpers나 $uses와 같이 컨트롤러의 컴포넌트는 AppController의 컴포넌트와 병합됩니다. $helpers와 같이 $componetns에 설정을 전달하는 것도 가능합니다. 보다 상세한 내용은 컴포넌트의 설정을 참조해 주세요.
그 외의 변수
컨트롤러의 변수의 세부내용은 API페이지를 보면 여기의 설명 이외의 다른 컨트롤러변수에 대한 섹션이 있습니다.property
Controller::$cacheAction
cacheAction변수는 전체 페이지 캐쉬의 유지시간이나 다른 정보를 정의하기 위해서 사용됩니다. 전체 페이지 캐쉬에 대한 세부내용은 CacheHelper의 문서를 확인해주세요.
property
Controller::$paginate
paginate변수는 비추천의 호환성이 있는 프로퍼티입니다. 이 변수를 사용하여 PaginatorComponent의 로딩과 설정을 합니다. 다음과 같이 컴포넌트의 설정을 수정하는 것을 추천합니다.
class ArticlesController extends AppController{
public $components = array(
'Paginator' => array(
'Article' => array(
'conditions' => array('published' => 1)
)
)
);
}
'PHP' 카테고리의 다른 글
[CakePHP] Controller - Components (0) | 2015.05.08 |
---|---|
[CakePHP] Controller - PageController (0) | 2015.05.08 |
[CakePHP] Controller - Scaffolding (0) | 2015.05.08 |
[CakePHP] CakeResponse (0) | 2015.05.07 |
[CakePHP] CakeRequest 요청 객체 (0) | 2015.05.07 |
HAProxy
haproxy는 오픈 소스 로드 벨런서로서 손쉽게 서비스 이중화가 가능하도록 합니다.
설치 환경
CentOS release 6.4 (Final)
haproxy-1.5.2
Link
- HAProxy home page
http://www.haproxy.org/ - Configuration Manual
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html
다운로드 및 압축 해제
먼저 haproxy의 컴파일에 필요한 모듈을 설치합니다.
$ yum install wget gcc gcc-c++ autoconf automake make openssl openssl-devel pcre-devel zlib
haproxy를 다운로드
$ wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.2.tar.gz
압축을 해제하고 소스 디렉도리로 이동.
$ tar zxvf haproxy-1.5.2.tar.gz
$ cd haproxy-1.5.2
컴파일및 설치.
README파일에 예제가 상세하게 기술 되어 있니 참고하여 옵션을 설정합니다.
$ make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
$ make install
> uname -a //현재 OS의 버전 확인. Linux lvm01 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linuxmake install를 실행하면 아래와 같이 설치 위치가 출력됨.
install -d /usr/local/sbin install haproxy /usr/local/sbin install haproxy-systemd-wrapper /usr/local/sbin install -d /usr/local/share/man/man1 install -m 644 doc/haproxy.1 /usr/local/share/man/man1 install -d /usr/local/doc/haproxy for x in configuration architecture haproxy-en haproxy-fr; do \ install -m 644 doc/$x.txt /usr/local/doc/haproxy ; \ done
haproxy 설정
examples 폴더에 기동 스크립트와 설정 파일과 관련한 예제 파일들이 있으니 예제 파일을 이용하여 설정합니다.
$ mkdir /etc/haproxy
$ cp ./examples.cfg /etc/haproxy/haproxy.cfg
$ vi /etc/haproxy/haproxy.cfg
lobal log 127.0.0.1 local0 log 127.0.0.1 local1 notice #log loghost local0 info maxconn 4096 chroot /usr/share/haproxy uid 99 gid 99 daemon #debug #quiet defaults log global mode http option httplog option dontlognull option forwardfor retries 3 maxconn 2000 option redispatch timeout connect 5000 timeout client 50000 timeout server 50000 listen appli1-rewrite bind *:80 cookie SERVERID rewrite cookie JSESSIONID prefix balance roundrobin server webserver1 172.16.120.172:80 cookie webserver1 check inter 2000 rise 2 fall 5 server webserver2 172.16.120.173:80 cookie webserver2 check inter 2000 rise 2 fall 5 listen stats :4997 mode http stats enable stats hide-version stats realm Haproxy\ Statistics stats uri / stats auth admin:pwd
예제 디렉토리에서 기동 스크립트 복사
$ cp examples/haproxy.init /etc/init.d/haproxy
/etc/init.d/haproxy start : 시작 /etc/init.d/haproxy stop : 정지 /etc/init.d/haproxy restart : 재기동
위와 같이 설정하여도 로그 파일이 출력되지 않음.
로그 파일을 출력하기 위해서는 rsyslog를 설치하여 기동해야함.
※ rsyslog : 중앙 집중형 원격 시스템에 로깅
rsyslog설치
$ yum install rsyslog
rsyslog설정 파일 백업 후 설정
$ vi /etc/rsyslog.d/haproxy.conf
$ModLoad imudp $UDPServerRun 514 $template Haproxy, "%msg%\n" local0.=info -/var/log/haproxy.log;Haproxy local1.notice -/var/log/haproxy-status.log;Haproxy local0.* ~
rsyslog의 설정후 rsyslog와 haproxy를 재기동 하면 로그가 rsyslog에 설정한 위치에 기록되는 것을 확인 할 수 있다.
$ /etc/init.d/rsyslog restart
$ /etc/init.d/haproxy restart
테스트용 webserver설치
테스트 용으로 haproxy에서 로드 밸런싱 설정한 두개의 서버에 apache를 설치한다.
$ yum install httpd httpd-devel openssl openssl-devel gcc gcc-c++ pcre-devel zlib
테스트용 파일 생성 후 httpd 시작.
$ echo hostname
> /var/www/html/server.html
$ /etc/init.d/httpd start
haproxy 확인
브라우저로 haproxy 서버의 아이피의 server.html파일을 요청하면 설정대로 두개의 서버로 밸런싱 되어 페이지가 표시되는 것을 확인 할 수 있다.
http://haproxy서버/server.html
그러나,
테스트용 웹서버에서 httpd의 액세스 로그를 확인하면 클라이언트의 야이피가 아닌 haproxy서버의 아이가 출력됨.
httpd 액세스 로그에 haproxy가 아닌 클라이언트의 ip가 출력되도록 설정 방법.
위의 haproxy 설정에서 이미 클라이언트 정보를 전달하도록 되어 있습니다.
option forwardfor
방법 1.
header의 X-Forwarded-For 를 출력하도록 로그 포멧을 변경하면 된다.
웹서버의 LogFormat에서 %h -> %{X-Forwarded-For}i로 수정.
$ vi /etc/httpd/conf/httpd.conf
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
방법 2.
웹서버에 mod_rpaf 모듈을 설치해서 애플리케이션 서버가 HTTP 헤더에서 클라이언트 IP 주소를 조회하면 실제 클라이언트 IP 주소가 반환되도록 함.
- mod_rpaf : http://www.stderr.net/apache/rpaf
$ wget http://www.stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
$ tar zxvf mod_rpaf-0.6.tar.gz
$ cd mod_rpaf-0.6
$ apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c
$ vi /etc/httpd/conf/httpd.conf
LoadModule rpaf_module modules/mod_rpaf-2.0.so RPAFenable On RPAFsethostname On RPAFproxy_ips {haproxy서버 아이피} ## 여러 아이피를 지정할 경우 스페이스 후에 연속하여 기술 ## RPAFproxy_ips 127.0.0.1 xxx.xxx.xxx.xxx
참고
소프트웨어 로드 밸런서 실제 사용할 때 1 vCPU + 1G 메모리로 약 10k~100k HTTP request/sec 처리. ulimit, conntrack, … 등의 설정이 필요. HAProxy 의 stats socket 정보 확인하여 적절히 수정
keepalived는 서비스의 가동 상태를 감시하는 소프트웨어로 서비스에 장애가 발생하여 정시했을 경우 그 서버로 오는 요청을 다른 가용 서버로 할당하도록 하여 서비스가 정지하지 않고 무정지 운영이 가능하도록 하는 기능을 가지고 있습니다.
환경
CentOS release 6.4
Link
설치
테스트를 위하여 두대의 서버가 필요합니다.
현재 최신 버전은 Version 1.2.13 이지만 yum을 통하여 두대의 서버에 동일하게 keepalived를 설치합니다.
1.2.7 버전이 설치 되네요.
$ yum install keepalived
keepalived 설정
설치된 설정 파일을 백업하고 수정합니다.
$ cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.org
$ vi /etc/keepalived/keepalived.conf
Master Server (172.16.120.172)
! Configuration File for keepalived global_defs { notification_email { # 메일 관련 기능은 생략 } } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 200 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { # 동일한 가상 IP 172.16.120.150 } }
Backup Server (172.16.120.173)
! Configuration File for keepalived global_defs { notification_email { # 메일 관련 기능은 생략 } } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { # 동일한 가상 IP 172.16.120.150 } }
서비스 시작
Master, Backup 서버에서 keepalived를 시작합니다.
$ /etc/init.d/keepalived start
동작확인
두 서버에서 설정한 가상 IP인 172.16.120.150로 요청을 보내게 되면
최초 MASTER 서버로만 요청이 가게 됩니다.
MASTER 서버를 정시하고 172.16.120.150로 요청을 하게 되면 Backup서버로 요청이 가게 됩니다.
간단한 테스트 방법으로는 제 3의 서버에서 172.16.120.150로 ping을 실행시켜 두고 Master, Backup 서버를 번갈아 가면 정지 기동 하여도 ping은 끊김없이 지속적으로 가는 것을 확인 할 수 있습니다.