Zend Framework - 使用路由和正则表达式设置用户友好的URL

时间:2015-05-20 09:05:28

标签: php zend-framework routes zend-route

我有两个用户友好网址问题。

我的路由器设置如下:

  • 实际网址为http://www.example.com/course/view-batch/course_id/19
  • 我想要更友好的网址http://www.example.com/java-training/19

我在application.ini中设置了以下路线:

resources.router.routes.viewbatchcourse.route = "/:title/:course_id/"
resources.router.routes.viewbatchcourse.defaults.controller = course
resources.router.routes.viewbatchcourse.defaults.action = view-batch
resources.router.routes.viewbatchcourse.reqs.course_id = "\d+"

这非常有效。

现在我有一个新页面 - 其中包含Java的用户评论

  • 实际网址为http://www.example.com/course/view-reviews/course_id/19
  • 我想要更友好的网址http://www.example.com/java-reviews/19

我意识到它不可能,因为已经设置了一条路线来匹配该格式。

所以我在想是否有可能使用正则表达式并检查标题是否包含"评论"然后使用这条路线。

我试过这种方法,但它没有用。相反,它会打开视图批处理页面:

resources.router.routes.viewreviews.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.viewreviews.route = "/:title/:course_id"
resources.router.routes.viewreviews.defaults.controller = "course"
resources.router.routes.viewreviews.defaults.action = "view-reviews"
resources.router.routes.viewreviews.reqs.course_id = "\d+"
resources.router.routes.viewreviews.reqs.title =  "\breviews\b"

我最接近工作的是

resources.router.routes.viewreviews.route = "/:title/:course_id"
resources.router.routes.viewreviews.defaults.controller = "course"
resources.router.routes.viewreviews.defaults.action = "view-reviews"
resources.router.routes.viewreviews.reqs.course_id = "\d+"
resources.router.routes.viewreviews.reqs.title =  "reviews"

现在,如果我输入网址http://www.example.com/reviews/19,则会调用view-reviews操作。 是否可以 - 检查标题是否包含单词"评论" - 那么应该调用这条路线吗?

回到http://www.example.com/java-training/19的早期工作路线:

resources.router.routes.viewbatchcourse.route = "/:title/:course_id/"
resources.router.routes.viewbatchcourse.defaults.controller = course
resources.router.routes.viewbatchcourse.defaults.action = view-batch
resources.router.routes.viewbatchcourse.reqs.course_id = "\d+"

数字19是课程ID,我需要在操作中从数据库中提取详细信息。

但是当显示页面时,我不希望数字19可见。

我只想让网址为http://www.example.com/java-training

这可能吗?

3 个答案:

答案 0 :(得分:1)

1)您可以使用Route_Regex来实现您想要的目标

protected function _initRoutes()
{
    $router = Zend_Controller_Front::getInstance()->getRouter();

    $route = new Zend_Controller_Router_Route_Regex(
        '([a-zA-Z]+)-reviews/(\d+)',
        array(
            'module' => 'default',
            'controller' => 'course',
            'action'     => 'view-reviews'
        ),
        array(
            1 => 'language',
            2 => 'course_id',
        )
    );
    $router->addRoute('review', $route);

    $route = new Zend_Controller_Router_Route_Regex(
        '([a-zA-Z]+)-training/(\d+)',
        array(
            'module' => 'default',
            'controller' => 'course',
            'action'     => 'view-batch'
        ),
        array(
            1 => 'language',
            2 => 'course_id',
        )
    );
    $router->addRoute('training', $route);        
}

2)对于第二点,我无法看到它是如何可能的。

您可以做的一件事是使用课程名称(如果有的话)显示如下网址:

www.xyz.com/java-training/my-awesome-course-19
www.xyz.com/java-training/19/my-awesome-course

使用我上面提到的路线会很容易。

答案 1 :(得分:0)

问题1.我认为你可以通过改变路线来解决这个问题。您不需要:标题作为路线的一部分,而是可以在您的情况下进行硬编码。我建议使用以下配置。

resources.router.routes.viewbatchcourse.route = "/java-training/:course_id/"
resources.router.routes.viewbatchcourse.defaults.controller = course
resources.router.routes.viewbatchcourse.defaults.action = view-batch
resources.router.routes.viewbatchcourse.defaults.title = java-training
resources.router.routes.viewbatchcourse.reqs.course_id = "\d+"

resources.router.routes.viewreviews.route = "/java-reviews/:course_id/"
resources.router.routes.viewreviews.defaults.controller = course
resources.router.routes.viewreviews.defaults.action = view-reviews
resources.router.routes.viewreviews.defaults.title = java-reviews
resources.router.routes.viewreviews.reqs.course_id = "\d+"

对于问题2.正如你所描述的那样,根本就没有。

答案 2 :(得分:0)

回复:Q1。我没有测试过这个,但希望它指向你想要的方向。

resources.router.routes.viewreviews.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.viewreviews.route = "(.+)-reviews/(\d+)"
resources.router.routes.viewreviews.defaults.controller = "course"
resources.router.routes.viewreviews.defaults.action = "view-reviews"
resources.router.routes.viewreviews.map.1 = "title"
resources.router.routes.viewreviews.map.2 = "course_id"

回复:Q2。我认为您需要将用户转发到另一个(无参数)URL或通过javascript处理此问题。请参阅Modify the URL without reloading the page