Php 使用友好URL的可选分页参数向symfony路由添加尾部斜杠

Php 使用友好URL的可选分页参数向symfony路由添加尾部斜杠,php,symfony,routing,Php,Symfony,Routing,我有以下路由配置: # Resources/config/routing.yml AcmeBundle_article: resource: "@AcmeBundle/Resources/config/routing/article.yml" prefix: /article # Resources/config/routing/article.yml acme_article: path: /{page} defaults: { _controll

我有以下路由配置:

# Resources/config/routing.yml
AcmeBundle_article:
    resource: "@AcmeBundle/Resources/config/routing/article.yml"
    prefix:   /article

# Resources/config/routing/article.yml
acme_article:
    path:     /{page}
    defaults: { _controller: AcmeBundle:Article:index, page: 1 }
每当我调用
$this->redirect($this->generateUrl('acme_-article'))
{path('acme_-article')}
,URL都不带尾随斜杠
/
,例如
example.com/article
。我希望它是这样的

example.com/article/
您可以执行以下操作:

# Resources/config/routing/article.yml
acme_article:
    pattern: /{page}
    defaults: { _controller: AcmeBundle:Article:index, page: 1 }
    requirements:
        page: ".*"
在控制器中:

// ArticleController.php
public function indexAction($page)
{
    if (!$page) {
        $page = 1;
    }
}
现在,您可以使用以下方式访问路线:

/article   # page = 1
/article/  # page = 1
/article/2 # page = 2
编辑

要保留参数的类型提示,只需在方法中添加一个检查。例如:

// Article:index
if ($page && intval($page) < 1) {
    return $this->redirect('/article/');
}
此选项允许尾随斜杠,并且
页面
参数必须是数字(如果已设置)


它可以解决您在URL中允许斜杠的问题,但如果您不在生成的URL末尾手动添加尾随斜杠,则不会自动重定向(我知道它不是很干净,但找不到其他替代方法:/)。

我正在寻找一种方法,可以使用路由配置修复此问题,但我认为这是不可能的。不过,我还是做了一些调整

(1)我在路由中添加了一个带有默认值的变量
trailingSlash
。我用它来分页。第一页分页时需要默认值
/
,否则尾随斜杠不会追加到URL中

acme_article:
    path:     /{trailingSlash}{page}
    defaults: { _controller: AcmeBundle:Article:index, trailingSlash: /, page: 1 }
    requirements:
        trailingSlash : '/?'
(2)我在
文章:index
controller中添加了一些参数处理。未找到尾随斜杠时,抛出错误

public function indexAction($trailingSlash = null, $page = 1)
{
    $request = $this->container->get('request');

    // if there is $page, $trailingSlash will be empty
    if (($trailingSlash == '/' && $page >= 1) || !is_numeric($page)) {
        throw new NotFoundHttpException(sprintf('No route found for "%s"', $request->getPathInfo()));
    }

    // ...

    return $this->render('AcmeBundle:Article:index.html.twig', array(
        'articles'          => $articles,
        'pagination'        => $pagination,
        'totalArticles'     => $pagination->getTotalItemCount(),
        'trailingSlash'     => $trailingSlash
    ));
}
(3)我必须在控制器和细枝中的每个URL生成中添加一个尾部斜杠

// Controller
$this->redirect($this->generateUrl('acme_article').'/');
// Twig
{{ path('acme_article') }}/
(4)从SEO的角度来看,我强制在
rel=“canonical”
中为
page=1

{% block canonical %}
    <!-- trailingSlash is / when page = 1 -->
    <!-- trailingSlash is empty when page > 1 -->
    <link rel="canonical" href="{{ url(app.request.get('_route'), app.request.get('_route_params')) }}{{ trailingSlash }}" />
{% endblock %}
{%block canonical%}
{%endblock%}

它解决了问题,但我觉得这是一个解决办法。欢迎提供更好的解决方案。

page:'%2!'
表示允许任何字符使用
page
?是的,如果您仅将参数限制为数字,则后面似乎不能有斜杠。使用这种(快速且脏)的替代方法,您必须检查控制器中页面参数的类型,如果它不是int,则使用重定向(查看我的编辑以了解工作示例)。您可能会误解这个问题。当我们在控制器中调用
$this->redirect($this->generateUrl('acme_-article'))
或在细枝中使用路由键
acme_-article
调用
{path('acme_-article')}}
时,Symfony路由自动省略斜杠。我们从未使用过这样的
$this->redirect('/article/')''$this->redirect($this->generateUrl('your_home_route').'article/');')返回带有尾随斜杠的完整URL。如果您真的需要斜杠,我知道这是唯一的选择,因为在Symfony上定义/生成url似乎是不可能的。直接在controller(如
article/
)中使用url不是一个好主意,因为所有路由都是在一个地方定义的,即
routing.yml
// Controller
$this->redirect($this->generateUrl('acme_article').'/');
// Twig
{{ path('acme_article') }}/
{% block canonical %}
    <!-- trailingSlash is / when page = 1 -->
    <!-- trailingSlash is empty when page > 1 -->
    <link rel="canonical" href="{{ url(app.request.get('_route'), app.request.get('_route_params')) }}{{ trailingSlash }}" />
{% endblock %}