ZF2.0用户向导 —— 5. 路由及控制器

路由及控制器

 

我们将会建立一个展示我们收集的唱片封面的系统。主页将会列出我们的唱片及添加、编辑、删除封面的链接。下面的页面是我们必须的:

 

页面

描述

唱片列表

此页面展示唱片列表,并且有着编辑、删除及添加页面的链接

添加新的唱片封面

提供一个添加表单

编辑一个唱片封面

提供编辑功能

删除

可以删除某个唱片封面

 

在我们创建文件之前,对于理解框架是如何组织页面的是非常重要的。应用的每个页面在模块的控制器中是按照操作(action)分组的。所以你一般会将有关联的操作放到同一个控制器中。例如,一个新闻控制器可能包括 current、archived及view等操作。

 

所以我们在 albums 有四个页面,我们将这些操作集中到 Album 模块的一个控制器中——AlbumController。四个操作如下:

 

Page

Controller

Action

Home

AlbumController

index

Add new Album

AlbumController

add

Edit album

AlbumController

edit

Delete album

AlbumController

delete

 

The mapping of a URL to a particular action is done using routes that are defined in the module’s module.config.php file. We will add a route for our album actions. This is the updated module config file with the new code highlighted.

 

使用定义在模块里面的 module.config.php 文件里的路由可以使得URL映射到某个特定的action。我们将为我们的封面操作定义一个路由。下面的模块配置文件是更新过的(红色部分是新添加的)。

 

// module/Album/config/module.config.php:

return array(

    'controllers' => array(

        'invokables' => array(

            'Album\Controller\Album' => 'Album\Controller\AlbumController',

        ),

    ),

 

    // The following section is new and should be added to your file

    'router' => array(

        'routes' => array(

            'album' => array(

                'type'    => 'segment',

                'options' => array(

                    'route'    => '/album[/:action][/:id]',

                    'constraints' => array(

                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',

                        'id'     => '[0-9]+',

                    ),

                    'defaults' => array(

                        'controller' => 'Album\Controller\Album',

                        'action'     => 'index',

                    ),

                ),

            ),

        ),

    ),

 

    'view_manager' => array(

        'template_path_stack' => array(

            'album' => __DIR__ . '/../view',

        ),

    ),

);

 

上面配置文件中的路由名称是“album”,类型为 “segment”。segment类型路由可以允许我们使用特别的URL规矩(路由)而可以映射到命名的参数路由上。正因为如此,有路由是 “/album[/:action][/:id]”就可以匹配任何以 album开头的url。下一个片段是关于操作名的控制,最后一个一个映射到可选择的id。中括号的意思是我们可选择的。而 constraints 部分让我们确保在此片段中的字符是可以预料到的,所以我们可以限制操作是以字母开头然后子片段只可能是字母、下划线、或数字。我们同时也限制了id只能为数字。

 

此路由规则让我们的url一般像这样:

 

URL

页面(Page)

操作(Action)

/album

Home (list of albums)

index

/album/add

Add new album

add

/album/edit/2

Edit album with an id of 2

edit

/album/delete/4

Delete album with an id of 4

delete

 

创建控制器

 

我们准备建立我们的控制器。在 ZF 2中,控制器是一般命名为 {Controller name}Controller 的类。注意 {Controller name}必须是以大写字母开头的。而这个类的文件在模块的  Controller 文件夹中一般为 {Controller name}Controller.php。在我们这个应用中为 module/Album/src/Album/Controller。每个动作是一个 Public 类型的方法,并命名为 {action name}Action。其中 {action name} 必须是以小写字母开头。

 

注意

这是约定俗成的。ZF 2 并没有约束它一定要实现 theZend\Stdlib\Dispatchable 接口。框架提供2个抽象类给我们: Zend\Mvc\Controller\AbstractActionController 及 Zend\Mvc\Controller\AbstractRestfulController。我们一般使用标准的 AbstractActionController,但是如果你想写一个 RESTful 架构的 web 服务,AbstractRestfulController 这个类应该更有用些。

 

现在就让我们来创建我们的控制器类:

// module/Album/src/Album/Controller/AlbumController.php:

namespace Album\Controller;

 

use Zend\Mvc\Controller\AbstractActionController;

use Zend\View\Model\ViewModel;

 

class AlbumController extends AbstractActionController

{

    public function indexAction()

    {

    }

 

    public function addAction()

    {

    }

 

    public function editAction()

    {

    }

 

    public function deleteAction()

    {

    }

}

 

注意

我们已经通过配置 config/module.config.php 文件中的 “controller”部分将控制器通知给模块。

 

我们现在可以创建4个我们想使用的动作。他们并不能工作,除非我们已经建立了视图。这些url应该如下:

 

http://zf2-tutorial.localhost/album Album\Controller\AlbumController::indexAction

http://zf2-tutorial.localhost/album/add Album\Controller\AlbumController::addAction

http://zf2-tutorial.localhost/album/edit Album\Controller\AlbumController::editAction

http://zf2-tutorial.localhost/album/delete Album\Controller\AlbumController::deleteAction

 

我们现在已经有个可以工作的路由及对应应用页面的操作。

 

现在就让我们来建立视图层(view)及模型层(model)吧。

 

初识视图脚本(view script)

 

为了将视图集成进应用我们需要创建一些视图脚本文件。这些文件会被 DefaultViewStrategy 执行,并且能够通过控制器的方法返回。这些脚本文件存储在我们的模块的 views 文件夹中,与控制器名称一一对应的。创建4个空的文件如下:

 

module/Album/view/album/album/index.phtml

module/Album/view/album/album/add.phtml

module/Album/view/album/album/edit.phtml

module/Album/view/album/album/delete.phtml

 

我们现在开始填写任何东西,同时开始我们的数据库及模型层。

 

写一些测试

 

我们的 Album 控制器没有处理更多东西,所以还是很方便测试的。

 

创建 zf2-tutorial/tests/module/Album/src/Album/Controller/AlbumControllerTest.php 文件,内容如下:

 

<?php

 

namespace Album\Controller;

 

use Album\Controller\AlbumController;

use Zend\Http\Request;

use Zend\Http\Response;

use Zend\Mvc\MvcEvent;

use Zend\Mvc\Router\RouteMatch;

use PHPUnit_Framework_TestCase;

 

class AlbumControllerTest extends PHPUnit_Framework_TestCase

{

    protected $controller;

    protected $request;

    protected $response;

    protected $routeMatch;

    protected $event;

 

    public function testAddActionCanBeAccessed()

    {

        $this->routeMatch->setParam('action', 'add');

 

        $result   = $this->controller->dispatch($this->request);

        $response = $this->controller->getResponse();

 

        $this->assertEquals(200, $response->getStatusCode());

        $this->assertInstanceOf('Zend\View\Model\ViewModel', $result);

    }

 

    public function testDeleteActionCanBeAccessed()

    {

        $this->routeMatch->setParam('action', 'delete');

 

        $result   = $this->controller->dispatch($this->request);

        $response = $this->controller->getResponse();

 

        $this->assertEquals(200, $response->getStatusCode());

        $this->assertInstanceOf('Zend\View\Model\ViewModel', $result);

    }

 

    public function testEditActionCanBeAccessed()

    {

        $this->routeMatch->setParam('action', 'edit');

 

        $result   = $this->controller->dispatch($this->request);

        $response = $this->controller->getResponse();

 

        $this->assertEquals(200, $response->getStatusCode());

        $this->assertInstanceOf('Zend\View\Model\ViewModel', $result);

    }

 

    public function testIndexActionCanBeAccessed()

    {

        $this->routeMatch->setParam('action', 'index');

 

        $result   = $this->controller->dispatch($this->request);

        $response = $this->controller->getResponse();

 

        $this->assertEquals(200, $response->getStatusCode());

        $this->assertInstanceOf('Zend\View\Model\ViewModel', $result);

    }

 

    protected function setUp()

    {

        $bootstrap        = \Zend\Mvc\Application::init(include 'config/application.config.php');

        $this->controller = new AlbumController();

        $this->request    = new Request();

        $this->routeMatch = new RouteMatch(array('controller' => 'index'));

        $this->event      = $bootstrap->getMvcEvent();

        $this->event->setRouteMatch($this->routeMatch);

        $this->controller->setEvent($this->event);

        $this->controller->setEventManager($bootstrap->getEventManager());

        $this->controller->setServiceLocator($bootstrap->getServiceManager());

    }

}

 

然后执行 phpunit:

 

PHPUnit 3.5.15 by Sebastian Bergmann.

 

.....

 

Time: 0 seconds, Memory: 5.75Mb

 

OK (5 tests, 10 assertions)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值