URL Zend Route с регулярным выражением

Я пытаюсь создать маршрут, который будет "покрывать" этот вид URL:

www.test.com/parent1/parent2/parent3/item

www.test.com/parent1/parent2/parent3/parent4/item1

Число этих родителей не указано, и оно должно служить только для лучшего, более интуитивного просмотра URL-адресов сайтов. Основным параметром является этот "элемент".

Я полагаю, что единственный способ решить это - использовать Route_Regex, и поэтому я попытался выполнить эту задачу маршрута примерно так:

routes.test.type = "Zend_Controller_Router_Route_Regex"
routes.test.route = "test/(?:.*)?([^\/]+)"
routes.test.defaults.module = default
routes.test.defaults.controller = test
routes.test.defaults.action = index
routes.test.map.1 = "path"
routes.test.map.2 = "item"
routes.test.reverse = "test/%s%s"

Я не слишком много тестировал это, потому что я не уверен, правильно ли я поступаю... Я понятия не имею, как должно выглядеть это регулярное выражение и как мне относиться к этому "пути".

Можете ли вы посоветовать, что я должен сделать, чтобы удовлетворить такой маршрут? Итак, мне нужен этот путь (parent1, parent2 и т. Д.) Только для внешнего вида, а основным параметром является этот "элемент"...

3 ответа

Я знаю, что это старый вопрос, но у меня была похожая проблема, и я подумал, что должен опубликовать свое решение. Может быть, это может помочь другим, рассматривающим этот вопрос.

Я написал свои маршруты в плагине, очевидно, вам нужно добавить плагин в загрузчик, чтобы это работало;)

class Plugin_RoutesPage extends Zend_Controller_Plugin_Abstract
{
    public function routeStartup(Zend_Controller_Request_Abstract $request)
    {
        $front_controller = Zend_Controller_Front::getInstance();
        $router = $front_controller->getRouter();

        // Page SEO friendly hierarchical urls
        $routePageSeoTree = new Zend_Controller_Router_Route_Regex(
            '([-a-zA-Z0-9/]+)/([-a-zA-Z0-9]+)',
            array(
                // default Route Values
                'controller' => 'page',
                'action' => 'open',
            ),
            array(
                // regex matched set names
                1 => 'parents',
                2 => 'item'
            )
        );
        $router->addRoute('page-seo-tree',$routePageSeoTree);

        // only one level
        $routeSinglePage = new Zend_Controller_Router_Route_Regex(
            '([-a-zA-Z0-9]+)',
            array(
                // default Route Values
                'controller' => 'page',
                'action' => 'open',
            ),
            array(
                // regex matched set names
                1 => 'item'
           )
        );
        $router->addRoute('page-single',$routeSinglePage);
    }
}

Вот как вы можете использовать его в действии вашего контроллера

class PageController extends Zend_Controller_Action
{
    public function openAction()
    {
        // the part of the uri that you are interested in 
        $item = $this->_request->getParam('item');
    }
}

Вот быстрый пример того, как включить его в свой загрузчик

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initPlugins()
    {
            $front_controller = Zend_Controller_Front::getInstance();

            $front_controller->registerPlugin(new Plugin_RoutesPage(), 1);
    }
}

Мне пришлось использовать два маршрута, потому что текущая страница, которую мы пытаемся просмотреть / открыть, может не иметь родителей. Я уверен, что, возможно, есть лучший способ написать регулярное выражение, но это то, что сработало для меня. Если кто-нибудь знает, как улучшить регулярное выражение, пожалуйста, дайте мне знать.

Если родительские элементы полностью не важны, простое решение может состоять в том, чтобы удалить их до того, как они достигнут Zend - то есть переписать URL-адреса так, чтобы они были видны только каждому test/:item

Например, используя:

RewriteEngine On
RewriteRule ^(test/).*/([^/]+) $1$2  [L]

(Очевидно, что часть "test/" может быть изменена или сделана динамической.)

Это входит в конфигурационный файл Apache для сайта - или в файл.htaccess на виртуальном хостинге.

Если вы не используете Apache, проверьте функциональность перезаписи URL для любого веб-сервера, который вы используете - синтаксис может немного отличаться, но будет схожим.

Я не знаю, что такое zend route (что-то, связанное с php?), Но если вы можете использовать обычные функции программирования, то гораздо более простое решение, чем регулярное выражение, - это использовать встроенные функции list / split, например:

end(explode($Url,'/'))

Url.split('/').last()

ListLast(Url,'/')

так далее


Если вам нужно регулярное выражение, вы можете сделать это просто с помощью этого:

[^/]+$

Это даст вам все после последнего слеша до конца строки.
(Вам нужно только избежать / с обратной косой чертой, если вы используете его в контексте, который требует экранирования.)


(кстати, в вашем примере, у вас есть test/ в начале - это преднамеренно / требуется?)

Другие вопросы по тегам