自定义PHP MVC应用:Apache到NGINX的重写规则迁移咨询
Hey there, let's get your custom PHP MVC app running smoothly on Nginx. I've worked with this exact directory structure before, so I can help you ditch those finicky if directives and set up a clean, reliable rewrite config that mirrors your Apache .htaccess setup perfectly.
Core Approach
Nginx works differently than Apache when it comes to routing—instead of relying on .htaccess (which Nginx doesn't handle efficiently by default), we'll use location blocks with clear priority rules to:
- Serve static files directly (no need to pass them to PHP)
- Route all
/admin/requests toadmin/index.php - Route all other requests to the root
index.php
Full Server Block Config
Here's the complete, commented config you can drop into your Nginx server block (replace placeholders like yourdomain.com and /path/to/your/app/root with your actual values):
server { listen 80; server_name yourdomain.com; # Replace with your domain root /path/to/your/app/root; # Replace with your app's absolute root directory # Serve static files directly (bypass PHP entirely) location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; # Long-term caching for static assets add_header Cache-Control "public, immutable"; access_log off; # Disable logs for static files to reduce clutter } # Handle ALL /admin/ requests (highest priority match) location ^~ /admin/ { # Try to serve real files/dirs first; if not found, route to admin/index.php try_files $uri $uri/ /admin/index.php?$args; # PHP-FPM handler for admin PHP files location ~ \.php$ { fastcgi_pass unix:/run/php/php8.2-fpm.sock; # Replace with your PHP-FPM socket path fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # Load default CGI parameters (critical for route parsing) } } # Handle all non-admin requests location / { # Try real files/dirs first; if not found, route to root index.php try_files $uri $uri/ /index.php?$args; # PHP-FPM handler for root PHP files location ~ \.php$ { fastcgi_pass unix:/run/php/php8.2-fpm.sock; # Match the same PHP-FPM path as above fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } # Optional: Block access to hidden files (like .htaccess) location ~ /\.ht { deny all; } }
Key Details Explained
location ^~ /admin/: The^~flag ensures this location takes highest priority, so any request starting with/admin/won't be caught by other regex locations. This guarantees admin requests go toadmin/index.php.try_files: This is Nginx's preferred way to handle routing—first it checks if the requested file/directory exists, and if not, it forwards the request to the specified index.php while preserving query parameters ($args).- Static Asset Handling: By matching common static file extensions first, we avoid wasting PHP resources on serving CSS, JS, images, etc. The cache headers also improve performance for repeat visitors.
- PHP-FPM Config: The
SCRIPT_FILENAMEparameter tells PHP exactly which script to execute, andinclude fastcgi_paramsensures critical server variables (likeREQUEST_URI) are passed to your MVC app so it can parse routes correctly.
Why We Avoid if Directives
Nginx's if directive is notoriously finicky in server blocks (the official docs even call it "evil" in some contexts). Using location blocks and try_files is far more reliable and avoids unexpected routing bugs.
Testing the Config
- Reload Nginx with
sudo nginx -s reload - Test a non-admin route (e.g.,
http://yourdomain.com/foo/bar)—it should route to rootindex.php - Test an admin route (e.g.,
http://yourdomain.com/admin/dashboard)—it should route toadmin/index.php - Verify static files load directly (e.g.,
http://yourdomain.com/css/style.css)
内容的提问来源于stack exchange,提问作者MediaGiantDesign

