Using Zend 1.9, I am trying to use Zend_Rest_Route to implement hierarchical url. So I have 2 restFul controller (users and items) and invoke the second controller using hierarchical routes.
Example: (consider GET http verb)
- http://example.org/users/ //this point to
indexActionofusersController - http://example.org/users/234 //this point to
getActionofusersController - http://example.org/users/234/items //this point to
indexActionofitemsController - http://example.org/users/234/items/34 //this point to
showActionofitemsController
Example: (consider POST http verb)
- http://example.org/users/ //this point to
postActionofusersController - http://example.org/users/234/items //this point to
postActionofitemsController
Example: (consider PUT http verb)
- http://example.org/users/234 //this point to
putActionofusersController - http://example.org/users/234/items/34 //this point to
putActionofitemsController
Example: (consider DELETE http verb)
- http://example.org/users/234 //this point to
deleteActionofusersController - http://example.org/users/234/items/34 //this point to
deleteActionofitemsController
It seems Zend Framework don't provide this feature out of the box, so I have try to implement my custom solution but I am not very satisfied.
$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);
This is a prototipe of itemsController.php:
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'
]);}
}
This solution seems work but in my opinion is not the best way to do this.
There is a better solution to implement hierarchical restFul routes in Zend?
You can manage route with a plugin.
For example, you can try something like this (not tested with ZF 1.9):
In your bootstrap, add this function (to declare the plugin)
public function _initPlugins(){
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_PRoutage());
}
with this example, the application/plugins folder, create the PRoutage.php plugin like this:
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) ;
}
}
}
Of course, you can improve it.
I hope it will help you.
来源:https://stackoverflow.com/questions/27189987/zend-rest-route-and-hierarchical-routes