htaccess 将所有页面重定向到除 root 之外的子目录

htaccess redirect all pages to subdirectory except root

我的根目录中有这些文件,内页我有 php 个文件,例如 projects.php,我尝试在 .htaccess 规则中写入文件,例如 xxx .com/projects 从 /pages/projects.php 打开文件,它与以下

一起工作
RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} . [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# No file extension on request then append .php and rewrite to subdir
RewriteCond %{REQUEST_URI} /(.+)
RewriteRule !\.[a-z0-4]{2,4}$ /pages/%1.php [NC,L]

# All remaining requests simply get rewritten to the subdir
RewriteRule (.*) /pages/ [L]

我的问题是当我转到根 xxx.com 而不是打开 index.php 它的打开页面目录时,但是如果我明确地转到 xxx.com/index.php 有用。 我不想 index.php 显示在 url 我需要从我的规则中排除根并使其打开 index.php 而 url 保持 xxx.com

# All remaining requests simply get rewritten to the subdir
RewriteRule (.*) /pages/ [L]

要排除“根”被重写为 /pages/(并改为从根提供 index.php),您只需将最后一条规则中的量词从 * (0或更多)到 +(1 个或更多)- 这样它就不会匹配对根的请求(.htaccess 中的空 URL 路径)。

换句话说:

RewriteRule (.+) /pages/ [L]

顺便说一下,您已经在 CondPattern 中使用 + 在前面的规则/条件 中做了类似的事情, IE。 RewriteCond %{REQUEST_URI} /(.+).

我想到了另一个解决方案:

RewriteEngine On

RewriteBase /

# Hide the "pages" directory and all PHP files from direct access.
RewriteRule ^pages\b|\.php$ - [R=404]

# Rewrite clean-URL pages to the PHP files inside the "pages" directory:
# If the request isn't a file.
RewriteCond %{REQUEST_FILENAME} !-f
# If the request isn't a folder.
RewriteCond %{REQUEST_FILENAME} !-d
# If the PHP page file exists.
RewriteCond %{DOCUMENT_ROOT}/pages/[=10=].php -f
# /your-page?param=foo is rewritten to /pages/your-page.php?param=foo
# The L flag isn't suffisient because the rewrite rule to protect PHP files
# above will take over in the second loop over all the rewrite rules. To stop
# here we can use the newly END flag which stops completely the rewrite engine.
RewriteRule ^.*$ pages/[=10=].php [END,QSA]

您想隐藏 index.php。这可以通过 404 错误来完成。 所以你可以这样做:

RewriteRule ^index\.php - [R=404]

但您可能还想避免有人请求 /pages 列出所有 PHP 文件或直接访问 /pages/your-page.php。所以我使用了一个匹配目录和 PHP 文件扩展名的正则表达式(这里只有小写字母,但是你可以使用 \.(?i)php where (?i) enables the case i不敏感标志)。

然后,对于重写本身,我会用 ^.*$ 捕获 URL,这将在 [=18=] 反向引用中可用,然后可以在重写规则本身中使用,并且在重写条件下。

如果请求不是目录或现有文件,那么我们必须检查重写后的 URL 是否实际上是 pages 目录中的现有 PHP 文件。

我使用了 QSA 标志,以便您将查询参数保留在结果 URL 中。然后 PHP 脚本可以通过 $_GET 轻松访问它们。如果您不使用此标志,我希望您也可以通过检查其他一些环境变量来获取它们。我还必须使用 END 标志,它类似于 Last 标志的 L,但完全停止执行重写规则。如果你使用 L 标志,问题是你会得到 404 错误,因为 /pages/your-page.php 将匹配重写规则以隐藏 PHP 文件,因为整个过程重写规则是 运行 第二次。只有当输入 URL 不再被重写规则更改时,重写引擎循环才会停止。是的,这让我花了很长时间才明白重写规则不仅仅是 运行 一旦它们显示在配置文件中!