Назад | Перейти на главную страницу

Как заставить Nginx перенаправлять все запросы на файлы, которые не существуют, в один файл php?

У меня есть следующая конфигурация nginx vhost:

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    try_files $uri /index.php;

    location ~ \.php$ {
            if (!-f $request_filename) {
                    return 404;
            }

            fastcgi_pass localhost:9000;
            fastcgi_param SCRIPT_FILENAME /path/to/site/dir/webroot$fastcgi_script_name;
            include /path/to/nginx/conf/fastcgi_params;
    }
}

Я хочу перенаправить все запросы, которые не соответствуют файлам, которые существуют, на index.php. На данный момент это отлично работает для большинства URI, например:

example.com/asd
example.com/asd/123/1.txt

Ни один из asd или asd/123/1.txt существуют, поэтому они перенаправляются на index.php, и это отлично работает. Однако, если я введу URL example.com/asd.php, он пытается найти asd.php и когда он не может его найти, он возвращает 404 вместо отправки запроса на index.php.

Есть ли способ получить asd.php быть также отправленным index.php если asd.php не существует?

Судя по вашим дополнительным комментариям, это звучит так, как будто это самый оптимальный способ, хотя это не очень хорошая конфигурация.

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        try_files $uri @missing;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /path/to/nginx/conf/fastcgi_params;
    }

    location @missing {
        rewrite ^ /error/404 break;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        include /path/to/nginx/conf/fastcgi_params;
    }
}

Вау, я думаю, все, что вы хотите заменить этим кодом, это:

error_page 404 /index.php

... если я правильно прочитал то, что вы хотите.

Со мной это сработало!

    location /anyfolder {
        error_page 404 /yourhandler.php?fnf=$uri;
    } 

То, что вы пытаетесь сделать, совпадает с пользовательской страницей ошибок. Для этого вы можете использовать свойство error_page в nginx. Перейдите по ссылке для получения дополнительной информации

http://wiki.nginx.org/HttpCoreModule#error_page

Я думаю, проблема в том, что вы используете «try_files» вместе с оператором «if» в своем местоположении. Согласно документации, try_files должен быть заменой проверки существования стилей if и mod_rewrite. Из вики nginx на странице "try_files" ( http://wiki.nginx.org/HttpCoreModule#try_files ):

"try_files в основном заменяет типичную проверку существования файла / каталога в стиле mod_rewrite. Предполагается, что это более эффективно, чем использование if - см. IfIsEvil"

Проверьте вики-страницу "если" ( http://wiki.nginx.org/NginxHttpRewriteModule#if ):

"примечание: перед использованием if, пожалуйста, просмотрите страницу if is evil и рассмотрите возможность использования try_files вместо этого."

Итак, попробуйте удалить это, если проверьте и просто оставайтесь с "try_files". Это должно проверить наличие какой-либо страницы (включая asd.php или что-либо еще, заканчивающееся на .php) и вернуться к index.php, если он не найдет его.

Ричард, согласно руководству по ловушкам, рекомендуется установить «cgi.fix_pathinfo = 0» в php.ini, поскольку он разрешает потенциальную уязвимость между nginx и php.

Я хочу перенаправить все отсутствующие файлы php на пользовательский внутренний /error404 страница ошибки. Я выложу свое решение, найденное при перестановке.

error_page 404 /error404;

мне не помогло. Также не было комбинаций location, @missing, rewrite и break. Но

location ~ \.php$ {
    # this is it! $fastcgi_script_name points to my url
    try_files $fastcgi_script_name = /error404; 
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
    ...
    etc.