Why won't my PHP app send a 404 error?

PhpHeaderHttp Status-Code-404

Php Problem Overview


if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
    header('HTTP/1.0 404 Not Found');
}

Why wont this work? I get a blank page.

Php Solutions


Solution 1 - Php

Your code is technically correct. If you looked at the headers of that blank page, you'd see a 404 header, and other computers/programs would be able to correctly identify the response as file not found.

Of course, your users are still SOL. Normally, 404s are handled by the web server.

  • User: Hey, do you have anything for me at this URI webserver?
  • Webserver: No, I don't, 404! Here's a page to display for 404s.

The problem is, once the web server starts processing the PHP page, it's already passed the point where it would handle a 404

  • User: Hey, do you have anything for me at this URI webserver?
  • Webserver: Yes, I do, it's a PHP page. It'll tell you what the response code is
  • PHP: Hey, OMG 404!!!!!!!
  • Webserver: Well crap, the 404 page people have already gone home, so I'll just send along whatever PHP gave me

In addition to providing a 404 header, PHP is now responsible for outputting the actual 404 page.

Solution 2 - Php

if (strstr($_SERVER['REQUEST_URI'],'index.php')){
    header('HTTP/1.0 404 Not Found');
    echo "<h1>404 Not Found</h1>";
    echo "The page that you have requested could not be found.";
    exit();
}

If you look at the last two echo lines, that's where you'll see the content. You can customize it however you want.

Solution 3 - Php

That is correct behaviour, it's up to you to create the contents for the 404 page.
The 404 header is used by spiders and download-managers to determine if the file exists.
(A page with a 404 header won't be indexed by google or other search-engines)

Normal users however don't look at http-headers and use the page as a normal page.

Solution 4 - Php

For the record, this is the all-case handler:

<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");
             
$_SERVER['REDIRECT_STATUS'] = 404;
?> <!-- 404 contents below this line -->

Solution 5 - Php

Load default server 404 page, if you have one, e.g. defined for apache:

if(strstr($_SERVER['REQUEST_URI'],'index.php')){
  header('HTTP/1.0 404 Not Found');
  readfile('404missing.html');
  exit();
}

Solution 6 - Php

Since php 5.4 you can now do http_response_code(404);

Solution 7 - Php

Another solution, based on @Kitet's.

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");

$_SERVER['REDIRECT_STATUS'] = 404;
//If you don't know which web page is in use, use any page that doesn't exists
$handle = curl_init('http://'. $_SERVER["HTTP_HOST"] .'/404missing.html');
curl_exec($handle);

If you are programming a website that hosted in a server you do not have control, you will not know which file is the "404missing.html". However you can still do this.

In this way, you provided exactly the same outcome of a normal 404 page on the same server. An observer will not be able to distinguish between an existing PHP page returns 404 and a non-existing page.

Solution 8 - Php

try with:

header("Status: 404 Not Found");
header('HTTP/1.0 404 Not Found');

Bye!

Solution 9 - Php

A little bit shorter version. Suppress odd echo.

if (strstr($_SERVER['REQUEST_URI'],'index.php')){
  header('HTTP/1.0 404 Not Found');
  exit("<h1>404 Not Found</h1>\nThe page that you have requested could not be found.");
}

Solution 10 - Php

if($_SERVER['PHP_SELF'] == '/index.php'){ 
   header('HTTP/1.0 404 Not Found');
   echo "<h1>404 Not Found</h1>";
   echo "The page that you have requested could not be found.";
   die;
}

never simplify the echo statements, and never forget the semi colon like above, also why run a substr on the page, we can easily just run php_self

Solution 11 - Php

If you want the server’s default error page to be displayed, you have to handle this in the server.

Solution 12 - Php

You're doing it right though it could use some refining. Looks like that's been addressed so let's talk practical application benefits:

An old website of ours that has a large collection of multilingual tech docs was executing this inside an if else conditional:

    if (<no file found>){
        die("NO FILE HERE");
    }

The problem (besides the unhelpful message and bad user experience) being that we generally use a link crawler (in our case integrity) to check out bad links and missing documents. This means that we were getting a perfectly correct 200 no error response telling us that there was a file there. Integrity didn't know that we were expecting a PDF so we had to manually add a 404 header with php. By adding your code above the die (because nothing afterwards would execute and header should always be before any rendered html anyway), integrity (which behaves more or less like a browser) would return a 404 and we would know exactly where to look for missing files. There are more elegant ways of telling the user that there is an error, but by serving a 404 error you are not only notifying browsers and browser-like programs of the error but (I believe-correct me if I'm wrong) are also recording those errors in your server logs where you can easily grep for 404s.

    header('HTTP/1.0 404 Not Found');
    die("NO FILE HERE");

Solution 13 - Php

Try this:

if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
    header('HTTP/1.0 404 Not Found');
    echo "<head><title>404 Not Found</title></head>";
    echo "<h1>Not Found</h1>";
    $uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
    echo "<p>The requested URL ".$uri." was not found on this server.</p>";
    exit();
}

Solution 14 - Php

You know, in my website i created something like this:

        $uri=$_SERVER['REQUEST_URI'];
        $strpos=strpos($uri, '.php');
        if ($strpos!==false){
    	$e404="The page requested by you: &quot".$_SERVER['REQUEST_URI']."&quot, doesn't exists on this server.";
    	$maybe=str_replace('.php','',$uri);
    	$maybe=str_replace('/','',$maybe);
    	die("<center><h1>404</h1><hr><h3>$e404</h3><h3>Maybe try <a href=$maybe>www.leaveyortexthere.p.ht/$maybe</a>?</center>");

}

i hope it helps you.

Solution 15 - Php

I came up to this problem.. I think that redirecting to a non existing link on your server might do the trick ! Because the server would return his 404:
header('Redirect abbb.404.nonexist'); < that doesnt exist for sure

Solution 16 - Php

If you want to show the server’s default 404 page, you can load it in a frame like this:

echo '<iframe src="/something-bogus" width="100%" height="100%" frameBorder="0" border="0" scrolling="no"></iframe>';

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYrrolView Question on Stackoverflow
Solution 1 - PhpAlan StormView Answer on Stackoverflow
Solution 2 - PhpEvan FosmarkView Answer on Stackoverflow
Solution 3 - PhpBob FangerView Answer on Stackoverflow
Solution 4 - PhpSilviu-MarianView Answer on Stackoverflow
Solution 5 - PhpKitetView Answer on Stackoverflow
Solution 6 - PhprparkerView Answer on Stackoverflow
Solution 7 - PhpEarth EngineView Answer on Stackoverflow
Solution 8 - PhpJorge OlafView Answer on Stackoverflow
Solution 9 - Phpuser347726View Answer on Stackoverflow
Solution 10 - PhpJesseView Answer on Stackoverflow
Solution 11 - PhpGumboView Answer on Stackoverflow
Solution 12 - PhpJacob StazewskiView Answer on Stackoverflow
Solution 13 - PhpMohammad FarhoudiView Answer on Stackoverflow
Solution 14 - PhpGGGView Answer on Stackoverflow
Solution 15 - PhpGorillaApeView Answer on Stackoverflow
Solution 16 - PhpcicadaView Answer on Stackoverflow