使用Zend 1.9,我尝试使用Zend_Rest_Route
来实现分层URL。所以我有2个restFul控制器(users
和items
)并使用分层路由调用第二个控制器。
示例:(考虑GET http动词)
indexAction
usersController
getAction
usersController
indexAction
itemsController
showAction
itemsController
示例:(考虑POST http动词)
postAction
usersController
postAction
itemsController
示例:(考虑PUT http动词)
putAction
usersController
putAction
itemsController
示例:(考虑DELETE http动词)
deleteAction
usersController
deleteAction
itemsController
似乎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路由有更好的解决方案吗?
答案 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) ;
}
}
}
当然,你可以改进它。
我希望它会对你有所帮助。