Nginx - Kieruj wszystkie żądania do jednego skryptu

11

Mam skrypt PHP, który obsługuje routing skryptów i robi różne wymyślne rzeczy. Został pierwotnie zaprojektowany dla Apache, ale próbuję migrować go do nginx dla kilku moich urządzeń. W tej chwili próbuję usprawnić działanie na serwerze testowym.

Tak więc skrypt działa w ten sposób, że przechwytuje cały ruch HTTP do katalogu (w Apache) za pomocą .htaccesspliku. Oto jak to wygląda:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.+$ index.php [L]
</IfModule>

Całkiem proste. Wszystkie żądania są uruchamiane index.php, proste i proste.

Chcę naśladować to zachowanie w Nginx, ale nie znalazłem jeszcze sposobu. Czy ktoś ma jakieś sugestie?

Oto kopia mojego nginx.confpliku w tej chwili. Zauważ, że został zaprojektowany dla mnie, aby po prostu spróbować go uruchomić; głównie praca kopiuj / wklej.

user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    # multi_accept on;
}

http {
        include         /etc/nginx/mime.types;
        default_type    text/plain;
        include         /etc/nginx/conf.d/*.conf;
        server {
                listen          80;
                server_name     swingset.serverboy.net;

                access_log      /var/log/nginx/net.serverboy.swingset.access_log;
                error_log       /var/log/nginx/net.serverboy.swingset.error_log warn;

                root            /var/www/swingset;

                index           index.php index.html;
                fastcgi_index   index.php;

                location ~ \.php {
                        include /etc/nginx/fastcgi_params;
                        keepalive_timeout 0;
                        fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                        fastcgi_pass    127.0.0.1:9000;
                }
        }
}
mattbasta
źródło

Odpowiedzi:

13

Dodaj,

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

To, co robi, to najpierw sprawdza istnienie $ uri i $ uri / jako rzeczywistych plików / folderów, a jeśli nie istnieją, przejdzie przez /index.php (to moja konfiguracja dla środowiska Zend, gdzie routing odbywa się za pomocą indeksu .php) - oczywiście, jeśli chcesz przekazać niektóre parametry, po prostu dołącz do /index.php a? q = na końcu, a on przekaże parametry.

Upewnij się, że dyrektywa try_file jest dostępna od wersji 0.7.27 i nowszych.

Adam Benayoun
źródło
Ostrzeżenie: To nie zadziała na adresach URL kończących się na .php , na przykład to zadziała/doesNotExist.ph/doesNotExist.php
:,
7

Zrozumiałem to sam! Tak!

Potrzebowałem tylko tego locationbloku:

location /  {
    include /etc/nginx/fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME  $document_root/index.php;
    fastcgi_pass    127.0.0.1:9000;
}

Cała reszta pozostała w dużej mierze taka sama.

mattbasta
źródło
Próbowałeś tego, co napisałem poniżej? Oznacza to również, że wszystkie twoje pliki statyczne przejdą przez index.php - nie jestem pewien, czy tego chcesz.
Adam Benayoun,
@Adam: tak, próbowałem twojego kodu. Chciałem, żeby wszystko przebiegało przez index.php. W każdym razie dzięki!
mattbasta
2

Aby zachować argumenty GET, użyj:

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

$ is_args staje się „?” jeśli $ argumenty nie są puste

Lub jeszcze prościej:

location / {
    try_files /index.php$is_args$args;
}
Alexander Gavriliuk
źródło
Ostrzeżenie: To nie zadziała na adresach URL kończących się na .php , na przykład to zadziała/doesNotExist.ph/doesNotExist.php
:,
1

Po ustawieniu katalogu głównego dodaj to

if (!-e $request_filename)
{
    rewrite ^/(.*)$ /index.php?/$1 last;
    break;
}

W zależności od potrzeb możesz zmienić wyrażenie regularne, ponieważ potrzebujesz rządzenia query_string na index.php

Zhandos Zhandos Ulanuly
źródło
4
Są lepsze sposoby, niż ifosiągnąć to, o co prosi. wiki.nginx.org/IfIsEvil
Isius
0

Jednym z bardzo ważnych problemów, na które należy uważać, gdy celem jest plik PHP, jest upewnienie się, że cokolwiek return/ rewritereguła, której używasz, nie zastępuje location ~ \.phpdyrektywy. Jeśli tak się stanie, nginx będzie obsługiwał twój plik PHP bez renderowania go, ujawniając kod źródłowy PHP. To może być katastrofalne.

Najbezpieczniejszy sposób jest już zapewniony, location / { try_files $uri $uri/ /index.php; }

Upewnij się, że ustawiłeś także index index.phpw swoim location /bloku i odkomentujesz location ~ \.phpblok zawarty w domyślnym pliku konfiguracyjnym.

Luke Mlsna
źródło