我想用NGINX提供静态HTML文件,但是如果文件丢失,它应该加载PHP文件而PHP应该处理内容.
我一直在测试几种组合try_files
,但我无法理解它.我有一个虚拟的PHP应用程序,如下所示:
./
../
dynamic.php
index.php
static/
static/static.html
Run Code Online (Sandbox Code Playgroud)
然后我在索引上有一个小的PHP代码,如下所示:
<?php
$path = $_SERVER['REQUEST_URI'];
$pattern = '/^\/(.*)\.html$/';
$matches = [];
$results = preg_match($pattern, $path, $matches);
if (count($matches) > 0) {
if ($matches[1] == "dynamic") {
require 'dynamic.php';
} else {
echo "Not found!";
}
} else {
echo "Index page!";
}
Run Code Online (Sandbox Code Playgroud)
浏览每个页面的结果应该是:
http://foo.bar/ - Loads index.php
http://foo.bar/static.html - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html - Loads index.php with "not found" message
Run Code Online (Sandbox Code Playgroud)
这是我在NGINX配置文件中得到的:
server {
listen 80;
server_name .foo.bar *.foo.bar;
access_log /var/log/nginx/foo.access.log;
error_log /var/log/nginx/foo.error.log;
root /var/www/foo;
index index.php;
location / {
# Trying with 'try_files' here. No success.
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在反复尝试,显然完全失败了这条线:
try_files $uri $uri/static /index.php;
Run Code Online (Sandbox Code Playgroud)
我错过了什么.救命?
有许多方法可以static
从URL 隐藏目录.例如,操纵root
,巧妙使用try_files
或a rewrite
.
可能最明显的是:
root /var/www/foo;
location / {
root /var/www/foo/static;
try_files $uri /index.php;
}
location ~ \.php$ { ... }
Run Code Online (Sandbox Code Playgroud)
这样nginx
在static
文件夹中查找普通文件,但文件的父文件夹.php
.
你想要实现的是这样的:
root /var/www/foo;
location / {
try_files /static$uri /index.php;
}
location ~ \.php$ { ... }
Run Code Online (Sandbox Code Playgroud)
/static
在测试存在之前,它将为任何URI添加前缀.的/index.php
必须是最后一个元素,因为它在不同的位置所需要的处理.有关更多信息,请参阅此文
我会将您的静态目录用作文档根目录.这可以确保没有人可以/dynamic.php
直接执行,但是,它将index.php
通过命名的位置块转发给您@php
.
此配置示例未经测试!
server {
index index.php;
root /var/www/foo/static;
server_name foo.bar *.foo.bar;
location / {
try_files $uri @php;
}
location @php {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/foo/index.php;
}
}
Run Code Online (Sandbox Code Playgroud)
listen
如果它只包含80,则不需要该指令,因为这是默认值.server_name
不是应该包含前导点.$uri
总是包含请求的URI包括前导斜杠(例如/static.html
)和nginx的前缀将他们在的调用文档根目录try_files
(如/var/www/foo/static.html
).因此,您需要static
在$uri
(例如/static$uri
变为/var/www/foo/static/static.html
)之前设置目录.fastcgi_split_path_info
因为您没有使用该功能.try_files
在PHP位置使nginx无法正确转发内容.因此,请求/dynamic.html
不会结束.php
,try_files
总是会失败.