Nginx: enruta todas las solicitudes a un solo script

11

Tengo un script PHP que maneja el enrutamiento de script y hace todo tipo de cosas elegantes. Originalmente fue diseñado para Apache, pero estoy tratando de migrarlo a nginx para algunas de mis cajas. En este momento, estoy tratando de suavizar las cosas en un servidor de prueba.

Entonces, la forma en que funciona el script es que intercepta todo el tráfico HTTP para el directorio (en Apache) usando un .htaccessarchivo. Así es como se ve:

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

Muy claro. Todas las solicitudes se ejecutan index.php, simple y llanamente.

Estoy tratando de imitar ese comportamiento en nginx, pero aún no he encontrado una manera. Alguien tiene alguna sugerencia?

Aquí hay una copia de mi nginx.confarchivo en este momento. Tenga en cuenta que fue diseñado para que yo solo trate de hacerlo funcionar; principalmente un trabajo de copiar / pegar.

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
fuente

Respuestas:

13

Agrega esto,

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

Lo que hace es verificar primero la existencia de $ uri y $ uri / como archivos / carpetas reales y, si no existen, simplemente pasará por /index.php (esa es mi configuración para Zend Framework, donde el enrutamiento se realiza a través del índice .php): por supuesto, si necesita pasar algunos parámetros, simplemente agregue /index.php a? q = al final y pasará los parámetros.

Asegúrese de que la directiva try_file esté disponible desde la versión 0.7.27 en adelante.

Adam Benayoun
fuente
Advertencia: Esto no funcionará en las URL que terminan en .php , por ejemplo, esto funcionará: /doesNotExist.ph pero esto no funcionará (obtendrá 404 en su lugar):/doesNotExist.php
hanshenrik
7

¡Lo descubrí por mi cuenta! ¡Si!

Todo lo que necesitaba para el locationbloque era:

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

Todo lo demás permaneció en gran medida igual.

mattbasta
fuente
¿Intentaste lo que escribí a continuación? También significa que todos sus archivos estáticos pasarán por index.php, no estoy seguro de querer eso.
Adam Benayoun
@ Adam: sí, probé tu código. Quería que todo se ejecutara a través de index.php. Gracias, sin embargo!
mattbasta
2

Para preservar los argumentos GET, use lo siguiente:

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

$ is_args se convierte en '?' si $ args no está vacío

O incluso más simple:

location / {
    try_files /index.php$is_args$args;
}
Alexander Gavriliuk
fuente
Advertencia: Esto no funcionará en las URL que terminan en .php , por ejemplo, esto funcionará: /doesNotExist.ph pero esto no funcionará (obtendrá 404 en su lugar):/doesNotExist.php
hanshenrik
1

Después de configurar el directorio raíz, agregue esto

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

Según su necesidad, puede cambiar la expresión regular ya que necesita gobernar query_string a index.php

Zhandos Zhandos Ulanuly
fuente
44
Hay mejores formas que iflograr lo que está pidiendo. wiki.nginx.org/IfIsEvil
Isius
0

Un error muy importante tener cuidado de cuando su destino es un archivo PHP es para asegurarse de que lo return/ rewriteregla que su uso no reemplaza la location ~ \.phpdirectiva. Si esto sucede, nginx servirá su archivo PHP sin procesarlo, revelando el código fuente PHP. Esto puede ser catastrófico.

La forma más segura ya está disponible, location / { try_files $uri $uri/ /index.php; }

Asegúrese de establecer también index index.phpen su location /bloque y descomentar el location ~ \.phpbloque incluido en el archivo de configuración predeterminado.

Luke Mlsna
fuente