When working with PHP frameworks like DooPHP, we often need to handle clean URLs by removing the index.php
segment. The goal is to transform URLs like:
http://example.com/index.php/something/more/
into cleaner versions:
http://example.com/something/more/
The existing configuration has several components we need to consider:
if (!-e $request_filename){
rewrite /.* /index.php;
}
This currently rewrites all non-existent files to index.php, but doesn't handle the reverse operation we need.
To properly remove index.php, we need to add these rules to your server block:
server {
# ... existing configuration ...
# Remove index.php with permanent redirect
location ~ ^/index\.php/(.*)$ {
return 301 /$1;
}
# Existing PHP handler
location ~ \.php$ {
# ... existing PHP configuration ...
}
}
Here's how your complete server block should look with the improvements:
server {
listen 80;
server_name vip.example.com;
return 301 https://vip.example.com$request_uri;
}
server {
listen 443;
server_name vip.example.com;
root /sites/vip.example.com;
# Error pages
error_page 404 /404.html;
error_page 403 /403.html;
error_page 401 /401.html;
# SSL configuration
ssl on;
ssl_certificate /etc/nginx/config/server.csr;
ssl_certificate_key /etc/nginx/config/server.sky;
# Remove index.php permanently
location ~ ^/index\.php/(.*)$ {
return 301 /$1;
}
# Main location block
location / {
auth_basic "example Team Access";
auth_basic_user_file config/htpasswd;
index index.php;
try_files $uri $uri/ /index.php?$args;
}
# PHP handler
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_script_name;
}
}
After making these changes:
- Test your configuration with
nginx -t
- Reload NGINX with
service nginx reload
- Verify by accessing
https://vip.example.com/index.php/test/path
- it should redirect tohttps://vip.example.com/test/path
The configuration now includes several improvements:
- Changed the HTTP to HTTPS redirect to use
return 301
instead ofrewrite
for better performance - Simplified the error page paths
- Added
try_files
directive for better handling of clean URLs - Fixed the root directory specification
Many PHP frameworks like DooPHP generate URLs containing index.php
in the path (e.g., http://example.com/index.php/something/more/
). This creates ugly URLs that aren't SEO-friendly. We want clean URLs like http://example.com/something/more/
.
Here's how to implement clean URLs in NGINX with proper rewrite rules:
server {
listen 80;
server_name example.com;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
root /var/www/example.com;
index index.php;
# Remove index.php from URLs
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/index.php/(.*)$ /$1 permanent;
rewrite ^/(.*)$ /index.php/$1 last;
}
# PHP processing
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Error pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
The configuration uses two key rewrite rules:
rewrite ^/index.php/(.*)$ /$1 permanent;
- Redirects any URL containing index.php to its clean version (301 permanent redirect)rewrite ^/(.*)$ /index.php/$1 last;
- Internally rewrites clean URLs to the index.php handler
After making changes:
sudo nginx -t
sudo systemctl reload nginx
Test with curl to verify redirects:
curl -I http://example.com/index.php/something/more/
- Ensure your PHP framework is configured to handle clean URLs
- Check file permissions on your web root directory
- Verify PHP-FPM is running if you get 502 errors
- Clear your browser cache when testing redirects
For more complex scenarios, you might need additional rules:
# Handle direct requests to index.php
location = /index.php {
return 301 $scheme://$host/;
}
# Prevent direct access to other PHP files
location ~ /(app|config|core)/.*\.php$ {
deny all;
}