# MVC 应用(MVC Applications)
在Phalcon,策划MVC操作背后的全部困难工作通常都可以 通过[Phalcon\\Mvc\\Application](http://docs.iphalcon.cn/api/Phalcon_Mvc_Application.html)做到。这个组件封装了全部后端所需要的复杂 操作,实例化每一个需要用到的组件并与项目整合在一起,从而使得MVC模式可以如期地运行。
## 单模块或多模块应用(Single or Multi Module Applications)
通过这个组件,你可以运行各式各样的MVC结构:
### 单模块(Single Module)
单一的MVC应用仅仅包含了一个模块。可以使用命名空间,但不是必需的。 这样类型的应用可能会有以下文件目录结构:
~~~
single/
app/
controllers/
models/
views/
public/
css/
img/
js/
~~~
如果未使用命名空间,以下的启动文件可用于编排MVC工作流:
~~~
<?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();
}
~~~
如果使用了命名空间,则可以使用以下启动文件(译者注:主要区别在于使用$loader的方式):
~~~
<?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();
}
~~~
### 多模块(Multi Module)
多模块的应用使用了相同的文档根目录但拥有多个模块。在这种情况下,可以使用以下的文件目录结构:
~~~
multiple/
apps/
frontend/
controllers/
models/
views/
Module.php
backend/
controllers/
models/
views/
Module.php
public/
css/
img/
js/
~~~
在apps/下的每一个目录都有自己的MVC结构。Module.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)
{
// Registering a dispatcher
$di->set(
"dispatcher",
function () {
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace("Multiple\\Backend\\Controllers");
return $dispatcher;
}
);
// Registering the view component
$di->set(
"view",
function () {
$view = new View();
$view->setViewsDir("../apps/backend/views/");
return $view;
}
);
}
}
~~~
还需要一个指定的启动文件来加载多模块的MVC架构:
~~~
<?php
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
$di = new FactoryDefault();
// 自定义路由
// More information how to set the router up https://docs.phalconphp.com/zh/latest/reference/routing.html
$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",
]
]
);
// 处理请求
$response = $application->handle();
$response->send();
} catch (\Exception $e) {
echo $e->getMessage();
}
~~~
如果你想在启动文件保持模块的配置,你可以使用匿名函数来注册对应的模块:
~~~
<?php
use Phalcon\Mvc\View;
// 创建视图组件
$view = new View();
// 设置视图组件相关选项
// ...
// Register the installed modules
$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](http://docs.iphalcon.cn/api/Phalcon_Mvc_Application.html)有多个模块注册时,通常 每个都是需要的,以便每一个被匹配到的路由都能返回一个有效的模块。每个已经注册的模块都有一个相关的类来提供建立和启动自身的函数。 而每个模块定义的类都必须实现registerAutoloaders()和registerServices()这两个方法,这两个函数会在模块即被执行时被[Phalcon\\Mvc\\Application](http://docs.iphalcon.cn/api/Phalcon_Mvc_Application.html)调用。
## 应用事件(Application Events)
[Phalcon\\Mvc\\Application](http://docs.iphalcon.cn/api/Phalcon_Mvc_Application.html)可以把事件发送到[EventsManager](http://docs.iphalcon.cn/reference/events.html)(如果它激活的话)。 事件将被当作”application”类型被消费掉。目前已支持的事件如下:
| 事件名称 | 消费于 |
| --- | --- |
| boot | 当应用处理它首个请求时被执行 |
| beforeStartModule | 在初始化模块之前,仅当模块被注册时 |
| afterStartModule | 在初始化模块之后,仅当模块被注册时 |
| beforeHandleRequest | 在执行分发环前 |
| afterHandleRequest | 在执行分发环后 |
以下示例演示了如何将侦听器绑定到组件:
~~~
<?php
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
$eventsManager = new EventsManager();
$application->setEventsManager($eventsManager);
$eventsManager->attach(
"application",
function (Event $event, $application) {
// ...
}
);
~~~
## 外部资源(External Resources)
* [Github上的MVC示例](https://github.com/phalcon/mvc)
- 简介
- 安装
- 安装(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