CakePHP 3.x 使用 htaccess 将目录重写为分页查询参数

CakePHP 3.x use htaccess to rewrite directories as pagination query params

我正在将 CakePHP 1.x 项目升级到 CakePHP 3.x

1.x 项目的 URL 发布在我们无法更改的地方,例如书籍,因此我需要重写以前的 URL 以匹配 CakePHP 中的分页 URL 3.x

这是 1.x 网址的示例

http://example.org/ledgers/index/1/2
http://example.org/ledgers/index/<page_int>/<tribe_id_int>

这就是 3.x 网址的样子

http://example.org/ledgers/index?page=1&tribe=2

我试过这个 htaccess 规则集

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    RewriteRule ^ledgers/index/(\d)+/(\d)+$ /ledgers/index?page=&tribe= [NC]
</IfModule>

以及

的输出
die(print_r($this->request->getQueryParams(), true));

Array()

我在另一个 Whosebug 看到 post 尝试使用

https://www.generateit.net/mod-rewrite/index.php

哪个给了我

RewriteRule ^ledgers/index/([^/]*)/([^/]*)$ /ledgers/index?page=&tribe= [L]

但仍然是

的输出
die(print_r($this->request->getQueryParams(), true));

Array()

关于如何让它工作的任何想法?

您的规则必须在 ^ index.php [L] 之前定义,因为它捕获所有内容并且永远不会达到您的规则。特别是在您的情况下,它甚至必须放在 RewriteCond 行之前,因为条件只能应用于单个规则。考虑使用 skipping rules 作为解决方法。

虽然在内部重写 URL 会起作用,即您将能够访问查询参数,但保持 URL 不变可能会产生负面影响,例如 Router::url()会产生:

/ledgers/index/1/2?page=1&tribe=2

而不是:

/ledgers/index?page=1&tribe=2

因此您可能需要考虑发出这样的实际重定向(请注意可选的结束斜线,以及括号内的 + 以匹配整数,不只是最后一位):

RewriteRule ^ledgers/index/(\d+)/(\d+)/?$ /ledgers/index?page=&tribe= [NC,L,QSA,R=301]

这将在外部重定向到新的 URL 结构,并且使用 QSA 标志还允许合并可能的现有查询参数,即:

/ledgers/index/1/2?foo=bar

将重定向到:

/ledgers/index?page=1&tribe=2&foo=bar

另见