Php 在Phalcon控制器中处理视图

Php 在Phalcon控制器中处理视图,php,model-view-controller,phalcon,Php,Model View Controller,Phalcon,我正在做一个新创建的Phalcon项目,我真的不知道如何实际使用多重视图 什么是切入点?我真的不知道什么时候调用控制器中的每个方法,在什么条件下,等等 控制流在哪里定义?它是否基于视图的名称?或者您可以在哪里注册它们?应用程序从路由阶段开始。从那里,您从路由器抓取控制器和操作,并将其提供给调度程序。设置视图,然后调用execute调度程序,以便它访问控制器的操作。从那里创建一个新的响应对象,并将其内容设置为与视图请求相等,最后将响应发送到客户端的浏览器——内容和标题。最好通过Phalcon执行此

我正在做一个新创建的Phalcon项目,我真的不知道如何实际使用多重视图

什么是切入点?我真的不知道什么时候调用控制器中的每个方法,在什么条件下,等等


控制流在哪里定义?它是否基于视图的名称?或者您可以在哪里注册它们?

应用程序从路由阶段开始。从那里,您从路由器抓取控制器和操作,并将其提供给调度程序。设置视图,然后调用execute调度程序,以便它访问控制器的操作。从那里创建一个新的响应对象,并将其内容设置为与视图请求相等,最后将响应发送到客户端的浏览器——内容和标题。最好通过Phalcon执行此操作,而不是直接回显或使用PHP的header(),因此只能在调用
$response->send()时执行此操作这是最佳实践,因为它允许您创建测试,例如在phpunit中,这样您就可以测试头或内容的存在,同时转到下一个响应和头,而不实际发送任何内容,这样您就可以测试内容了。与
退出相同的想法,这样您就可以编写测试并继续进行下一个测试,而不会因为存在exit而在第一个测试中中止测试

至于Phalcon应用程序如何工作以及在哪些步骤中,通过查看手动引导,更容易遵循流程:

Phalcon的核心是依赖注入容器DI。这允许您创建服务,并将它们存储在DI上,以便服务可以相互访问。您可以创建自己的服务,并将它们以自己的名称存储在DI上,使用的名称没有什么特别之处。但是,根据您使用的Phalcon的区域,DI上的某些服务被假定为“db”,用于与您的数据库交互。注意:服务可以在DI上设置为共享或不共享。共享意味着它实现了单例,并在以后的所有调用中保持对象的活动状态。如果使用getShared,即使它最初不是一个共享服务,它也会做类似的事情。getShared方法被认为是不好的做法,Phalcon团队正在讨论在未来的Phalcon版本中删除该方法。请改用setShared

对于多个视图,可以从
$this->view->disable()开始来自控制器内。这允许您禁用视图,这样就不会从控制器中生成任何内容,从而可以了解视图在控制器中的工作方式

Phalcon假设每个控制器在
/someController/someView
下都有一个匹配的视图,然后是您在视图上注册的任何扩展名,默认为
.volt
,但也可以设置为使用
.phtml
.php

这两者对应于:
Phalcon\Mvc\View\Engine\Php
Phalcon\Mvc\View\Engine\Volt

请注意,在查找要渲染的模板时,没有指定扩展名,Phalcon会为您添加此扩展名

Phalcon还将根视图模板
index.volt
(如果存在)用于与视图的所有交互,因此您可以对所有响应使用相同的doctype之类的内容,使您的生活更轻松

Phalcon还为您提供了分部,因此您可以在视图中呈现分部,如面包屑,或页眉或页脚,否则您将复制粘贴到每个模板中。这允许您管理来自同一模板的所有页面,这样您就不会重复自己

至于在Phalcon中使用哪个视图类,有两个主要选择:
Phalcon\Mvc\View
Phalcon\Mvc\View\Simple

与此类似,
Phalcon\Mvc\View
为您提供了一个如前所述的多级层次结构,包括一个主模板、一个基于控制器操作的模板以及一些其他奇特的功能。至于
Phalcon\Mvc\View\Simple
,它更加轻量级,是一个单一级别

您应该熟悉分层渲染:

这个想法是通过
Phalcon\Mvc\View
你有一个主布局(如果这个模板存在的话)通常存储在
/views/index.volt
中,它被用在每一页上,这样你就可以输入你的文档类型、标题(你可以用视图传入的变量设置)等等。你就有一个控制器布局,它将存储在
/views/layouts.myController.volt
下,并用于控制器内的每个操作(如果此模板存在),最后您将拥有用于
/views/myController/myAction.volt
中控制器特定操作的操作布局

有各种各样的方法可以打破Phalcon的默认行为。您可以执行前面所述的
$this->view->disable()这样您就可以自己手动完成所有操作,这样Phalcon就不会对视图模板进行任何假设。您还可以使用
->pick
来选择要使用的模板,前提是该模板与运行该模板的控制器和操作不同

您还可以从控制器中返回响应对象,Phalcon不会尝试呈现模板,而是使用响应对象

例如,您可能希望执行以下操作:

return $this->response->redirect('index/index');
这会将用户的浏览器重定向到所述页面。您也可以执行
转发
,这将在Phalcon内部使用,以访问不同的控制器和/或操作

您可以配置存储视图的目录
setViewsDir
。您还可以在控制器本身中执行此操作,甚至可以在视图中执行此操作,只要您愿意,如果由于目录结构错误而出现一些异常情况

您可以使用
$this->view->setTemplateBefore('common'
use Phalcon\Di\FactoryDefault;

// initializes the dependency injector of Phalcon framework
$injector = new FactoryDefault();

// defines the routes
$injector->setShared('router', function () {
    return require_once('some/path/routes.php');
});
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Router\Group as RouterGroup;

// instantiates the router
$router = new Router(false);
// defines routes for the 'users' controller
$user_routes = new RouterGroup(['controller' => 'users']);
$user_routes->setPrefix('/users');
$user_routes->addGet('/show/{id:[0-9]{1,9}}', ['action' => 'show']);
$router->mount($user_routes);
return $router;
public function showAction(int $id) {
    // ... do all you need to do...

    // fetch data
    $user = UserModel::findFirst(blah blah);

    // pass data to view
    $this->view->setVar('user', $user);

    // Phalcon automatically calls the view; from the manual:
    /*
    Phalcon automatically passes the execution to the view component as soon as a particular
    controller has completed its cycle. The view component will look in the views folder for
    a folder named as the same name of the last controller executed and then for a file named
    as the last action executed.
    */

    // but in case you would need to specify a different one
    $this->view->render('users', 'another_view');
}
use Phalcon\Loader;
// registers namespaces and other classes
$loader = new Loader();
$loader->registerNamespaces([
    'MyNameSpace\Controllers' => 'path/controllers/',
    'MyNameSpace\Models' => 'path/models/',
    'MyNameSpace\Views' => 'path/views/'
]);
$loader->register();
use Phalcon\Mvc\View;

$injector->setShared('view', function () {
    $view = new View();
    $view->setViewsDir('path/views/');
    return $view;
});