Phalcon 控制器
使用控制器(Using Controllers)
Actions是控制器中用於處理請求的方法。默認情況下,控制器中所有公共方法都映射到Actions,能夠通過URL訪問。Actions負責解釋請求並創建響應,響應通常以視圖形式呈現,或通過其他方式創建。
當訪問類似http://localhost/blog/posts/show/2015/the-post-title的URL時,Phalcon會像下面這樣解析URL的各個部分:
| Phalcon目錄 | blog |
| 控制器 | posts |
| 方法 | show |
| 參數 | 2015 |
| 參數 | the-post-title |
這種情況下,控制器PostsController將負責處理該請求。控制器可以通過Phalcon\Loader加載,因此控制器存放在應用中什麼地方,並沒有強制要求,可以根據需求自由的組織控制器。
控制器名稱以Controller結尾,Actions名稱以Action結尾。
<?php
use Phalcon\Mvc\Contrller;
class PostsController extends Contrller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
}
}
額外的URI參數被定義為Action的參數,可以通過局部變量訪問它們。控制器如果繼承基類Phalcon\Mvc\Controller,便可以訪問應用中的各種服務。
沒有默認值的參數被視為必選參數,可以像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)
調度循環在調度器中運行,直到沒有剩餘操作需要執行。上例中,只有一個動作被執行。forward()方法在調度循環中提供更復雜的操作流,可以將操作轉發給其他控制器 / 方法。
<?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"
);
// 轉發給另一個方法
$this->dispatcher->forward(
[
'controller' => 'users',
'action' => 'signin',
]
);
}
}
如果用户沒有訪問某個方法的權限,則將用户轉發到UsersController控制器的signin方法。
<?php
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function indexAction()
{
}
public function signinAction()
{
}
}
初始化控制器(Initializing Controllers)
Phalcon\Mvc\Controller提供了initialize()方法,它在所有方法被執行前執行,不建議使用構造方法__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') {
// ...
}
}
}
只有當beforeExecuteRoute事件成功執行時,initialize()方法才被調用,避免了初始化方法中的應用邏輯無法在未授權的情況下執行。
如果想在構造控制器對象之後執行初始化邏輯,可以實現onConstruct()方法:
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function onConstruct()
{
// ...
}
}
注意,即使被調用的方法不存在於控制器中,或者用户無權訪問(根據開發者定義的權限控制)該方法,onConstruct()方法仍會被執行。
注入服務(Injecting Services)
繼承了Phalcon\Mvc\Controller的控制器,可以訪問應用中的服務容器。例如,如果註冊了這樣的服務:
<?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');
$this->getDi()->getStorage()->save('/some/file');
// 使用數組語法
$this->di['storage']->save('/some/file');
}
}
請求和響應(Request and Response)
假設框架預先註冊好了服務。request服務包含一個Phalocn\Http\Request實例,response服務包含一個Phalcon\Http\Response實例,表示將要發送給客户端的內容。
<?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');
}
}
}
響應對象通常不是直接被使用,而是在方法執行前構建。有時,比如afterDispatch事件中,直接訪問響應對象很有用:
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function notFoundAction()
{
// 發送HTTP 404 響應頭
$this->response->setStatusCode(404, 'Not Found');
}
}
Session數據(Session Data)
Session能夠在請求之間維持持久的數據,可以從任何控制器中訪問Phalcon\Session\Bag來封裝需要持久化的數據:
<?php
use Phalcon\Mvc\Controller;
class UserController extends Controller
{
public function indexAction()
{
$this->persistent->name = 'Micheal';
}
public function welcomeAction()
{
echo 'Welcome, ', $this->persistent->name;
}
}
服務充當控制器(Using Services as Controller)
服務可以充當控制器,控制器總是從服務容器中請求。因此,以類名稱註冊的任何服務,都可以充當控制器角色:
<?php
// 將控制器註冊為服務
$di->set(
'IndexController',
function () {
$component = new Component();
return $component;
}
);
// 帶命名空間的控制器
$di->set(
'Backend\Controllers\IndexController',
function () {
$component = new Component();
return $component;
}
);
控制器事件(Events in Controllers)
控制器自動監聽調度事件,實現與事件名稱同名的方法,可以在操作執行之前 / 之後實現鈎子:
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function beforeExecuteRoute($dispatcher)
{
// 在所有動作之前執行
if ($dispatcher->getActionName() === 'save') {
$this->flash->error(
"You don't have permission to save posts"
);
$this->dispatcher->forward(
[
'controller' => 'home',
'action' => 'index',
]
);
}
}
public function afterExecuteRoute($dispatcher)
{
// 在所有動作之後執行
}
}