NginX:捕获根目录之外的所有文件,但有例外
NginX: catch all file outside of root dir, with exceptions
我正在构建一个站点 运行ning NginX / PHP 并希望所有访问都由 /private/routes.php 处理。
但我也想为 css/js-files 和 public 目录(和子目录)中的奇数 php 文件添加一些例外。
文件夹/文件结构:
/var/www/domain.com
/private/routes.php
/public/test.php
/public/css/main.css
/public/js/main.js
我当前的 NginX 配置:
server {
listen 80;
listen [::]:80;
server_name domain.com;
root /var/www/domain.com/public;
#index index.php;
#allow existing css files
location /css/ {
try_files $uri =404;
}
#allow my defined php files
location /test.php {
try_files $uri =404;
}
#route everything else to my catch-all file
location / {
root /var/www/domain.com;
try_files /private/nada.php /private/routes.php;
#must add php here because of redefined root
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
#handle allowed php files
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
以上配置有效但存在一些问题:
- 我需要将 root 重新定义为 运行 捕获所有文件 (/private/routes.php).
- 因为 #1 我需要在位置中添加 .php ,所以我最终得到 2 php-location-configs.
- 出于某种原因,如果我从“try_files”.
中删除“/private/nada.php”,它就不起作用了
- None-存在.php-文件在/public returns 404 而不是被包罗万象。
我可以将根设置为“/var/www/domain”,但这似乎没有必要,因为只有万能的才会使用其他东西。
有什么好的方法可以稍微清理一下吗?
你的配置真是一团糟。我不会解释每一个错误,否则会使答案长 10 倍。我花了一些时间才弄清楚它是如何部分可行的。这里最有趣的是你的 location /test.php { ... }
并不是真的用来处理 /test.php
请求(或者你得到了 test.php
源代码作为响应),但是如果你删除它,该请求将由嵌套的 PHP 处理程序而不是根处理程序处理。
由于您要实现的配置不属于通常的用例,因此您不应使用 fastcgi-php.conf
它是某种 pre-written PHP-FPM 处理程序,可用于大多数情况情况。它不是 nginx 团队提供的默认 nginx 包的一部分,但一些发行版与 nginx 一起打包,尤其是 Debian-based 发行版。因为它已经包含 try_files
指令,而我们需要使用自定义 try_files
代替,我们不能使用该文件,否则 nginx 会抱怨重复使用 try_files
。
这是一个应该有效的配置:
server {
...
root /var/www/domain.com/public;
# process an existing non-PHP file as a static one, fallback otherwise
location / {
try_files $uri @fallback;
}
# process an existing PHP file through PHP-FPM, fallback otherwise
location ~ \.php$ {
try_files $uri @fallback;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$uri;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
# fallback to /private/routes.php
location @fallback {
include fastcgi_params;
# we don't need a "root" directive here
# instead we can specify the fallback filename directly
fastcgi_param SCRIPT_FILENAME /var/www/domain.com/private/routes.php;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
这种PHP-FPM用法与通常的用法略有不同,因为在fastcgi_params
文件中定义了几个FastCGI变量,这些变量取决于nginx或实际使用的root
$uri
变量值:
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
我从未见过任何 PHP 脚本以某种方式依赖这些,通常的做法是依赖 REQUEST_URI
变量值,但我认为值得注意这种差异。但是,如果需要,可以重新定义这些变量(在这种情况下,应该在 include fastcgi_params;
行之后完成)。例如,以下将完全模拟 PHP 处理程序的通常行为:
location @fallback {
include fastcgi_params;
fastcgi_param SCRIPT_NAME /private/routes.php;
fastcgi_param DOCUMENT_URI /private/routes.php;
fastcgi_param DOCUMENT_ROOT /var/www/domain.com;
fastcgi_param SCRIPT_FILENAME /var/www/domain.com/private/routes.php;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
或者您可以定义一个不同的根,重写一个 URI 并使用常用的:
location @fallback {
root /var/www/domain.com;
rewrite ^ /private/routes.php break;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$uri;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
但是,如前所述,很可能不需要。
如果在 public
目录下您有包含 index.php
文件的子目录,并且您希望这些文件可用而不用文件名指定完整路径(例如 domain.com/subdir/
而不是 domain.com/subdir/index.php
), 将根位置更改为这个:
location / {
index index.php;
try_files $uri $uri/ @fallback;
}
我正在构建一个站点 运行ning NginX / PHP 并希望所有访问都由 /private/routes.php 处理。 但我也想为 css/js-files 和 public 目录(和子目录)中的奇数 php 文件添加一些例外。
文件夹/文件结构:
/var/www/domain.com
/private/routes.php
/public/test.php
/public/css/main.css
/public/js/main.js
我当前的 NginX 配置:
server {
listen 80;
listen [::]:80;
server_name domain.com;
root /var/www/domain.com/public;
#index index.php;
#allow existing css files
location /css/ {
try_files $uri =404;
}
#allow my defined php files
location /test.php {
try_files $uri =404;
}
#route everything else to my catch-all file
location / {
root /var/www/domain.com;
try_files /private/nada.php /private/routes.php;
#must add php here because of redefined root
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
#handle allowed php files
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
以上配置有效但存在一些问题:
- 我需要将 root 重新定义为 运行 捕获所有文件 (/private/routes.php).
- 因为 #1 我需要在位置中添加 .php ,所以我最终得到 2 php-location-configs.
- 出于某种原因,如果我从“try_files”. 中删除“/private/nada.php”,它就不起作用了
- None-存在.php-文件在/public returns 404 而不是被包罗万象。
我可以将根设置为“/var/www/domain”,但这似乎没有必要,因为只有万能的才会使用其他东西。
有什么好的方法可以稍微清理一下吗?
你的配置真是一团糟。我不会解释每一个错误,否则会使答案长 10 倍。我花了一些时间才弄清楚它是如何部分可行的。这里最有趣的是你的 location /test.php { ... }
并不是真的用来处理 /test.php
请求(或者你得到了 test.php
源代码作为响应),但是如果你删除它,该请求将由嵌套的 PHP 处理程序而不是根处理程序处理。
由于您要实现的配置不属于通常的用例,因此您不应使用 fastcgi-php.conf
它是某种 pre-written PHP-FPM 处理程序,可用于大多数情况情况。它不是 nginx 团队提供的默认 nginx 包的一部分,但一些发行版与 nginx 一起打包,尤其是 Debian-based 发行版。因为它已经包含 try_files
指令,而我们需要使用自定义 try_files
代替,我们不能使用该文件,否则 nginx 会抱怨重复使用 try_files
。
这是一个应该有效的配置:
server {
...
root /var/www/domain.com/public;
# process an existing non-PHP file as a static one, fallback otherwise
location / {
try_files $uri @fallback;
}
# process an existing PHP file through PHP-FPM, fallback otherwise
location ~ \.php$ {
try_files $uri @fallback;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$uri;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
# fallback to /private/routes.php
location @fallback {
include fastcgi_params;
# we don't need a "root" directive here
# instead we can specify the fallback filename directly
fastcgi_param SCRIPT_FILENAME /var/www/domain.com/private/routes.php;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
这种PHP-FPM用法与通常的用法略有不同,因为在fastcgi_params
文件中定义了几个FastCGI变量,这些变量取决于nginx或实际使用的root
$uri
变量值:
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
我从未见过任何 PHP 脚本以某种方式依赖这些,通常的做法是依赖 REQUEST_URI
变量值,但我认为值得注意这种差异。但是,如果需要,可以重新定义这些变量(在这种情况下,应该在 include fastcgi_params;
行之后完成)。例如,以下将完全模拟 PHP 处理程序的通常行为:
location @fallback {
include fastcgi_params;
fastcgi_param SCRIPT_NAME /private/routes.php;
fastcgi_param DOCUMENT_URI /private/routes.php;
fastcgi_param DOCUMENT_ROOT /var/www/domain.com;
fastcgi_param SCRIPT_FILENAME /var/www/domain.com/private/routes.php;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
或者您可以定义一个不同的根,重写一个 URI 并使用常用的:
location @fallback {
root /var/www/domain.com;
rewrite ^ /private/routes.php break;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$uri;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
但是,如前所述,很可能不需要。
如果在 public
目录下您有包含 index.php
文件的子目录,并且您希望这些文件可用而不用文件名指定完整路径(例如 domain.com/subdir/
而不是 domain.com/subdir/index.php
), 将根位置更改为这个:
location / {
index index.php;
try_files $uri $uri/ @fallback;
}