[TOC]
# MVC 應用
在Phalcon中編排MVC操作的所有艱苦工作通常由`Phalcon\Mvc\Application`完成。該組件封裝了后臺所需的所有復雜操作,實例化了所需的每個組件并將其與項目集成,以允許MVC模式按需運行。
以下引導代碼是Phalcon應用程序的典型代碼:
```php
<?php
use Phalcon\Mvc\Application;
// 注冊自動加載器
// ...
// 注冊服務
// ...
// 處理請求
$application = new Application($di);
try {
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
```
調用`handle()`時是控制器的所有工作的核心:
```php
<?php
$response = $application->handle();
```
## 手動引導
如果您不想使用`Phalcon\Mvc\Application`,可以按如下方式更改上面的代碼:
```php
<?php
// 獲取 router 服務
$router = $di['router'];
$router->handle();
$view = $di['view'];
$dispatcher = $di['dispatcher'];
// 將已處理的路由器參數傳遞給調度程序
$dispatcher->setControllerName(
$router->getControllerName()
);
$dispatcher->setActionName(
$router->getActionName()
);
$dispatcher->setParams(
$router->getParams()
);
// 開始視圖
$view->start();
// 發送請求
$dispatcher->dispatch();
// 呈現相關視圖
$view->render(
$dispatcher->getControllerName(),
$dispatcher->getActionName(),
$dispatcher->getParams()
);
// 結束視圖
$view->finish();
$response = $di['response'];
// 將視圖的輸出傳遞給響應
$response->setContent(
$view->getContent()
);
// 發送響應
$response->send();
```
以下替換`Phalcon\Mvc\Application`缺少一個視圖組件,使其適用于Rest API:
```php
<?php
use Phalcon\Http\ResponseInterface;
// 獲取 router 服務
$router = $di['router'];
$router->handle();
$dispatcher = $di['dispatcher'];
// 將已處理的路由器參數傳遞給調度程序
$dispatcher->setControllerName(
$router->getControllerName()
);
$dispatcher->setActionName(
$router->getActionName()
);
$dispatcher->setParams(
$router->getParams()
);
// 發送請求
$dispatcher->dispatch();
// 通過上次執行的操作獲取返回值
$response = $dispatcher->getReturnedValue();
// 檢查返回的操作是否為“響應”對象
if ($response instanceof ResponseInterface) {
// 發送響應
$response->send();
}
```
另一種替代方法是捕獲調度員轉發到其他操作時產生的異常:
```php
<?php
use Phalcon\Http\ResponseInterface;
// 獲取 router 服務
$router = $di['router'];
$router->handle();
$dispatcher = $di['dispatcher'];
// 將已處理的路由器參數傳遞給調度程序
$dispatcher->setControllerName(
$router->getControllerName()
);
$dispatcher->setActionName(
$router->getActionName()
);
$dispatcher->setParams(
$router->getParams()
);
try {
// 發送請求
$dispatcher->dispatch();
} catch (Exception $e) {
// 發生異常,發送一些針對此的控制器/操作
// 將已處理的路由器參數傳遞給調度程序
$dispatcher->setControllerName('errors');
$dispatcher->setActionName('action503');
// 發送請求
$dispatcher->dispatch();
}
// 通過上次執行的操作獲取返回值
$response = $dispatcher->getReturnedValue();
// 檢查返回的操作是否為“響應”對象
if ($response instanceof ResponseInterface) {
// 發送響應
$response->send();
}
```
雖然上述實現比使用`Phalcon\Mvc\Application`時所需的代碼要冗長得多,但在引導應用程序時提供了另一種選擇。根據您的需要,您可能希望完全控制應該實例化的內容,或者使用您自己的組件替換某些組件以擴展默認功能。
## 單/多模塊應用
使用此組件,您可以運行各種類型的MVC結構:
### 單模塊
單個MVC應用程序僅包含一個模塊。可以使用命名空間,但不是必需的。像這樣的應用程序將具有以下文件結構:
```php
single/
app/
controllers/
models/
views/
public/
css/
img/
js/
```
如果未使用名稱空間,則可以使用以下引導文件來編排MVC流:
```php
<?php
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
$loader = new Loader();
$loader->registerDirs(
[
'../apps/controllers/',
'../apps/models/',
]
);
$loader->register();
$di = new FactoryDefault();
// 注冊視圖組件
$di->set(
'view',
function () {
$view = new View();
$view->setViewsDir('../apps/views/');
return $view;
}
);
$application = new Application($di);
try {
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo $e->getMessage();
}
```
如果使用名稱空間,可以使用以下引導程序:
```php
<?php
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
$loader = new Loader();
// 使用帶名稱空間前綴的自動加載
$loader->registerNamespaces(
[
'Single\Controllers' => '../apps/controllers/',
'Single\Models' => '../apps/models/',
]
);
$loader->register();
$di = new FactoryDefault();
// 為控制器注冊默認調度程序的命名空間
$di->set(
'dispatcher',
function () {
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace('Single\Controllers');
return $dispatcher;
}
);
// 注冊視圖組件
$di->set(
'view',
function () {
$view = new View();
$view->setViewsDir('../apps/views/');
return $view;
}
);
$application = new Application($di);
try {
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo $e->getMessage();
}
```
### 多模塊
多模塊應用程序對多個模塊使用相同的文檔根。在這種情況下,可以使用以下文件結構:
```php
multiple/
apps/
frontend/
controllers/
models/
views/
Module.php
backend/
controllers/
models/
views/
Module.php
public/
css/
img/
js/
```
apps/ 中的每個目錄都有自己的MVC結構。`Module.php`用于配置每個模塊的特定設置,如自動加載器或自定義服務:
```php
<?php
namespace Multiple\Backend;
use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\DiInterface;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\ModuleDefinitionInterface;
class Module implements ModuleDefinitionInterface
{
/**
* 注冊模塊的特定自動加載
*/
public function registerAutoloaders(DiInterface $di = null)
{
$loader = new Loader();
$loader->registerNamespaces(
[
'Multiple\Backend\Controllers' => '../apps/backend/controllers/',
'Multiple\Backend\Models' => '../apps/backend/models/',
]
);
$loader->register();
}
/**
* 注冊模塊的特定服務
*/
public function registerServices(DiInterface $di)
{
// 注冊調度器
$di->set(
'dispatcher',
function () {
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace('Multiple\Backend\Controllers');
return $dispatcher;
}
);
// 注冊視圖組件
$di->set(
'view',
function () {
$view = new View();
$view->setViewsDir('../apps/backend/views/');
return $view;
}
);
}
}
```
加載多模塊MVC架構需要特殊的引導程序文件:
```php
<?php
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
$di = new FactoryDefault();
// 指定模塊的路由
$di->set(
'router',
function () {
$router = new Router();
$router->setDefaultModule('frontend');
$router->add(
'/login',
[
'module' => 'backend',
'controller' => 'login',
'action' => 'index',
]
);
$router->add(
'/admin/products/:action',
[
'module' => 'backend',
'controller' => 'products',
'action' => 1,
]
);
$router->add(
'/products/:action',
[
'controller' => 'products',
'action' => 1,
]
);
return $router;
}
);
// 創建一個應用
$application = new Application($di);
// 注冊已安裝的模塊
$application->registerModules(
[
'frontend' => [
'className' => 'Multiple\Frontend\Module',
'path' => '../apps/frontend/Module.php',
],
'backend' => [
'className' => 'Multiple\Backend\Module',
'path' => '../apps/backend/Module.php',
]
]
);
try {
// 處理請求
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo $e->getMessage();
}
```
如果要在引導文件中維護模塊配置,可以使用匿名函數注冊模塊:
```php
<?php
use Phalcon\Mvc\View;
// 創建一個視圖組件
$view = new View();
// 給視圖組件設置參數
// ...
// 注冊已安裝的模塊
$application->registerModules(
[
'frontend' => function ($di) use ($view) {
$di->setShared(
'view',
function () use ($view) {
$view->setViewsDir('../apps/frontend/views/');
return $view;
}
);
},
'backend' => function ($di) use ($view) {
$di->setShared(
'view',
function () use ($view) {
$view->setViewsDir('../apps/backend/views/');
return $view;
}
);
}
]
);
```
當`Phalcon\Mvc\Application`注冊了模塊時,每個匹配的路由都必須返回一個有效的模塊。每個注冊的模塊都有一個關聯的類,它提供了設置模塊本身的功能。每個模塊類定義必須實現兩個方法:`registerAutoloaders()`和`registerServices()`,它們將由`Phalcon\Mvc\Application`根據要執行的模塊調用。
## 應用事件
`Phalcon\Mvc\Application` 能夠將事件發送到EventsManager(如果存在)。使用類型`application`觸發事件。支持以下事件:
| 事件名稱 | Triggered |
| --------------------- | -------------------------------- |
| `boot` | 在應用程序處理其第一個請求時執行 |
| `beforeStartModule` | 在初始化模塊之前,僅在注冊模塊時 |
| `afterStartModule` | 在初始化模塊之后,僅在注冊模塊時 |
| `beforeHandleRequest` | 在執行調度循環之前 |
| `afterHandleRequest` | 在執行調度循環之后 |
以下示例演示如何將偵聽器附加到此組件:
```php
<?php
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
$eventsManager = new EventsManager();
$application->setEventsManager($eventsManager);
$eventsManager->attach(
'application',
function (Event $event, $application) {
// ...
}
);
```
## 外部資源
* [MVC examples on Github](https://github.com/phalcon/mvc)
- 常規
- Welcome
- 貢獻
- 生成回溯
- 測試重現
- 單元測試
- 入門
- 安裝
- Web服務器設置
- WAMP
- XAMPP
- 教程
- 基礎教程
- 教程:創建一個簡單的REST API
- 教程:V?kuró
- 提升性能
- 教程:INVO
- 開發環境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 開發工具
- Phalcon開發者工具的安裝
- Phalcon開發者工具的使用
- 調試應用程序
- 核心
- MVC應用
- 微應用
- 創建命令行(CLI)應用程序
- 依賴注入與服務定位
- MVC架構
- 服務
- 使用緩存提高性能
- 讀取配置
- 上下文轉義
- 類加載器
- 使用命名空間
- 日志
- 隊列
- 數據庫
- 數據庫抽象層
- Phalcon查詢語言(PHQL)
- ODM(對象文檔映射器)
- 使用模型
- 模型行為
- ORM緩存
- 模型事件
- 模型元數據
- 模型關系
- 模型事務
- 驗證模型
- 數據庫遷移
- 分頁
- 前端
- Assets管理
- 閃存消息
- 表單
- 圖像
- 視圖助手(標簽)
- 使用視圖
- Volt:模板引擎
- 業務邏輯
- 訪問控制列表(ACL)
- 注解解析器
- 控制器
- 調度控制器
- 事件管理器
- 過濾與清理
- 路由
- 在session中存儲數據
- 生成URL和路徑
- 驗證
- HTTP
- Cookies管理
- 請求環境
- 返回響應
- 安全
- 加密/解密
- 安全
- 國際化
- 國際化
- 多語言支持