在Zend Framework 2中基于请求类型触发相同路由上的不同操作

时间:2014-11-13 10:57:30

标签: javascript php backbone.js zend-framework2

我试图让ZF2以REST方式响应不同的请求类型。

在我的module.config.php中,我有这个路由器配置。

'router' => array(
    'routes' => array(
        'student' => array(
            'type'    => 'segment',
            'options' => array(

                'route'    => '/student[/:action][/:id]',
                'constraints' => array(
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'id'     => '[0-9]+',
                ),

                'defaults' => array(
                    'controller' => 'Student\Controller\Student',
                    'action'     => 'index',
                ),
            ),
        ),
    ),
),

在前端我使用Backbone根据用户交互向服务器发送GET,POST,DELETE请求。 当用户触发删除id为n的学生的动作时,骨干将使用DELETE请求发送/ somePath / student / n。 当用户触发动作以获取id为n的学生时,骨干将使用GET请求发送/ somePath / student / n。

如果我想让当前设置正常工作,我必须更改Backbone请求并将URL从student / n更改为student / delete / n,如果我想删除具有该ID的学生,并且类似于GET。

这是我在客户端做的,我想避免。

define(['backbone'], function(Backbone){
    return Backbone.Model.extend({
        defaults:{
            //set default model values
        },
        initialize: function(){
            //initialize
        },
        methodToURL: {
            'delete': '/student/delete'
        },
        sync: function(method, model, options) {
            options = options || {};
            var id = arguments[1]['id']
            options.url = model.methodToURL[method.toLowerCase()] + '/' + id;
            return Backbone.sync.apply(this, arguments);
        }
    });
});

在服务器端的控制器中,我有不同的操作方法,我想为不同的请求类型运行。

public function deleteAction()
{
        //some code
}
public function getAction()
{
        //some code
}

我不想更改默认主干行为(拦截和更改请求)。

有没有办法配置ZF2路由器使用相同的路由但是根据请求方法类型触发不同的操作?

3 个答案:

答案 0 :(得分:2)

您可以使用Method路由作为分段路由的子路由。 http://framework.zend.com/manual/2.3/en/modules/zend.mvc.routing.html

有一个名为A complex example with child routes的示例,其中blog文字路由的作者创建子路由,每个子路由都是不同的类型。

只需您可以在学生路线中创建子路线,对于您要使用的每种方法都将为Method类型,然后仅更改此方法类型的操作。

'router' => array(
    'routes' => array(
        'student' => array(
            'type'    => 'segment',
            'options' => array(

                'route'    => '/student[/:action][/:id]',
                'constraints' => array(
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'id'     => '[0-9]+',
                ),

                'defaults' => array(
                    'controller' => 'Student\Controller\Student',
                    'action'     => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'delete' => array(
                    'type' => 'method',
                    'options' => array(
                        'verb' => 'delete',
                        'defaults' => array(
                            'action' => 'delete'
                        ),
                    ),
                ),
                'put' => array(
                    'type' => 'method',
                    'options' => array(
                        'verb' => 'put',
                        'defaults' => array(
                            'action' => 'put'
                        ),
                    ),
                ),//and so on...
            ),
        ),
    ),
),

答案 1 :(得分:1)

您可以使用Zend\Mvc\Controller\AbstractRestfulController

它将根据HTTP请求方法调用某些函数

class StudentRest extends AbstractRestfulController {

    /** 
     * will be called with a GET request when it detects that route
     * matches paramater id has been set
     */
    public function get($id) {
        /*load studentdata*/
        return new JsonModel($data);
    }

    /**
     * Will be called on a POST request, and data should be sent with a $_POST
     * This should create a new object/row in db and return 201
     */
   public function Create($data) {
       /*create student*/
       $this->response->setStatusCode(201); // if new student was created.
       return JsonModel();
   }

    /**
     * Will be called on a PUT request. Data should be sent via $_POST
     * It also requires that the $id parameter is set in the route match
     */
   public function Update($id, $data) {}

    /**
     * Will be called on a DELETE request, It requires that the $id parameter is set in the route match
     */
   public function Delete($id) {}
}

你可以通过路线链接到控制器,如此

'student' => array(
        'type'    => 'segment',
        'options' => array(
            'route'    => '/student[/:id]',
            'constraints' => array(
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'Student\Controller\StudentRest ',
            ),
        ),
    ),

还有一些getList函数,当不在路由参数中提供$ id时将调用它。 也值得一提的是,所有函数的默认实现都返回405,其中['content'=> '方法不允许']

Documentation how to use it

答案 2 :(得分:0)

根据文件: http://framework.zend.com/manual/1.12/en/zend.controller.request.html

确定请求方法

getMethod()允许您确定用于请求当前资源的HTTP请求方法。此外,存在各种方法,允许您在询问是否已经发出特定类型的请求时获取布尔响应:

isGet()

isPost()

isPut()

isDelete()

isHead()

isOptions()

这些用例主要用于创建RESTful MVC架构。