php - Zend_Rest_Route 和分层路由

标签 php rest zend-framework

使用 Zend 1.9,我尝试使用 Zend_Rest_Route 来实现分层 url。因此,我有 2 个 RestFul Controller (usersitems),并使用分层路由调用第二个 Controller 。

示例:(考虑 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原型(prototype):

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路由有更好的解决方案吗?

最佳答案

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

例如,您可以尝试这样的操作(未使用 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) ;
        }
    }      

}

当然,你可以改进它。

希望对你有帮助。

关于php - Zend_Rest_Route 和分层路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27189987/

相关文章:

php - PHP 中的数据标准?

python - 如何使用API​​将图像文件写入OpenERP的二进制字段

php - 在 Doctrine 中使用 LIMIT 进行子查询

java - Spring MVC 4 + Tomcat 7,如何用JavaConfig实现HTTPS?

php - 使用 Zend_Pdf 时出现 PDF 文档错误

php - 将对象传递给ZF2中的partial() View 助手

javascript - 将服务器端谷歌图表生成为图像

php - 从 iOS 应用程序安全地访问数据库

php - SOAP 已安装但未在 phpinfo 中显示

java - 对于轻松的 https 调用,如何接受所​​有证书