I would like to make a php script output like a real 404 page (as set in the Apache ErrorDocument directive) if certain conditions are not met. I\'m not sure how I can / if
There is no default method for that. But you can always cheat:
header("Status: 404 Not There");
// no worky
#readfile("http://$_SERVER[HTTP_HOST]/non-existant-url");
// doesn't work either (Apache detects the fraud)
#virtual("/non-existant-url");
// otherwise a HTTP class, this one works but is seldomly available
$request = new HttpRequest("http://localhost/error", 1);
$answer = $request->send();
print $answer->getBody();
This triggers a subrequest. Since it's on the local server, I would disregard any bigger performance penalties. But it might be worth to investiage using the Apache/mod_php virtual() function.
Notably this method depends on knowing a certain location of a 404 resource. If there is already url rewriting in place, then another trick is necessary in your .htaccess:
RewriteRule ^non-existant-url$ error [E=404,L]
This forces the resource to generate the expected result, thus making the default errordocument available.
Your example seems good. You need to use the php header function to do that:
<?php
header("HTTP/1.0 404 Not Found");
?>
Like that you're saying that this page is a 404, and you can then fill in the contents with what you want
A real 404 is just any piece of code that send's a 404 error code back to the browser, so ErrorDocument or header(..404...) are equivalent in this regard.
The recommended way to set the response code from PHP is as @mario suggested:
Header('Status: 404 Not Found');
If you want to get the body of the page the server would ordinarily provide for a 404, and don't care about the URL getting rewritten in the user's browser, you could use something like:
$uri_404 = 'http://'
. $_SERVER['HTTP_HOST']
. ($_SERVER['HTTP_PORT'] ? (':' . $_SERVER['HTTP_PORT']) : '')
. '/was-nowhere-to-be-seen';
Header("Location: $uri");
(When you're directly frobbing the Location
header field, you need to supply a full URI.) The result of this is that the user's browser's will end up pointing to that bogus location, which may not be what you want. (Probably isn't.) So then you could actuall collect the contents of the page yourself and combine the two, in effect:
Header('Status: 404 Not Found');
$uri_404 = 'http://'
. $_SERVER['HTTP_HOST']
. ($_SERVER['HTTP_PORT'] ? (':' . $_SERVER['HTTP_PORT']) : '')
. '/was-nowhere-to-be-seen';
$curl_req = curl_init($uri);
curl_setopt($curl_req, CURLOPT_MUTE, true);
$body = curl_exec($curl_req);
print $body;
curl_close($curl_req);
That should fetch the contents of the 404 page the server reports for the bogus URI, and you can then copy it and use it yourself. This should properly handle any ErrorDocument 404
handler output.