# 使用控制器(Using Controllers)
控制器提供了一堆可以被調用的方法,即:action。action是控制器中用于處理請求的方法。默認情況下,全部 控制器public的方法都會映射到action并且可以通過URL訪問。action負責解釋請求和創建響應。 通常,響應是以渲染的視圖格式被創建,但也存在其他的方式來創建(譯者注:如AJAX請求返回JSON格式的數據)。
例如,當你訪問一個類似這樣的URL時:[http://localhost/blog/posts/show/2015/the-post-title](http://localhost/blog/posts/show/2015/the-post-title),Phalcon默認會這樣分解各個部分:
Phalcon目錄blog控制器postsActionshow參數2015參數the-post-title
這時,PostsController將會處理這個請求。在一個項目中,沒有強制指定放置控制器的地方,這些控制器都可以 通過使用[autoloaders](http://docs.iphalcon.cn/reference/loader.html)來加載,所以你可以根據需要自由組件你的控制器。
控制器類必須以“Controller”為后綴,action則須以“Action”為后綴。一個控制器類的例子如下:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
}
}
~~~
額外的URI參數定義為action的參數,以致這些參數可以簡單地通過本地變量來獲取。控制器 可以選擇繼承[Phalcon\\Mvc\\Controller](http://docs.iphalcon.cn/api/Phalcon_Mvc_Controller.html)。如果繼承此基類,你的控制器類則能 輕松訪問應用的各種服務。
沒有默認缺省值的參數視為必須參數處理。可以像PHP那樣為參數設定一個默認值:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year = 2015, $postTitle = "some default title")
{
}
}
~~~
參數將會按路由傳遞和函數定義一樣的順序來賦值。你可以使用以下根據參數名稱的方式來獲取任意一個參數:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction()
{
$year = $this->dispatcher->getParam("year");
$postTitle = $this->dispatcher->getParam("postTitle");
}
}
~~~
## 循環調度(Dispatch Loop)
循環調度將會在分發器執行,直到沒有action需要執行為止。在上面的例子中,只有一個action 被執行到。現在讓我們來看下:code:[`](http://docs.iphalcon.cn/reference/controllers.html#id1)forward()``(轉發)怎樣才能在循環調度里提供一個更加復雜的操作流,從而將執行轉發到 另一個controller/action。
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
$this->flash->error(
"You don't have permission to access this area"
);
// Forward flow to another action
$this->dispatcher->forward(
[
"controller" => "users",
"action" => "signin",
]
);
}
}
~~~
如果用戶沒有訪問某個action的權限,那么請求將會被轉發到Users控制器的signin行為。
~~~
<?php
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function indexAction()
{
}
public function signinAction()
{
}
}
~~~
對于“forwards”轉發的次數沒有限制,只要不會形成循環重定向即可,否則就意味著 你的應用將會停止(譯者注:如果瀏覽器發現一個請求循環重定向時,會終止請求)。 如果在循環調度里面沒有其他action可以分發,分發器將會自動調用由[Phalcon\\Mvc\\View](http://docs.iphalcon.cn/api/Phalcon_Mvc_View.html)管理的MVC的視圖層。
## 初始化控制器(Initializing Controllers)
[Phalcon\\Mvc\\Controller](http://docs.iphalcon.cn/api/Phalcon_Mvc_Controller.html)提供了初始化的函數,它會最先執行,并優于任何控制器 的其他action。不推薦使用“\_\_construct”方法。
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public $settings;
public function initialize()
{
$this->settings = [
"mySetting" => "value",
];
}
public function saveAction()
{
if ($this->settings["mySetting"] === "value") {
// ...
}
}
}
~~~
> `initialize()`僅僅會在事件“beforeExecuteRoute”成功執行后才會被調用。這樣可以避免 在初始化中的應用邏輯在未鑒權的情況下無法執行。
如果你想在緊接著創建控制器對象的后面執行一些初始化的邏輯,你要實現:code:onConstruct()”方法:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function onConstruct()
{
// ...
}
}
~~~
> 需要注意的是,即使待執行的action在控制器不存在,或者用戶沒有 訪問到它(根據開發人員提供的自定義控制器接入),“onConstruct”都會被執行。
## 注入服務(Injecting Services)
如果控制器繼承于[Phalcon\\Mvc\\Controller](http://docs.iphalcon.cn/api/Phalcon_Mvc_Controller.html),那么它可以輕松訪問 應用的服務容器。例如,如果我們類似這樣注冊了一個服務:
~~~
<?php
use Phalcon\Di;
$di = new Di();
$di->set(
"storage",
function () {
return new Storage(
"/some/directory"
);
},
true
);
~~~
那么,我們可以通常多種方式來訪問這個服務:
~~~
<?php
use Phalcon\Mvc\Controller;
class FilesController extends Controller
{
public function saveAction()
{
// 以和服務相同名字的類屬性訪問
$this->storage->save("/some/file");
// 通過DI訪問服務
$this->di->get("storage")->save("/some/file");
// 另一種方式:使用魔法getter來訪問
$this->di->getStorage()->save("/some/file");
// 另一種方式:使用魔法getter來訪問
$this->getDi()->getStorage()->save("/some/file");
// 使用數組下標
$this->di["storage"]->save("/some/file");
}
}
~~~
如果你是把Phalcon作為全能(Full-Stack)框架來使用,你可以閱讀框架中[by default](http://docs.iphalcon.cn/reference/di.html)提供的服務。
## 請求與響應(Request and Response)
假設框架預先提供了一系列的注冊的服務。我們這里將解釋如何和HTTP環境進行關聯和交互。 “request”服務包含了一個[Phalcon\\Http\\Request](http://docs.iphalcon.cn/api/Phalcon_Http_Request.html)的實例, “response”服務則包含了一個[Phalcon\\Http\\Response](http://docs.iphalcon.cn/api/Phalcon_Http_Response.html)的實例,用來表示將要返回給客戶端的內容。
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function saveAction()
{
// 檢查請求是否為POST
if ($this->request->isPost()) {
// 獲取POST數據
$customerName = $this->request->getPost("name");
$customerBorn = $this->request->getPost("born");
}
}
}
~~~
響應對象通常不會直接使用,但在action的執行前會被創建,有時候 - 如在 一個afterDispatch事件中 - 它對于直接訪問響應非常有幫助:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function notFoundAction()
{
// 發送一個HTTP 404 響應的header
$this->response->setStatusCode(404, "Not Found");
}
}
~~~
如需學習了解HTTP環境更多內容,請查看專題:[request](http://docs.iphalcon.cn/reference/request.html)和[response](http://docs.iphalcon.cn/reference/response.html)。
## 會話數據(Session Data)
會話可以幫助我們在多個請求中保持持久化的數據。你可以從任何控制器中訪問[Phalcon\\Session\\Bag](http://docs.iphalcon.cn/api/Phalcon_Session_Bag.html)以便封裝需要進行持久化的數據。
~~~
<?php
use Phalcon\Mvc\Controller;
class UserController extends Controller
{
public function indexAction()
{
$this->persistent->name = "Michael";
}
public function welcomeAction()
{
echo "Welcome, ", $this->persistent->name;
}
}
~~~
## 在控制器中使用服務(Using Services as Controllers)
服務可以是控制器,控制器類通常會從服務容器中請求。據于此, 任何一個用其名字注冊的類都可以輕易地用一個控制器來替換:
~~~
<?php
// 將一個控制器作為服務進行注冊
$di->set(
"IndexController",
function () {
$component = new Component();
return $component;
}
);
// 將一個命名空間下的控制器作為服務進行注冊
$di->set(
"Backend\\Controllers\\IndexController",
function () {
$component = new Component();
return $component;
}
);
~~~
## 控制器中的事件(Events in Controllers)
控制器會自動作為[dispatcher](http://docs.iphalcon.cn/reference/dispatching.html)事件的偵聽者,使用這些事件并實現這些方法后, 你便可以實現對應被執行的action的before/after鉤子函數:
~~~
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function beforeExecuteRoute($dispatcher)
{
// 這個方法會在每一個能找到的action前執行
if ($dispatcher->getActionName() === "save") {
$this->flash->error(
"You don't have permission to save posts"
);
$this->dispatcher->forward(
[
"controller" => "home",
"action" => "index",
]
);
return false;
}
}
public function afterExecuteRoute($dispatcher)
{
// 在找到的action后執行
}
}
~~~
- 簡介
- 安裝
- 安裝(installlation)
- XAMPP下的安裝
- WAMP下安裝
- Nginx安裝說明
- Apache安裝說明
- Cherokee 安裝說明
- 使用 PHP 內置 web 服務器
- Phalcon 開發工具
- Linux 系統下使用 Phalcon 開發工具
- Mac OS X 系統下使用 Phalcon 開發工具
- Windows 系統下使用 Phalcon 開發工具
- 教程
- 教程 1:讓我們通過例子來學習
- 教程 2:INVO簡介
- 教程 3: 保護INVO
- 教程4: 使用CRUD
- 教程5: 定制INVO
- 教程 6: V?kuró
- 教程 7:創建簡單的 REST API
- 組件
- 依賴注入與服務定位器
- MVC架構
- 使用控制器
- 使用模型
- 模型關系
- 事件與事件管理器
- Behaviors
- 模型元數據
- 事務管理
- 驗證數據完整性
- Workingwith Models
- Phalcon查詢語言
- 緩存對象關系映射
- 對象文檔映射 ODM
- 使用視圖
- 視圖助手
- 資源文件管理
- Volt 模版引擎
- MVC 應用
- 路由
- 調度控制器
- Micro Applications
- 使用命名空間
- 事件管理器
- Request Environmen
- 返回響應
- Cookie 管理
- 生成 URL 和 路徑
- 閃存消息
- 使用 Session 存儲數據
- 過濾與清理
- 上下文編碼
- 驗證Validation
- 表單_Forms
- 讀取配置
- 分頁 Pagination
- 使用緩存提高性能
- 安全
- 加密與解密 Encryption/Decryption
- 訪問控制列表
- 多語言支持
- 類加載器 Class Autoloader
- 日志記錄_Logging
- 注釋解析器 Annotations Parser
- 命令行應用 Command Line Applications
- Images
- 隊列 Queueing
- 數據庫抽象層
- 國際化
- 數據庫遷移
- 調試應用程序
- 單元測試
- 進階技巧與延伸閱讀
- 提高性能:下一步該做什么?
- Dependency Injection Explained
- Understanding How Phalcon Applications Work
- Api
- Abstract class Phalcon\Acl