Zend_Rest_Route和分层路由

时间:2014-11-28 13:42:59

标签: php rest zend-framework

使用Zend 1.9,我尝试使用Zend_Rest_Route来实现分层URL。所以我有2个restFul控制器(usersitems)并使用分层路由调用第二个控制器。

示例:(考虑GET http动词)

示例:(考虑POST http动词)

示例:(考虑PUT http动词)

示例:(考虑DELETE http动词)

似乎Zend Framework没有提供开箱即用的功能,所以我尝试实现自定义解决方案,但我不是很满意。

 $front = Zend_Controller_Front::getInstance();

 $restRoute = new Zend_Rest_Route($front, [], [
 'moduleName' => [
    'users'
    ]
 ]);
 $front->getRouter()->addRoute('users', $restRoute);   

$route = new Zend_Controller_Router_Route('moduleName/users/:user_id/items', [
    'controller' => 'items',
    'module' => 'moduleName',
    'action' => 'generic'
    ]);
$front->getRouter()->addRoute('items_generic', $route);

$route = new Zend_Controller_Router_Route('moduleName/users/:user_id/items/:item_id', [
    'controller' => 'items',
    'module' => 'moduleName',
    'action' => 'specific'
    ]);
$front->getRouter()->addRoute('items_specific', $route);

这是itemsController.php prototipe

class ModuleName_ItemsController extends Zend_Controller_Action
{


  public function genericAction () //called from http://example.org/users/234/items
  {
    if ($this->getRequest()->isGet()) {
      $this->privateindex();
    } else if ($this->getRequest()->isPost()){
      $this->privatepost();
    }
  }

  public function specificAction () //called from http://example.org/users/234/items/34
  {
    if ($this->getRequest()->isGet()) {
      $this->privateshow();
    } else if ($this->getRequest()->isPut() ||$this->getRequest()->isPost()){
      $this->privateput();
    }else if($this->getRequest()->isDelete()){
      $this->privatedelete();
    }
  }


  private function privateindex(){ return $this->_helper->json->sendJson([
          'items' => 'indexPrivata'
      ]);}

  private function privatepost(){ return $this->_helper->json->sendJson([
      'items' => 'postPrivata'
      ]);}

  private function privateshow(){ return $this->_helper->json->sendJson([
      'items' => 'showPrivata'
      ]);}

  private function privateput(){ return $this->_helper->json->sendJson([
      'items' => 'putPrivata'
      ]);}

  private function privatedelete(){ return $this->_helper->json->sendJson([
      'items' => 'deletePrivata'
      ]);}
}

此解决方案似乎有效,但在我看来,这不是最好的方法。

在Zend中实现分层restFul路由有更好的解决方案吗?

1 个答案:

答案 0 :(得分:2)

您可以使用插件管理路线。

例如,您可以尝试这样的事情(未使用ZF 1.9进行测试):

bootstrap中,添加此功能(以声明插件)

public function _initPlugins(){
    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin(new Application_Plugin_PRoutage());
}

使用此示例,application/plugins文件夹,创建PRoutage.php插件,如下所示:

class Application_Plugin_PRoutage extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {   
        if (preg_match('/(users)(.*)(items)/', $request->getPathInfo())){

            $request->setControllerName('items'); // itemsController

            if ($request->isGet()){
                if (preg_match('/(users\/)(.*)(items\/)([0-9].)/', $request->getPathInfo())){
                    // http://example.org/users/234/items/34 //this point to showAction of itemsController
                    $request->setActionName('show');
                }
                else{
                    // http://example.org/users/234/items //this point to indexAction of itemsController
                    $request->setActionName('index');
                }
            } elseif ($request->isPost()){
                // http://example.org/users/234/items //this point to postAction of itemsController
                $request->setActionName('post');
            } elseif ($request->isPut()){
                // http://example.org/users/234/items/34 //this point to putAction of itemsController
                $request->setActionName('put');
            }elseif ($request->isDelete()){
                // http://example.org/users/234/items/34 //this point to deleteAction of itemsController
                $request->setActionName('delete');
            }
            $request->setDispatched(true) ;
        }
        elseif (preg_match('/(users)/', $request->getPathInfo())){

            $request->setControllerName('users'); // usersController

            if ($request->isGet()){
                if (preg_match('/(users\/)([0-9].)/', $request->getPathInfo())){
                    // http://example.org/users/234 //this point to getAction of usersController 
                    $request->setActionName('get');
                }
                else{
                    // http://example.org/users/ //this point to indexAction of usersController
                    $request->setActionName('index');
                }
            } elseif ($request->isPost()){
                // http://example.org/users/ //this point to postAction of usersController
                $request->setActionName('post');
            } elseif ($request->isPut()){
                // http://example.org/users/234 //this point to putAction of usersController
                $request->setActionName('put');
            }elseif ($request->isDelete()){
                // http://example.org/users/234 //this point to deleteAction of usersController
                $request->setActionName('delete');
            }
            $request->setDispatched(true) ;
        }
    }      

}

当然,你可以改进它。

我希望它会对你有所帮助。