![使用 Nginx 实现 Apache 风格的多视图](https://linux22.com/image/532823/%E4%BD%BF%E7%94%A8%20Nginx%20%E5%AE%9E%E7%8E%B0%20Apache%20%E9%A3%8E%E6%A0%BC%E7%9A%84%E5%A4%9A%E8%A7%86%E5%9B%BE.png)
对于我运行的一些非 CMS 网站,我有兴趣从 Apache/mod_php 切换到 Nginx。这些网站要么是完全静态的 HTML 文件,要么是简单的 PHP,但它们有一个共同点,那就是我目前使用 Apache 的 mod_negotiation 来为它们提供服务,而无需文件扩展名。我并不关心实际的内容协商;我使用它只是为了不必在 URL 中使用文件扩展名。
例如,可以/info/contact.php
通过以下 URL 访问位于的文件:/info/contact
实际文件是.php
该位置的文件,但我不会在 URL 中使用扩展名。这样可以让我获得更短、更清晰的 URL,并且不会向用户暴露本质上毫无意义的实现细节。在 Apache 中,只需启用 mod_negotiation 并将 +MultiViews 添加到站点的选项中即可。在 Nginx 中,我猜我会以某种方式进行重写,但由于我是 Nginx 的新手,我不太清楚该怎么做。
这些网站目前通过 Nginx 代理到 Apache 运行良好,但我想尝试仅使用 Nginx/fastcgi 运行它们。只要我使用扩展,它们就可以以这种方式正常工作,因此 fastcgi 方面运行良好。我现在关心的只是删除这些扩展。
重要的是要记住文件名不是总是在 URL 中,对于子目录。也就是说,
/foo/bar
应该寻找/foo/bar.php
或/foo/bar/index.php
/foo/
应该寻找/foo/index.php
有没有一种简单的方法可以通过 Nginx 实现这一点,还是我应该坚持使用 Apache 代理?
答案1
你不需要任何繁琐的重写,try_files非常适合这个。它本质上只有一行。
server {
server_name foo.com;
root /your/root/path;
index index.php;
location /
try_files $uri.php $uri/ /notfound.html;
}
# Your standard PHP location and everything else is still required here.
}
答案2
或者你也可以使用:
try_files $uri $uri/ index.php;
/
如果index.php 前面没有 ,它会查找/foo/bar/index.php
,如果它找不到/foo/bar/somethingelse.php
。 (大多数人将其/index.php
作为后备方案,因为这通常是与 wordpress 和类似的 CMS 一起使用的方法)。