应用程序¶
概览¶
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) {
        // ...
    }
);