Forum Moderators: coopster
Suppose I have a web site [mysite.tld...] on which index.php contains the following
<?php
$foo = $_GET['foo'];switch ($foo)
{
case "bar":
include("nonexistent.html");
break;case "baz":
include("existent.html");
}
?>
I visit [mysite.tld...]
Apache, the web server, recieves a request for /index.php?foo=bar. It recognizes the '?' as indicative of a query string, and therefore just looks for a file named 'index.php' in my web root. It finds index.php. Since index.php is an executable program, Apache executes index.php, passing the query string ('foo=bar') on to index.php. Whatever output index.php produces, Apache returns to the user as the result of the request.
Since the query string passed to index.php indicates such behavior, index.php attempts to load "nonexistent.html". If it doesn't exist, the PHP engine prints an error, in HTML, as part of its output.
Apache doesn't know or care what index.php did, it just knows what the output is, and passes that on to the user. As far as Apache is concerned, this was a successfull request.
If you want to treat the absence of that file as a 404 error, you have to write index.php such that instead of generating an error message when it doesn't find the file, it sends a redirect to the 404 error page. Apache doesn't experience a 404, so how Apache is configured to handle 404s matters not at all. Apache found the document the user requested, index.php.
In addition to looking up the header() function, you will probably be interested in file_exists().
<edit> fixed a spelling error so bone-headed even I noticed it </edit>
broken.php
works.php
real.php
broken.php contains
<?php
include("fake.php");
?>
and works.php contains
<?php
include("real.php");
?>
If we visit [mysite.tld...] Apache looks for a file called 'fake.php'. It doesn't exist, so Apache doesn't find it. Having failed to find the file, Apache returns a 404 error and displays its 404 error page.
if we visit [mysite.tld...] Apache looks for a file called works.php. It finds it, determines that it is executable, and runs it. Works.php includes real.php, which also exists, and produces some output, which gets added to the output from works.php. Apache sends the output from works.php, which includes the output from real.php, to the browser.
If we visit [mysite.tld...] Apache looks for 'broken.php'. Apache finds broken.php, determines that it is executable, and runs it. Broken.php attempts to include 'fake.php', but fails because the file doesn't exist. The PHP engine therefore adds its error message to the ourput of broken.php. Apache gets this output, and returns it to the user. As far as Apache is concerned, this was a successfull request - you asked for broken.php, and you got it. No different from the works.php example.
Better?
If we visit [mysite.tld...] Apache looks for a file called 'fake.php'. It doesn't exist, so Apache doesn't find it. Having failed to find the file, Apache returns a 404 error and displays its 404 error page.
This is the problem: fake.php does not exist! fake was just an example name. So what I am saying is that when a .php file doesn't exist I want my error.htm to disply! Right now it works fine for a bad htm or html request as the Apache 404, but it is not working for a php request.
As it is working now, if some slug types anystupidfile.php, they see:
Fatal error: Unable to open /u/web/*****/anystupidfile.php in Unknown on line 0
and if they type anystupidfile.html or htm they see my error.htm page
Sorry I barked up the wrong tree for so long.
I think that apache is calling the CGI PHP interpreter, and passing control to it. The interpreter (and therefore not apache) looks for the missing file, fails, and spits out its error message which apache happily sends to the browser. This is just a theory though :)
Try putting this cheap workaround in your .htaccess file (there are three separate lines here):
RewriteEngine On RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^[0-9a-zA-Z_/.-]+\.php$ /404.html
ErrorDocument 404 /404.html
I haven't tested it though (I have PHP installed as a module, and the 404 error handling in works fine for php and html files) but the above should hopefully translate any non-existent .php URLs to /404.html.
volatilegx - tried it both ways on my development server, just in case, and at least with the module configuration it makes no difference. I can't think of any reason why it would, either, though that's hardly conclusive evidence.
Any request for non-existent HTML files would call the custom 404, but requests for non-existent ASP files would not! I would have expected the missing ASP script to generate a 404, but it actually generates a server error 500.
I assume the error code difference is a result of how the web server handles the requests for the different file types. HTML is basically a "hand-off" whilst the script must first be read and processed by the server.
I was able to get around my problem by simply including a custom 500 error page in addition to the 404. Not sure if this will help your problem, but it may be food for thought.
I wonder what would happen if you changed
ErrorDocument 404 /error.htmto
ErrorDocument 404 /error.php
and changed the name of error.htm to error.php?
Already tried that ...... lol
That said, if we are right that her host has a cgi php setup rather than an Apache module....
Make that him :)
dhdweb
<added>Just noticed your gender specification. Sorry, I thought I remembered some mention that you were female in another thread. I wonder who I'm using a male pronoun about when I shouldn't?</added>