Подтвердить что ты не робот

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;

Я что-то упускаю. Помощь?

4b9b3361

Ответ 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