Zend Route Url与正则表达式

时间:2009-10-31 20:15:15

标签: regex zend-framework url zend-route

我正在尝试创建一个“覆盖”此类网址的路由:

  

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

     

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

未指定的父母的数量,它应该只用于为网站网址提供更好,更直观的外观。主要参数是“item”。

我想解决这个问题的唯一方法就是使用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等)用于外观,而主要参数就是“item”......

3 个答案:

答案 0 :(得分:6)

我知道这是一个老问题,但我遇到了类似的问题,我想我应该发布我的解决方案。也许它可以帮助其他人查看这个问题。

我在一个插件中编写了我的路由,显然你需要将插件添加到引导程序中才能工作;)

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 :(得分:1)

如果父项完全不重要,一个简单的解决方案可能是在它们到达Zend之前删除它们 - 也就是说,重写URL以便每次只看到test/:item

例如,使用:

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

(" test /"部分显然可以根据需要更改或动态化。)

进入Apache的网站配置文件 - 或共享主机上的.htaccess文件。

如果您不使用Apache,请检查您正在使用的任何网络服务器的网址重写功能 - 语法可能略有不同但会有所不同。

答案 2 :(得分:-2)

我不知道什么是zend路由(与php相关的东西?),但如果你可以使用普通的编程功能,那么比正则表达式更简单的解决方案就是使用内置的列表/分割功能,例如:

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

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

ListLast(Url,'/')


如果你确实需要一个正则表达式,你只需要这样做:

[^/]+$

这将在最后一次正斜线到最后一行之后给你一切 (如果您在需要转义的上下文中使用反斜杠,则只需要使用反斜杠转义/。)


(顺便说一下,在你的例子中,你在开始时有test/ - 这是故意/必需的吗?)