Как настроить иерархические маршруты отдыха Zend?
-
18-09-2019 - |
Вопрос
С помощью Zend Framework я пытаюсь построить маршруты для API REST для ресурсов, организованных по следующему шаблону:
- http://example.org/users/
- http://example.org/users/234
- http://example.org/users/234/items
- http://example.org/users/234/items/34
Как мне настроить это с помощью Zend_Rest_Route?
Вот как я настроил маршрут для ресурса пользователей (users/:id) в моем файле bootstrap.php:
$this->bootstrap('frontController');
$frontController = Zend_Controller_Front::getInstance();
$restRoute = new Zend_Rest_Route($frontController);
$frontController->getRouter()->addRoute('default', $restRoute);
[Насколько я понимаю, это общий маршрут, поэтому пользователи/324/items/34 будут иметь параметры, установленные как id=324 и items=34, и все будет сопоставлено с моделью «Пользователи» (передний модуль).Думаю, оттуда я мог бы просто проверить параметр items и получить элемент № 34 для пользователя № 324 по запросу на получение.]<=== Я только что проверил это, и, похоже, это не работает так:
Доступ к /users/234/items/43 и
var_dump($this->_getAllParams());
в действии get контроллера rest приводит к следующему выводу:
array(4) {
["controller"]=> string(5) "users"
["action"]=> string(3) "get"
[2]=> string(5) "items" ["module"]=> string(7) "default"]
}
Каким-то образом оба идентификатора потерялись...
Любой?
Решение
AFAIK, в Zend_Rest_Route нет функции, которая позволяла бы вам делать что-то подобное.Есть предложение, но неизвестно, когда оно будет реализовано.Вы можете добавить это в свой Bootstrap, чтобы настроить этот собственный маршрут.
$front = $this->getResource('FrontController');
$testRoute = new Zend_Controller_Router_Route(
'users/:user_id/items/:item_id',
array(
'controller' => 'users',
'action' => 'item',
'module' => 'default'
)
);
$front->getRouter()->addRoute('test', $testRoute);
ID пользователя или item_id станут доступны в itemAction в UsersController в качестве параметров:
$user_id = $this->_request->getParam('user_id');
Другие советы
Я открыл исходный код решения на github и в виде пакета композитора.видеть https://github.com/aporat/Application_Rest_Controller_Route.
Я добавил новый класс, который расширяет Zend_Controller_Router_Route и добавляет возможность добавления пользовательских маршрутов отдыха, таких как
$frontController = Zend_Controller_Front::getInstance();
$frontController->getRouter()->addRoute('users-messages', new Application_Rest_Controller_Route($frontController, 'users/:user_id/messages', ['controller' => 'users-messages']));
Zend_Rest_Route сопоставляет первый параметр после имени контроллера с «id» только при наличии 1 параметра.
Лучшее решение, которое я придумал, — создать подкласс Zend_Rest_Route и переопределить функцию match().Скопируйте функцию сопоставления Zend_Rest_Route, но добавьте следующее непосредственно перед комментарием «Digest URI Params» (около 60 строк).
if($pathElementCount > 1 && $path[0] != 'id') {
$params['id'] = urldecode($path[0]);
array_shift($path);
}
Это должно дать вам ту функциональность, которую вы ищете.