使用 Zend 1.9,我尝试使用 Zend_Rest_Route
来实现分层 url。因此,我有 2 个 RestFul Controller (users
和 items
),并使用分层路由调用第二个 Controller 。
示例:(考虑 GET http 动词)
- http://example.org/users///这个指向
usersController
的indexAction
- http://example.org/users/234//这个指向
usersController
的getAction
- http://example.org/users/234/items//这个指向
itemsController
的indexAction
- http://example.org/users/234/items/34//这个指向
itemsController
的showAction
示例:(考虑 POST http 动词)
- http://example.org/users///这个指向
usersController
的postAction
- http://example.org/users/234/items//这个指向
itemsController
的postAction
示例:(考虑 PUT http 动词)
- http://example.org/users/234//这个指向
usersController
的putAction
- http://example.org/users/234/items/34//这个指向
itemsController
的putAction
示例:(考虑 DELETE http 动词)
- http://example.org/users/234//这个指向
usersController
的deleteAction
- http://example.org/users/234/items/34//这个指向
itemsController
的deleteAction
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/