Nginx служит для статической страницы перед динамической
Я хочу обслуживать статические файлы HTML с помощью NGINX, но если файл отсутствует, он должен загрузить файл PHP, а PHP должен обрабатывать содержимое.
Я тестировал несколько комбинаций try_files
, но я не могу обойти его. У меня есть фиктивное приложение PHP, которое выглядит так:
./
../
dynamic.php
index.php
static/
static/static.html
Затем у меня есть небольшой 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!";
}
Результаты просмотра на каждой странице должны быть:
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
Это то, что я получил в конфигурационном файле 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;
}
}
Я пытаюсь многократно и, очевидно, полностью терпеть неудачу с этой строкой:
try_files $uri $uri/static /index.php;
Я что-то упускаю. Помощь?
Ответы
Ответ 1
Я бы использовал ваш статический каталог в качестве корня документа. Это гарантирует, что никто не может выполнить /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;
}
}
- Вам не нужна директива
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
всегда терпит неудачу.
Ответ 2
Существует несколько способов скрыть каталог static
из URL-адреса. Например, манипулирование root
, умное использование try_files
или rewrite
.
Возможно, наиболее очевидным является следующее:
root /var/www/foo;
location / {
root /var/www/foo/static;
try_files $uri /index.php;
}
location ~ \.php$ { ... }
чтобы nginx
смотрел в папку static
для обычных файлов, но родительскую папку для файлов .php
.
То, что вы пытались достичь, было примерно так:
root /var/www/foo;
location / {
try_files /static$uri /index.php;
}
location ~ \.php$ { ... }
который будет префикс /static
для любого URI перед тестированием на существование. /index.php
должен быть последним элементом, поскольку он требует обработки в другом месте. Подробнее см. этот документ.
Ответ 3
В соответствии с конкретным примером, который вы указали, приведенная ниже конфигурация вернет результаты, которые вы указали.
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 ~ \.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;
}
location ~ /static {
rewrite ^/static\.html$ /static/ last;
index static.html;
}
location ~ / {
rewrite ^ /index.php last;
}
То есть...
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