Zend框架控制器包含HTML接口和REST接口

时间:2013-04-15 14:43:37

标签: php zend-framework rest web-applications

我正在使用Zend-framework开发一个Web应用程序。我正在寻找一种智能解决方案,将RESTful接口和非RESTful接口实现到单个控制器中。

让我们假装我们正在开发一个管理大量纸质杂志信息的网络应用程序。首先,我希望我的网站通过访问以下路径显示所有已注册的HTML格式的杂志。

GET /magazine/

另外,我想要一个HTML表单来修改

的新/现有杂志信息
GET /magazine/modify/new
GET /magazine/modify/3  (HTML form filled with magazine information where ID=3)

并按“提交”按钮添加|更新,该按钮隐式调用以下路径

POST /magazine/modify

...并重定向到/ magazine /。最后,我想要一个RESTful接口,它支持JSON格式的HEAD / GET / POST / PUT / DELETE杂志信息,如下所示。

HEAD /magazine/rest
GET /magazine/rest    (All magazine information in list)
GET /magazine/rest/3  (One single magazine information where ID=3)
POST /magazine/rest
PUT /magazine/rest/new
PUT /magazine/rest/3
DELETE /magazine/rest/3

我唯一的想法是在单个控制器类中准备所有操作,派生Zend_Controller_Action。

class SlipController extends Zend_Controller_Action{
    public function init(){}

    public function indexAction(){
        /* Load all magazine information from model and show. */
        $magazine_mapper = new Application_Model_MagazineMapper();
        $this->view->magazines = $magazine_mapper->fetchAll();
    }

    public function modifyAction(){
        $request = $this->getRequest();
        $form = new Application_Form_Magazine();
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                /* Modify magazine information. */
                $modified_magazine = new Application_Model_Magazine($form->getValues());
                $magazine_mapper = new Application_Model_MagazineMapper();
                $magazine_mapper->save($modified_magazine);
                return $this->_helper->redirector('index');
            }
        }else{
            /* Load and prepare form values from Application_Model_Magazine. */
        }
        $this->view->form = $form;
    }

    public function restAction(){
        switch($this->getRequest()->getMethod()){
            case 'HEAD':   /* Do for method HEAD   */ break;
            case 'GET':    /* Do for method GET    */ break;
            case 'POST':   /* Do for method POST   */ break;
            case 'PUT':    /* Do for method PUT    */ break;
            case 'DELETE': /* Do for method DELETE */ break;
        }
    }

问题在于此解决方案允许我实现每个REST操作。我也听说过一个名为Zend_Rest_Controller的好类,它(我听说它)使得实现RESTful接口变得更容易,但是这个类似乎与Zend_Rest_Route一起使用,所以我不知道在哪里放置非RESTful动作就这样。

我想了解这种情况的最佳做法。如果通过使用路由器黑客或其他解决方案来改善某些事情,我想知道如何做到这一点。

1 个答案:

答案 0 :(得分:2)

为什么坚持将所有东西放在同一个控制器中?

GET /magazine/rest/3对我来说似乎相当落后。 URL路径应该具有减小的范围,即,从最不具体到最具体。我会以GET /rest/magazine/3代替。这将允许您使用modules,一个用于Web应用程序,一个用于REST:

/application/modules/app/controllers
    MagazineController.php
        indexAction()
        editAction()
        newAction()

/application/modules/rest/controllers
    MagazineController.php
        getAction()
        putAction()
        postAction()
        headAction()