Сопоставление нескольких URL-адресов с параметрами с помощью регулярного выражения маршрута маршрутизатора контроллера Zend в Zend Framework
Я разрабатываю контроллер Rest с Zend, и меня смущает сопоставление URL-адресов маршрутизатору.
В основном я читал оZend Router , и я не мог планировать свои URL-адреса, чтобы удовлетворить упомянутые маршруты.
Вот некоторые из моих URL-адресов, которые должны быть сопоставлены с маршрутизаторами.
Http://localhost/api/v1/tags.в XML?abc=true (param: abc=true)
Http://localhost/api/v1/tags/123456.xml (param: 123456.xml)
Http://localhost/api/v1/tags/123456/pings.xml (params: 123456, pings.xml)
Http://localhost/api/v1/tags/123456/pings.в XML?a=1&b=2 (params: 123456, pings.xml, a=1, b=2)
Http://localhost/api/v1/tags/123456/pings/count.xml (params: 123456, pings, count.xml)
Я планирую такое что для шаблонов url от 1 до 3 "теги" должны быть контроллером, а для шаблонов url от 4 до 6 "pings" должен быть контроллером.
Теперь я не уверен в том, как настроить маршрутизаторы таким образом, чтобы вышеприведенные сценарии работали.
Обратите внимание, что я не могу изменить эти URL-адреса. Я могу предложить 100 баллов моей репутации за хороший ответ.
2 ответов:
Первые два URL-адреса могут быть объединены в один маршрутизатор.
$r = new Zend_Controller_Router_Route_Regex('api/v1/tags.xml', array('controller' => 'tags', 'action' => 'index')); $router->addRoute('route1', $r);Чтобы дифференцировать первые два маршрута, проверьте наличие параметра abc в контроллере тегов. Добавьте следующее в свой контроллер тегов, действие индекса.
Аналогичным образом маршруты 4 и 5 могут быть объединены в один маршрут.if($this->_getParam('abc') == "true") { //route 2 } else { // route 1 }Я объяснил для маршрута 6. Для маршрута 3 можно использовать ту же логику.
$r = new Zend_Controller_Router_Route_Regex('api/v1/tags/(.*)/pings/(.*)', array('controller' => 'pings', 'action' => 'index'), array(1 => 'param1',2=>'param2') ); $router->addRoute('route6', $r);Затем параметры могут быть доступны следующим образом в pings контроллер.
$this->_getParam('param1') and $this->_getParam('param2')Для Маршрута 5:
$r = new Zend_Controller_Router_Route_Regex('api/v1/tags/(.*)/pings.xml', array('controller' => 'pings', 'action' => 'index'), array(1 => 'param1') ); $router->addRoute('route5', $r);Параметры (часть URL после ?) не будет обрабатываться в маршрутизаторе. По умолчанию они будут переданы вашему контроллеру.
Чтобы получить значение параметра specifc, переданное в URL, используйте в контроллере следующее.
$this->_getParam('a');Логика использования (.* ) в вашем маршруте и назначить им имя параметра и получить к ним доступ в вашем контроллере
Вот стартер для части алгоритма, который перегоняет контроллер, индексированные парамы и расширение из запроса, который вы могли бы включить в расширенную версию
Zend_Rest_Route::match():public function match( $request ) { $path = $request->getPathInfo(); // distill extension (if any) and the remaining path preg_match( '~(?U:(?<path>.*))(?:\.(?<extension>[^\.]*))?$~', $path, $matches ); $this->_values[ '_extension' ] = isset( $matches[ 'extension' ] ) ? $matches[ 'extension' ] : null; $path = isset( $matches[ 'path' ] ) ? $matches[ 'path' ] : ''; // split the path into segments $pathSegments = preg_split( '~' . self::URI_DELIMITER . '~', $path, -1, PREG_SPLIT_NO_EMPTY ); // leave if no path segments found? up to you to decide, but I put it in anyway if( 0 == ( $length = count( $pathSegments ) ) ) { return false; } // initialize some vars $params = array(); $controller = null; // start finding the controller // (presumes controller found at segment 0, 2, 4, etc...) for( $i = 0; $i < $length; $i += 2 ) { // you should probably check here if this is a valid REST controller // (see Zend_Rest_Route::_checkRestfulController() ) $controller = $params[] = $pathSegments[ $i ]; if( isset( $pathSegments[ $i + 1 ] ) ) { $params[] = $pathSegments[ $i + 1 ]; } } // remove the param which is the actual controller array_splice( $params, $i - 2, 1 ); // set the controller $this->_values[ 'controller' ] = $controller; // merge the params and defaults $this->_values = array_merge( $this->_values, $params, $this->_defaults ); return $this->_values; }Это едва ли испытано, и, следовательно, не производственный материал, конечно. Но это должно помочь тебе начать.
Что это дает вам до сих пор, так это:
Контроллер
Расширение
Индексированные параметрыЧего это вам не дает, так это:
Действие (post, put, delete, и т.д. Алгоритм для этого уже есть вZend_Rest_Route::match())
Именованные параметры (Zend_Controller_Request_Httpуже заботятся об этом)EDIT
Я понимаю, что этот ответ можно было бы считать немного расплывчатым до сих пор. Суть в том, чтобы объединить этот алгоритм с алгоритмомmatch()Zend_Rest_Route. Но этот приведенный выше код все еще требует много внимания; вы хотите учитывать модули слишком вероятно (как это делаетZend_Rest_Route), и, возможно, даже дополнительный baseUrl (не уверен, как ZF справляется с этим внутренне на самом деле).
Comments