Wie lasse ich Nginx alle Anfragen nach Dateien, die nicht existieren, in eine einzige PHP-Datei umleiten?

7

Ich habe die folgende nginx vhost Konfiguration:

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;
    }
}

Ich möchte alle Anfragen umleiten, die nicht mit Dateien übereinstimmen, die in index.php vorhanden sind. Dies funktioniert derzeit für die meisten URIs einwandfrei, zum Beispiel:

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

Weder noch asdoder asd/123/1.txtvorhanden, daher werden sie zu index.php umgeleitet, und das funktioniert einwandfrei. Wenn ich jedoch die URL eingebe example.com/asd.php, versucht sie zu suchen, asd.phpund wenn sie nicht gefunden werden kann, gibt sie 404 zurück, anstatt die Anforderung an zu senden index.php.

Gibt es eine Möglichkeit, asd.phpauch gesendet zu werden, index.phpwenn asd.phpes keine gibt?

Richard
quelle
Sie könnten einfach ^ /index.php umschreiben; statt 404 zurückzugeben;
Martin Fjordvald
Siehe meinen Kommentar unter tyoyengels Antwort - Ich brauche eine Möglichkeit, der index.php-Datei mitzuteilen, dass sie error/404als Pfad verwendet werden soll
Richard

Antworten:

11

Wenn Sie sich Ihre zusätzlichen Kommentare ansehen, scheint dies der optimalste Weg zu sein, obwohl es keine hübsche Konfiguration ist.

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;
    }
}
Martin Fjordvald
quelle
1
Es soll ein Semikolon am Ende dieser try_files-Zeile stehen
jab11
@ jab11 Ja! Fügte das jetzt hinzu.
Martin Fjordvald
3

Wow, ich denke, alles, was Sie diesen Code ersetzen möchten, ist:

error_page 404 /index.php

... wenn ich richtig lese was du willst.


quelle
Dies funktioniert gut, und so habe ich, error_page 404 /error/404/was dann umleitet index.php, aber dann in der php request_uri (was ich benutze, um den angeforderten Pfad zu erhalten) hat es asd.php(vorausgesetzt, dies ist, was eingegeben wurde und führte zu der 404) und ich habe keine Möglichkeit den error/404Weg zu bekommen, um dann in der PHP zu handeln. Gibt es eine Möglichkeit, diesen Pfad an PHP weiterzugeben? IE Ich möchte immer noch eine einzelne front index.php, um auch Fehler zu behandeln. Wie kann ich der index.php mitteilen, dass dies ein zu behandelnder Fehler ist?
Richard
2

Was Sie versuchen, ist dasselbe wie die benutzerdefinierte Fehlerseite. Sie können die error_page-Eigenschaft von nginx verwenden, um dies zu erreichen. Folgen Sie dem Link für weitere Informationen

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

Sameer
quelle
1

Ich denke, das Problem ist, dass Sie "try_files" zusammen mit einer "if" -Anweisung an Ihrem Standort verwenden. Aus der Dokumentation geht hervor, dass try_files ein Ersatz für die Existenzprüfung von if und mod_rewrite sein soll. Aus dem Nginx-Wiki die Seite "try_files" ( http://wiki.nginx.org/HttpCoreModule#try_files ):

"try_files ist im Grunde ein Ersatz für die typische Überprüfung der Existenz von Dateien / Verzeichnissen im mod_rewrite-Stil. Es soll effizienter sein als die Verwendung von if - siehe IfIsEvil."

Überprüfen Sie die "if" -Wiki-Seite ( http://wiki.nginx.org/NginxHttpRewriteModule#if ):

"Hinweis: Bevor Sie if verwenden, lesen Sie bitte die Seite if is evil und ziehen Sie stattdessen try_files in Betracht."

Versuchen Sie also, das zu entfernen, wenn Sie es überprüfen und einfach bei den "try_files" bleiben. Das sollte prüfen, ob eine Seite vorhanden ist (einschließlich asd.php oder eines anderen Endes in .php) und auf index.php zurückgreifen, wenn es diese nicht findet.

Danakim
quelle
Die if-Anweisung soll eine potenzielle Sicherheitslücke verhindern, die hier beschrieben wird: blog.martinfjordvald.com/2010/07/nginx-primer (verlinkt von wiki.nginx.org/Configuration ). Es ist eine Ausnahme von der Regel, if-Anweisungen in Standortblöcken nicht zu verwenden.
Richard
1

Es hat bei mir funktioniert!

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

Richard, laut Pitfalls Guide, wird empfohlen, "cgi.fix_pathinfo = 0" in php.ini zu setzen, da dies eine potenzielle Sicherheitslücke zwischen nginx und php behebt .

Roger
quelle
0

Ich möchte alle fehlenden PHP-Dateien auf eine benutzerdefinierte interne /error404Fehlerseite umleiten . Ich werde meine während der Permutation gefundene Lösung veröffentlichen.

error_page 404 /error404;

hat mir nicht geholfen. Ebenso wenig wie Kombinationen aus location, @missing, rewriteund break. Aber

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.
vladkras
quelle