URL Zend Route с регулярным выражением - PullRequest
4 голосов
/ 31 октября 2009

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

www.test.com / Parent1 / parent2 / parent3 / пункт

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 ]

6 голосов
/ 22 марта 2012

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

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

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);
    }
}

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

1 голос
/ 07 марта 2013

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

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

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

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

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

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

0 голосов
/ 31 октября 2009

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

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

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

ListLast(Url,'/')

и т.д.


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

[^/]+$

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


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

...