php - 如果找不到,我们如何使用 Apache 重定向到新的 HTML 静态内容并回退到旧的基于 CMS 的 PHP 版本? (nginx try_files)

标签 php apache .htaccess nginx mod-rewrite

问题:

我们正在用 Gatsby 构建的 SSG HTML 版本替换旧的基于 PHP 的网站(基于 Statamic v1)。

问题是:只有一部分现有页面必须更换,而成员(member)空间、/login/contact 页面必须暂时保留。

所以我想知道我应该如何使用新版本调整当前的 .htaccess 配置首先在特定目录中找到新的静态内容(public/) 或者如果不是,则回退到旧的 index.php?path= 方法。

注意事项:

使用 nginx 这将通过 try_files 指令完成 所以,这个问题在某种程度上与: https://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
但我绝对不明白 balancer://app_cluster 的东西..

上下文:

这是目录的简化 View ,因为它们必须由 Apache 提供服务:

www/
├── index.php
├── (... more CMS files)
└── public
    ├── index.html
    ├── main.js
    ├── robots.txt
    ├── img
    │   ├── intro.jpg
    │   ├── logo.svg
    │   └── table.png
    ├── about
    │   └── index.html
    └── staff
        └── index.html

任何public/ 的内容都必须首先
没有 /public 出现在最终 URL 中:

URL : /img/intro.jpg => /public/img/intro.jpg (rewritten as /img/intro.jpg)

并且每个匹配 /index.html 页面的 URL 都必须在没有它的情况下重写:

URL : '' or '/' => /public/index.html (rewritten as '')
URL : /staff or /staff/ => /public/staff/index.html (rewritten as /staff)

现在所有未找到的文件都重定向到 /index.php?path=...

问题

是否只有 Apache 才有可能不使用两个单独的子域和 virtual_hosts.. 来分隔两个源?
我想是的,鉴于 Apache 不可思议的力量, 但由于我现在更习惯了 nginx 的方式,我真的需要你的帮助!! :)

当前配置

(不要问我为什么)

# Turn on the Rewrite Engine
RewriteEngine On

# PERMANENT HTTPS REDIRECTION
RewriteCond %{REQUEST_SCHEME} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# If you're running in a subfolder (like http://example.com/statamic),
# add that here. E.g. /statamic/
RewriteBase /
# Remove trailing slashes from your URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]

# Remove the index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

最佳答案

如果我理解正确,他们的关键要求是在 public/ 中提供静态内容(如果存在),如果不存在,则将请求传递给 index.php

这个要求相对容易处理。规则的顺序很重要,因为它们按顺序应用于每个传入请求。我们可以先对public/内容进行测试,如果存在则优先返回并停止处理。如果请求与该测试不匹配,处理将继续到 index.php 重定向。

RewriteEngine On

# If the requested file or directory exists in public/, internally redirect
# there (internally means no actual new http request, and the URL in the
# browser does not change).  Use OR flag to OR the 2 conditions, instead of
# the usual implicit AND.
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -d
RewriteRule ^.*$ public/%{REQUEST_URI} [L]

# If the requested file does not exist, and is not a directory, pass the
# request to index.php, appending any query string.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

注意你提到:

Every file not found are redirected to /index.php?path=... as allready done now.

需要说明的是,这实际上不是您包含的.htaccess 现在所做的。该规则只是将请求传递给 index.php,没有 path 参数(尽管包括请求中已有的任何现有参数)。您的 index.php 可以使用 $_SERVER 变量访问 - 并且肯定已经在访问 - 真正请求的路径。但是,如果您现在确实想按照您的描述将路径附加到查询中,则必须将该规则修改为:

RewriteRule ^(.*)$ index.php?path=$1 [QSA,L]

另一个旁注 - 问题和 .htaccess 中都有很多无关的东西,我认为这混淆了问题,也许这就是为什么你在这里没有得到很好的回应。

关于php - 如果找不到,我们如何使用 Apache 重定向到新的 HTML 静态内容并回退到旧的基于 CMS 的 PHP 版本? (nginx try_files),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55401961/

相关文章:

php - Flash和PHP库在浏览器中录制声音并保存到.wav文件?

php - 使用带有多选复选框的 Ajax 帖子过滤器获取帖子

php - 如何使 644 权限文件可从 PHP 写入?

php - 将目录移出到 .htaccess 文件是否会增加 CPU 加载时间和 CPU 周期

.htaccess - 使用 htaccess 屏蔽域名和文件夹名称

php - 如何使用@import 连接 CSS 文件?

php - 这就是 AltoRouter GET POST 方法的工作原理吗?

php - 如何在 PHP 中使用 Rails 应用程序 session

php - 从 XAMPP 迁移到 LAMP 时出现问题。内存限制错误

apache - .htaccess 重写规则 : what is the differences between %1 and $1 variables (percentage vs dollar sign)?