SearchTable Of ContentsPrevious topicNext topicThis Page |
控制器¶控制器提供了一些方法,他们被叫做actions。Actions是控制器用来处理用户请求的方法。默认情况下,控制器的所有公有的方法都映射到一个可访问的URL。Actions是负责解释请求以及创建用户响应的。通过的反应是一个渲染视图的形式,但也有其他的形式来处理用户请求。 例如,当你访问一个这样的URL时 http://localhost/blog/posts/show/2012/the-post-title ,默认情况下,Phalcon是这样对URL进行分解的:
在这个例子中,PostController控制器用于来接收用户请求。由于在应用程序中没有对controllers的存放指定存放位置,他们可以通过 autoloaders 来自动加载你的controllers目录。 所有的控制器都必须以“Controller”为结尾,所有的Actions都是以“Action”结尾。下面是一个控制器的示例: 译者注:也并非所有的控制器都必须以“Controller”为结尾的,比如我们一般会写一个名为 “ContollerBase”,让他继承自 PhalconMvcController. 同时我们自己应用程序中的其他控制器都再继承自 ContollerBase.这么来做的话,则控制器ContollerBase就不是以 “Controller”为结尾了。如果严谨一点来讲可以这么说,所以用于用户请求的控制器必须以“Controller”为结尾 <?php
class PostsController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
}
}
其他的URI参数将被定义为Action参数,因此你可以很容易的使用局部变量来访问这些参数。控制器继承自 Phalcon\Mvc\Controller 。 这样一来,你的控制器就很方便的提供应用服务了 Dispatch Loop¶其他的URI参数将被定义为Action参数,因此你可以很容易的使用局部变量来访问这些参数。控制器继承自 Phalcon\Mvc\Controller 。 这样一来,你的控制器就很方便的访问应用程序中的其他服务了 <?php
class PostsController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
$this->flash->error("You don't have permission to access this area");
// Forward flow to another action
$this->dispatcher->forward(array(
"controller" => "users",
"action" => "signin"
));
}
}
如果用户没有权限访问某个特定的动作,然后将被转发到UsersController控制器的signinAction <?php
class UsersController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function signinAction()
{
}
}
应用程序中并没有限制分发器的跳转次数,只要他们不导致死循环,可以正常停止即可。如果程序逻辑中再没有跳转到其他的Action,程序将自动调用MVC的视图层 Phalcon\Mvc\View. 初始化控制器¶Phalcon\Mvc\Controller 提供初始化的方法,它最先执行,注意:”__construct” 的初始化方法在这里不推荐使用。 <?php
class PostsController extends \Phalcon\Mvc\Controller
{
public $settings;
public function initialize()
{
$this->settings = array(
"mySetting" => "value"
);
}
public function saveAction()
{
if ($this->settings["mySetting"] == "value") {
//...
}
}
}
访问注入服务¶如果控制器继承自 Phalcon\Mvc\Controller ,那么它将可以很方便的访问应用程序容器中的其他服务。例如,我们注册了一个这样的服务: <?php
$di = new Phalcon\DI();
$di->set('storage', function(){
return new Storage('/some/directory');
}, true);
然后,我们可以通过以下方式访问那些服务: <?php
class FilesController extends \Phalcon\Mvc\Controller
{
public function saveAction()
{
//Injecting the service by just accessing the property with the same name
$this->storage->save('/some/file');
//Accessing the service from the DI
$this->di->get('storage')->save('/some/file');
//Another way to access the service using the magic getter
$this->di->getStorage()->save('/some/file');
//Another way to access the service using the magic getter
$this->getDi()->getStorage()->save('/some/file');
}
}
如果你正在使用Phalcon框架,你可以阅读一下DI by default 请求和响应¶假设,该框架已经提供了一组预置的服务。我们将解释他们如何与http相互协调工作。”request”服务是 Phalcon\Http\Request 的一个实例对象, “response”是 Phalcon\Http\Response 的一个实例对象,它负责向客户端发送响应内容。 <?php
class PostsController extends Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function saveAction()
{
// Check if request has made with POST
if ($this->request->isPost() == true) {
// Access POST data
$customerName = $this->request->getPost("name");
$customerBorn = $this->request->getPost("born");
}
}
}
The response object is not usually used directly, but is built up before the execution of the action, sometimes - like in an afterDispatch event - it can be useful to access the response directly: <?php
class PostsController extends Phalcon\Mvc\Controller
{
public function indexAction()
{
}
public function notFoundAction()
{
// Send a HTTP 404 response header
$this->response->setStatusCode(404, "Not Found");
}
}
Session 数据¶Sessions help us maintain persistent data between requests. You could access a Phalcon\Session\Bag from any controller to encapsulate data that need to be persistent. <?php
class UserController extends Phalcon\Mvc\Controller
{
public function indexAction()
{
$this->persistent->name = "Michael";
}
public function welcomeAction()
{
echo "Welcome, ", $this->persistent->name;
}
}
注入服务替代控制器¶控制器可以注册成为服务,这样的话,用户的请求都会从注册的控制器获得。因此,用此种办法可以很容易的取代其他控制器。 <?php
//Register a controller as a service
$di->set('IndexController', function() {
$component = new Component();
return $component;
});
译者注: 以上例来说明,如果要访问 /index/index 的话,则需要在类 Component 中编写 indexAction() 方法。即和控制器中的action写法是相同的。同时,即使控制器目录存在 IndexController,也将不再访问。而是直接输出 Component中indexAction()的内容 创建一个基础控制器类¶在应用程序的控制器中经常会需要访问控制列表,多语言,缓存,模板引擎等。在这种情况下,我们一般建议你创建一个 “base controller”,以防重复造轮子,保持代码 DRY .控制器只是一个简单的类文件,他要继承自 Phalcon\Mvc\Controller ,其他的控制器再继承自 “base controller”,这样就可以拥有基类控制器中的通用功能了,你的代码就会更整洁一些。 这个类可以放到任何目录下,但按照一般的规则来讲,我们推荐你把它放到控制器文件夹中,比如 apps/controllers/ControllerBase.php 。我们可能会需要这个文件,你可以直接在程序中引入,或者通过Phalcon的autoloader引入: <?php
require "../app/controllers/ControllerBase.php";
一般通用的功能组件,我们可以写到这个文件中,比如 (actions,methods, properties等): <?php
class ControllerBase extends \Phalcon\Mvc\Controller
{
/**
* This action is available for multiple controllers
*/
public function someAction()
{
}
}
其他继承自ControllerBase的控制器,会自动获得通用组件。 译者注: 只要明白类继承是怎么回事,这块就非常好理解了。 <?php
class UsersController extends ControllerBase
{
}
译者补充: 我在这里多加一个例子,你就可以很容易的明白 base controller的用处了。 比如,我们一般会在控制器中做跳转操作,一般会用到 dispatcher的 forward方法。但这个forward方法的参数是一个数组,需要这样写: <?php
class UsersController extends ControllerBase
{
public function authAction()
{
..... //valiate code
$this->dispatcher->forward(array(
'controller' => 'users',
'action' => 'login'
)
);
}
}
以上面示例中的写法来说,会有些麻烦。那么我们需要在 base controller中加入一个自定义的 forward 方法。 <?php
class ControllerBase extends \Phalcon\Mvc\Controller
{
protected function forward($uri){
$uriParts = explode('/', $uri);
return $this->dispatcher->forward(
array(
'controller' => $uriParts[0],
'action' => $uriParts[1]
)
);
}
}
再次来修改 UsersController中的authAction方法: <?php
class UsersController extends ControllerBase
{
public function authAction()
{
..... //valiate code
$this->forward('users/login');
}
}
是不是非常方便了? 控制器中的事件¶控制器本身也可以充当监听的身份,通过 dispatcher 事件,在控制器中实现 dispatcher的事件方法,控制器的方法名要与事件名相同。这样的话,你就可以很方便的在actions执行前后通过钩点执行其他内容: <?php
class PostsController extends \Phalcon\Mvc\Controller
{
public function beforeExecuteRoute($dispatcher)
{
// This is executed before every found action
if ($dispatcher->getActionName() == 'save') {
$this->flash->error("You don't have permission to save posts");
return false;
}
}
public function afterExecuteRoute($dispatcher)
{
// Executed after every found action
}
}
|