Nginx - กำหนดเส้นทางคำขอทั้งหมดไปยังสคริปต์เดียว


11

ฉันมีสคริปต์ PHP ที่จัดการการกำหนดเส้นทางสคริปต์และทำสิ่งที่แปลกใหม่ เดิมทีมันถูกออกแบบมาสำหรับ Apache แต่ฉันพยายามที่จะโยกย้ายไปยัง nginx สำหรับกล่องบางส่วนของฉัน ตอนนี้ฉันกำลังพยายามทำให้ทุกอย่างราบรื่นบนเซิร์ฟเวอร์ทดสอบ

ดังนั้นวิธีที่สคริปต์ทำงานคือมันสกัดกั้นปริมาณการรับส่งข้อมูล HTTP ทั้งหมดสำหรับไดเรกทอรี (ใน Apache) โดยใช้.htaccessไฟล์ นี่คือสิ่งที่ดูเหมือนว่า:

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

ค่อนข้างตรงไปตรงมา คำขอทั้งหมดจะดำเนินการผ่านindex.phpธรรมดาและเรียบง่าย

ฉันต้องการเลียนแบบพฤติกรรมนั้นใน nginx แต่ฉันยังไม่พบวิธี ใครมีคำแนะนำบ้าง?

นี่คือสำเนาnginx.confไฟล์ของฉันในขณะนี้ โปรดทราบว่ามันถูกออกแบบมาสำหรับฉันเพียงแค่พยายามทำให้มันใช้งานได้ ส่วนใหญ่เป็นงานคัดลอก / วาง

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

คำตอบ:


13

เพิ่มสิ่งนี้,

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

สิ่งแรกที่ต้องทำคือตรวจสอบการมีอยู่ของ $ uri และ $ uri / เป็นไฟล์ / โฟลเดอร์จริงและหากไม่มีอยู่ก็จะผ่าน /index.php .php) - แน่นอนถ้าคุณต้องการผ่านพารามิเตอร์บางตัวให้ผนวกกับ /index.php a? q = ที่ท้ายและมันจะผ่านพารามิเตอร์

ตรวจสอบให้แน่ใจว่าคำสั่ง try_file มีให้ตั้งแต่เวอร์ชัน 0.7.27 ขึ้นไป


คำเตือน: สิ่งนี้จะไม่ทำงานกับ URL ที่ลงท้ายด้วย.php ตัวอย่างเช่นวิธีนี้จะใช้งานได้/doesNotExist.ph แต่จะไม่ทำงาน (จะได้รับ 404 แทน):/doesNotExist.php
hanshenrik

7

ฉันคิดออกเอง! ใช่

สิ่งที่ฉันต้องการสำหรับlocationบล็อกคือ:

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

ทุกอย่างอื่นยังคงเหมือนเดิม


คุณลองสิ่งที่ฉันเขียนด้านล่างหรือไม่? นอกจากนี้ยังหมายความว่าไฟล์สแตติกทั้งหมดของคุณจะผ่าน index.php - ไม่แน่ใจว่าคุณต้องการ
Adam Benayoun

@ อดัม: ใช่ฉันลองรหัสของคุณ ฉันต้องการให้ทุกอย่างทำงานผ่าน index.php ขอบคุณ แต่!
mattbasta

2

เพื่อรักษาข้อโต้แย้ง GET ใช้ต่อไปนี้:

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

$ is_args กลายเป็น '?' ถ้า $ args ไม่ว่างเปล่า

หรือง่ายยิ่งขึ้น:

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

คำเตือน: วิธีนี้ใช้ไม่ได้กับ URL ที่ลงท้ายด้วย.php ตัวอย่างเช่นวิธีนี้จะใช้งานได้/doesNotExist.ph แต่จะไม่ทำงาน (จะได้รับ 404 แทน):/doesNotExist.php
hanshenrik

1

หลังจากตั้งค่ารูตผบเพิ่มแล้ว

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

ตามความต้องการของคุณคุณอาจเปลี่ยน regex ตามที่คุณต้องการปกครอง query_string เพื่อ index.php


4
มีวิธีที่ดีกว่าifทำสิ่งที่เขาขอให้สำเร็จ wiki.nginx.org/IfIsEvil
Isius

0

ข้อผิดพลาดที่สำคัญอย่างหนึ่งที่ต้องระวังเมื่อเป้าหมายของคุณคือไฟล์ PHP คือตรวจสอบให้แน่ใจว่าสิ่งที่return/ rewriteกฎที่คุณใช้นั้นไม่ได้ใช้location ~ \.phpคำสั่งเกินจริง หากสิ่งนี้เกิดขึ้น nginx จะให้บริการไฟล์ PHP ของคุณโดยไม่แสดงผลซึ่งจะเปิดเผยซอร์สโค้ด PHP นี่อาจเป็นความหายนะ

วิธีที่ปลอดภัยที่สุดมีไว้แล้ว location / { try_files $uri $uri/ /index.php; }

ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าindex index.phpในlocation /บล็อกของคุณและยกเลิกการใส่เครื่องหมายในlocation ~ \.phpบล็อกที่อยู่ในไฟล์กำหนดค่าเริ่มต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.