2

I want to route all 404 requests to a php script, How should I do that? My nginx config is:

server { listen 81; listen [::]:81; root /srv/http/paste.lan/www; autoindex on; client_max_body_size 20M; index index.txt index.html index.htm index.php; server_name paste.lan; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } # pass PHP scripts to FastCGI server # location ~ \.php$ { include snippets/fastcgi-php.conf; # # # With php-fpm (or other unix sockets): fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # # With php-cgi (or other tcp sockets): # fastcgi_pass 127.0.0.1:9000; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } } 

Things I have tried:

Attempt #1:

 location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ /index.php; } 
  • This only works for URI's that does not end with .php , for example /DoesNotExist.ph is passed to index.php , but /DoesNotExist.php get the standard nginx 404 page.

Attempt #2:

 location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } error_page 404 /index.php; 

This sort-of works, all 404 requests are passed to index.php but this forces the response code to be 404, even if index.php contains:

<?php http_response_code(200); die("index.php"); 

it will still be served with response code 404 :(

Attempt #3:

 location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } error_page 404 =200 /index.php; 

This also sort-of works, all 404 requests are passed to index.php but this forces the response code to be 200, even if index.php contains:

<?php http_response_code(400);// HTTP 400 Bad Request die("index.php"); 

it will still be served as HTTP 200 OK :(

2
  • 1
    Almost there, the one you want is error_page 404 = /index.php; to respond with the code it returns. Also, you may want to add try_files $uri =404; to your location ~ \.php$ block to catch non-existent PHP files. Commented Mar 10, 2023 at 11:12
  • @RichardSmith dang that works! and i don't need to add anything to the \.php$ block! want to post it as an answer? Commented Mar 10, 2023 at 11:19

1 Answer 1

3

The error_page directive includes an option to change the response code to another.

From the manual page:

If an error response is processed by a proxied server or a FastCGI/uwsgi/SCGI/gRPC server, and the server may return different response codes (e.g., 200, 302, 401 or 404), it is possible to respond with the code it returns:

error_page 404 = /404.php;

You should use:

error_page 404 = /index.php; 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.