使用控制器(Using Controllers) =============================== 控制器提供了一堆可以被调用的方法,即:action。action是控制器中用于处理请求的方法。默认情况下,全部 控制器public的方法都会映射到action并且可以通过URL访问。action负责解释请求和创建响应。 通常,响应是以渲染的视图格式被创建,但也存在其他的方式来创建(译者注:如AJAX请求返回JSON格式的数据)。 例如,当你访问一个类似这样的URL时:http://localhost/blog/posts/show/2015/the-post-title,Phalcon默认会这样分解各个部分: +-----------------+----------------+ | **Phalcon目录** | blog | +-----------------+----------------+ | **控制器** | posts | +-----------------+----------------+ | **Action** | show | +-----------------+----------------+ | **参数** | 2015 | +-----------------+----------------+ | **参数** | the-post-title | +-----------------+----------------+ 这时,PostsController将会处理这个请求。在一个项目中,没有强制指定放置控制器的地方,这些控制器都可以 通过使用 :doc:`autoloaders ` 来加载,所以你可以根据需要自由组件你的控制器。 控制器类必须以“Controller”为后缀,action则须以“Action”为后缀。一个控制器类的例子如下: .. code-block:: php ` 。如果继承此基类,你的控制器类则能 轻松访问应用的各种服务。 没有默认缺省值的参数视为必须参数处理。可以像PHP那样为参数设定一个默认值: .. code-block:: php dispatcher->getParam('year'); $postTitle = $this->dispatcher->getParam('postTitle'); } } 循环调度(Dispatch Loop) ------------------------- 循环调度将会在分发器执行,直到没有action需要执行为止。在上面的例子中,只有一个action 被执行到。现在让我们来看下“forward”(转发)怎样才能在循环调度里提供一个更加复杂的操作流,从而将执行转发到 另一个controller/action。 .. code-block:: php flash->error("You don't have permission to access this area"); // Forward flow to another action $this->dispatcher->forward( array( "controller" => "users", "action" => "signin" ) ); } } 如果用户没有访问某个action的权限,那么请求将会被转发到Users控制器的signin行为。 .. code-block:: php ` 管理的MVC的视图层。 初始化控制器(Initializing Controllers) ---------------------------------------- :doc:`Phalcon\\Mvc\\Controller <../api/Phalcon_Mvc_Controller>` 提供了初始化的函数,它会最先执行,并优于任何控制器 的其他action。不推荐使用“__construct"方法。 .. code-block:: php settings = array( "mySetting" => "value" ); } public function saveAction() { if ($this->settings["mySetting"] == "value") { // ... } } } .. highlights:: “initialize”仅仅会在事件“beforeExecuteRoute”成功执行后才会被调用。这样可以避免 在初始化中的应用逻辑不会在未验证的情况下执行不了。 如果你想在紧接着创建控制器对象的后面执行一些初始化的逻辑,你要实现“onConstruct”方法: .. code-block:: php ` ,那么它可以轻松访问 应用的服务容器。例如,如果我们类似这样注册了一个服务: .. code-block:: php set('storage', function () { return new Storage('/some/directory'); }, true); 那么,我们可以通常多种方式来访问这个服务: .. code-block:: php storage->save('/some/file'); // 通过DI访问服务 $this->di->get('storage')->save('/some/file'); // 另一种方式:使用魔法getter来访问 $this->di->getStorage()->save('/some/file'); // 另一种方式:使用魔法getter来访问 $this->getDi()->getStorage()->save('/some/file'); // 使用数组下标 $this->di['storage']->save('/some/file'); } } 如果你是把Phalcon作为全能(Full-Stack)框架来使用,你可以阅读框架中 :doc:`by default ` 提供的服务。 请求与响应(Request and Response) ---------------------------------- 假设框架预先提供了一系列的注册的服务。我们这里将解释如何和HTTP环境进行关联和交互。 “request”服务包含了一个 :doc:`Phalcon\\Http\\Request <../api/Phalcon_Http_Request>` 的实例, “response”服务则包含了一个 :doc:`Phalcon\\Http\\Response <../api/Phalcon_Http_Response>` 的实例,用来表示将要返回给客户端的内容。 .. code-block:: php request->isPost() == true) { // 获取POST数据 $customerName = $this->request->getPost("name"); $customerBorn = $this->request->getPost("born"); } } } 响应对象通常不会直接使用,但在action的执行前会被创建,有时候 - 如在 一个afterDispatch事件中 - 它对于直接访问响应非常有帮助: .. code-block:: php response->setStatusCode(404, "Not Found"); } } 如需学习了解HTTP环境更多内容,请查看专题: :doc:`request ` 和 :doc:`response ` 。 会话数据(Session Data) ------------------------ 会话可以帮助我们在多个请求中保持久化的数据。你可以从任何控制器中访问 :doc:`Phalcon\\Session\\Bag <../api/Phalcon_Session_Bag>` 以便封装需要进行持久化的数据。 .. code-block:: php persistent->name = "Michael"; } public function welcomeAction() { echo "Welcome, ", $this->persistent->name; } } 在控制器中使用服务(Using Services as Controllers) --------------------------------------------------- 服务可以是控制器,控制器类通常会从服务容器中请求。据于此, 任何一个用其名字注册的类都可以轻易地用一个控制器来替换: .. code-block:: php set('IndexController', function () { $component = new Component(); return $component; }); // 将一个命名空间下的控制器作为服务进行注册 $di->set('Backend\Controllers\IndexController', function () { $component = new Component(); return $component; }); 创建基控制器(Creating a Base Controller) ------------------------------------------ 对于某些应用特性如访问控制列表(ACL),翻译,缓存,和模板引擎一般对于 控制器都是通用的。在这种情况下,我们鼓励创建一个 “基控制器”,从而确保你的代码遵循 DRY_ 。 基控制器可以是一个简单的类,然后继承于 :doc:`Phalcon\\Mvc\\Controller <../api/Phalcon_Mvc_Controller>` ,并封装 全部控制器都有的通用功能操作。反过来,你的控制器则继承这个“基控制器”以便可以直接使用通用功能操作。 这个基类可以放置在任何一个地方,但出于代码组织的便利我们推荐应该放置在控制器的目录下, 如:apps/controllers/ControllerBase.php。我们可以在启动文件直接require这个文件,也可以使用自动加载: .. code-block:: php ` 事件的侦听者,使用这些事件并实现实现这些方法后, 你便可以实现对应被执行的action的before/after钩子函数: .. code-block:: php getActionName() == 'save') { $this->flash->error("You don't have permission to save posts"); $this->dispatcher->forward( array( 'controller' => 'home', 'action' => 'index' ) ); return false; } } public function afterExecuteRoute($dispatcher) { // 在找到的action后执行 } } .. _DRY: https://zh.wikipedia.org/wiki/%E4%B8%80%E6%AC%A1%E4%B8%94%E4%BB%85%E4%B8%80%E6%AC%A1