4

我正在尝试创建一个“覆盖”这种 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等)只是为了外观,主要参数是那个“项目”......

4

3 回答 3

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

我不得不使用两条路线,因为我们试图查看/打开的当前页面可能没有任何父页面。我确信可能有更好的方法来编写正则表达式,但这对我有用。如果有人知道如何改进正则表达式,请告诉我。

于 2012-03-22T16:50:31.940 回答
1

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

例如,使用:

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

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

这进入了 Apache 的站点配置文件 - 或共享主机上的 .htaccess 文件中。

如果您不使用 Apache,请检查您使用的任何 Web 服务器的 URL 重写功能 - 语法可能略有不同,但会相似。

于 2013-03-07T12:43:00.060 回答
-2

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

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

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

ListLast(Url,'/')

ETC


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

[^/]+$

从最后一个正斜杠到行尾,这将为您提供所有内容。(如果你在需要转义的上下文中使用它,
你只需要用反斜杠转义它。)/


(顺便说一句,在你的例子中,你已经test/开始了 - 这是故意/需要的吗?)

于 2009-10-31T20:33:19.037 回答