应用程序¶
概览¶
The Phalcon\Mvc\Application
该组件封装了运行MVC应用程序所需的操作。它集成了所有必要的组件和服务,提供了全栈应用程序体验。
快速开始¶
要快速开始使用Phalcon\Mvc\Application
,您可以使用以下代码片段:
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Application;
// Create a DI container
$container = new FactoryDefault();
// Create an application instance
$application = new Application($container);
try {
// Handle the request and send the response
$response = $application->handle($_SERVER["REQUEST_URI"]);
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
注意
handle()
接受一个URI,并且没有URI将无法运行。你可以通过参数传递$_SERVER["REQUEST_URI"]
作为参数
方法¶
构造函数。接受包含相关服务的DI容器 返回默认的模块名称 返回内部事件管理器 通过模块名称获取在应用程序中注册的模块定义 返回在应用程序中注册的模块 注册应用程序中存在的模块数组$this->registerModules(
[
"front" => [
"className" => \Multi\Front\Module::class,
"path" => "../apps/front/Module.php",
],
"back" => [
"className" => \Multi\Back\Module::class,
"path" => "../apps/back/Module.php",
],
]
);
$_SERVER['REQUEST_URI
]`) 启用或禁用每次请求处理时发送cookies 启用或禁用每次请求处理时发送头信息 此功能默认启用。视图会隐式缓冲所有输出。可以使用此方法完全禁用视图组件 激活¶
Phalcon\Mvc\Application该方法执行所有必需的工作来整合所有必要组件,使应用程序能够运行。可以通过多种方式引导启动您的应用程序。最常见的方法如下:
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Application;
$container = new FactoryDefault();
// Services
// ...
// Create an application instance
$application = new Application($container);
try {
// Handle the request and send the response
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
控制器核心工作的发生是在handle()
被调用时:
手动引导启动¶
如果您不想使用Phalcon\Mvc\Application,可以根据您的应用程序需求手动处理引导启动过程。以下是几种替代的手动引导启动方法:
标准Web应用程序¶
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Application;
$container = new FactoryDefault();
// Get the 'router' service
$router = $container['router'];
// Handle the request
$router->handle(
$_SERVER["REQUEST_URI"]
);
// Get the 'view' service
$view = $container['view'];
// Get the 'dispatcher' service
$dispatcher = $container['dispatcher'];
// Set controller, action, and params based on router
$dispatcher->setControllerName(
$router->getControllerName()
);
$dispatcher->setActionName(
$router->getActionName()
);
$dispatcher->setParams(
$router->getParams()
);
// Start buffering the view output
$view->start();
// Dispatch the request
$dispatcher->dispatch();
// Render the view with controller, action, and params
$view->render(
$dispatcher->getControllerName(),
$dispatcher->getActionName(),
$dispatcher->getParams()
);
// Finish buffering the view output
$view->finish();
// Get the 'response' service
$response = $container['response'];
// Set the response content from the view output
$response->setContent(
$view->getContent()
);
// Send the response
$response->send();
REST API¶
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Http\ResponseInterface;
use Phalcon\Mvc\Application;
$container = new FactoryDefault();
// Get the 'router' service
$router = $container['router'];
// Handle the request
$router->handle(
$_SERVER["REQUEST_URI"]
);
// Get the 'dispatcher' service
$dispatcher = $container['dispatcher'];
// Set controller, action, and params based on router
$dispatcher->setControllerName(
$router->getControllerName()
);
$dispatcher->setActionName(
$router->getActionName()
);
$dispatcher->setParams(
$router->getParams()
);
// Dispatch the request
$dispatcher->dispatch();
// Get the returned value from the dispatcher
$response = $dispatcher->getReturnedValue();
// If the response is an instance of ResponseInterface, send it
if ($response instanceof ResponseInterface) {
$response->send();
}
捕获异常¶
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Http\ResponseInterface;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\Dispatcher\Exception as DispatcherException;
$container = new FactoryDefault();
// Get the 'router' service
$router = $container['router'];
// Handle the request
$router->handle(
$_SERVER["REQUEST_URI"]
);
// Get the 'dispatcher' service
$dispatcher = $container['dispatcher'];
// Set controller, action, and params based on router
$dispatcher->setControllerName(
$router->getControllerName()
);
$dispatcher->setActionName(
$router->getActionName()
);
$dispatcher->setParams(
$router->getParams()
);
try {
// Dispatch the request
$dispatcher->dispatch();
} catch (DispatcherException $e) {
// Handle exceptions, for example,
// forward to a 503 error page
$dispatcher->setControllerName('errors');
$dispatcher->setActionName('action503');
$dispatcher->dispatch();
}
// Get the returned value from the dispatcher
$response = $dispatcher->getReturnedValue();
// If the response is an instance of
// `ResponseInterface`, send it
if ($response instanceof ResponseInterface) {
$response->send();
}
选择最适合您应用程序需求的选项。根据您的要求,您可以完全控制实例化和组件替换以扩展默认功能。手动引导启动方法应与您的具体使用场景相匹配。
单模块 - 多模块¶
Phalcon\Mvc\Application
支持单模块和多模块MVC结构。
单模块¶
在单模块MVC应用程序中,只有一个模块。命名空间是可选的。其结构通常如下所示:
如果未使用命名空间,引导文件可能如下所示:<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Autoload\Loader;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\View;
$loader = new Loader();
$loader->setDirectories(
[
'../apps/controllers/',
'../apps/models/',
]
);
$loader->register();
$container = new FactoryDefault();
$container->set(
'view',
function () {
$view = new View();
$view->setViewsDir('../apps/views/');
return $view;
}
);
$application = new Application($container);
try {
// Handle the request and send the response
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Autoload\Loader;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\View;
$loader = new Loader();
$loader->setNamespaces(
[
'Single\Controllers' => '../apps/controllers/',
'Single\Models' => '../apps/models/',
]
);
$loader->register();
$container = new FactoryDefault();
$container->set('dispatcher', function () {
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace('Single\Controllers');
return $dispatcher;
});
$container->set('view', function () {
$view = new View();
$view->setViewsDir('../apps/views/');
return $view;
});
$application = new Application($container);
try {
// Handle the request and send the response
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
} catch (\Exception $e) {
echo 'Exception: ', $e->getMessage();
}
多模块¶
多模块应用程序在一个共享文档根目录下使用多个模块。模块有助于组织组件、增强可维护性并隔离功能。每个模块必须实现Phalcon\Mvc\ModuleDefinitionInterface以确保正常的功能。目录结构通常包括在apps/
目录中的子目录,其中每个子目录都有自己的MVC结构。此外,每个模块目录包含一个Module.php
文件用于配置模块特定的设置,如自动加载器和自定义服务。
目录结构
multiple/
apps/
front/
controllers/
models/
views/
Module.php
back/
controllers/
models/
views/
Module.php
public/
css/
img/
js/
Module.php
文件负责注册特定模块的自动加载器和服务。以下是一个示例Module.php
文件针对Multi\Back
模块: <?php
namespace Multi\Back;
use Phalcon\Autoload\Loader;
use Phalcon\Di\DiInterface;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\ModuleDefinitionInterface;
use Phalcon\Mvc\View;
class Module implements ModuleDefinitionInterface
{
public function registerAutoloaders(DiInterface $container = null)
{
$loader = new Loader();
$loader->setNamespaces(
[
'Multi\Back\Controllers' => '../apps/back/controllers/',
'Multi\Back\Models' => '../apps/back/models/',
]
);
$loader->register();
}
public function registerServices(DiInterface $container)
{
// Dispatcher
$container->set(
'dispatcher',
function () {
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace(
'Multi\Back\Controllers'
);
return $dispatcher;
}
);
// View
$container->set(
'view',
function () {
$view = new View();
$view->setViewsDir(
'../apps/back/views/'
);
return $view;
}
);
}
}
多模块架构的引导文件对于多模块MVC架构,引导文件需要进行稍微修改的设置。路由器需要显式配置,并向应用程序注册模块。以下是一个示例的引导文件:
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\Router;
$container = new FactoryDefault();
$container->set(
'router',
function () {
$router = new Router();
$router->setDefaultModule('front');
$router->add(
'/login',
[
'module' => 'back',
'controller' => 'login',
'action' => 'index',
]
);
$router->add(
'/admin/products/:action',
[
'module' => 'back',
'controller' => 'products',
'action' => 1,
]
);
$router->add(
'/products/:action',
[
'controller' => 'products',
'action' => 1,
]
);
return $router;
}
);
$application = new Application($container);
$application->registerModules(
[
'front' => [
'className' => \Multi\Front\Module::class,
'path' => '../apps/front/Module.php',
],
'back' => [
'className' => \Multi\Back\Module::class,
'path' => '../apps/back/Module.php',
]
]
);
try {
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
} catch (\Exception $e) {
echo $e->getMessage();
}
<?php
use Phalcon\Mvc\View;
$view = new View();
// ...
$application->registerModules(
[
'front' => function ($container) use ($view) {
$container->setShared(
'view',
function () use ($view) {
$view->setViewsDir(
'../apps/front/views/'
);
return $view;
}
);
},
'back' => function ($container) use ($view) {
$container->setShared(
'view',
function () use ($view) {
$view->setViewsDir(
'../apps/back/views/'
);
return $view;
}
);
}
]
);
模块定义类必须实现两个方法:registerAutoloaders()
和registerServices()
。这些方法将由Phalcon\Mvc\Application相应地调用。
异常¶
在Phalcon\Mvc\Application组件中抛出的任何异常类型为Phalcon\Mvc\Application\Exception或Phalcon\Application\Exception。你可以使用此异常选择性地捕获仅从此组件抛出的异常。
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\Application\Exception;
try {
$container = new FactoryDefault();
// ...
$application = new Application($container);
$application->registerModules(
[
'front' => false,
]
);
$response = $application->handle(
$_SERVER["REQUEST_URI"]
);
$response->send();
} catch (Exception $e) {
echo $e->getMessage();
}
事件¶
Phalcon\Mvc\Application可以向EventsManager发送事件(如果存在的话)。事件使用application类型触发。支持的事件包括:
事件名称 | 触发时机 |
---|---|
boot | 当应用程序处理第一个请求时执行 |
beforeStartModule | 在初始化模块之前触发,仅当注册了模块时 |
afterStartModule | 在初始化模块之后触发,仅当注册了模块时 |
beforeHandleRequest | 在执行分发循环之前触发 |
afterHandleRequest | 在执行分发循环之后触发 |
以下是如何附加监听器到该组件的示例:
<?php
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
$manager = new Manager();
$application->setEventsManager($manager);
$manager->attach(
'application',
function (Event $event, $application) {
// ...
}
);