If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

[RESOLVED] Rewriting URLs  how to get 404 for non-existent content?

I use .htaccess to rewrite urls from site.com/persons/firstname-lastname/ to persons.php?person=firstname-lastname
If you type the url-friendly name of a person that exists in the database, then everything works fine. The problem with the way I've done it is that you can type anything in the address bar as long as it matches the rewrite rule even if there's no such record in the database. So if you go to /persons/rubbish/, you just get a blank page. I checked the response headers, and it says 200 OK. What should I do in order to get a 404 Not Found in such cases?

Send a 404 header if no record found

After you try to get the record from the database, see if it contains any data. If not, send the 404 error code with the header() function. If it does contain data, display your page.

Code:

...
$row = mysql_fetch_array($result, MYSQL_ASSOC);
// NEW CODE
if (!$row) {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
} else {
/// the rest of your code, indent it as it is now within the "else" clause
$first_name = stripslashes($row['first_name']);
$last_name = stripslashes($row['last_name']);
// and here's where the contents of the page will be.
...

Hope this helps!

NOTE: The header() function should occur before anything is output to the browser, otherwise you may get an error that headers have already been sent. The easiest way to get around that is to put

Code:

ob_start();

at the beginning of your script to capture all the output buffers, which will allow the header() function to work at any time. At the end of your script put

PS: Your code will generally be more secure (against SQL Injection attacks) if you use the new PDO database classes and used named parameters, rather than messing with quoting strings and putting them in your SQL directly.

Thanks for the reply!
I did what you suggested, and it worked in the sense that the response headers now say 404 Not Found. However, I'm not being redirected to a 404 page. (I do have the code for it in my htaccess: ErrorDocument 404 /404.php and a corresponding 404.php in the root directory) Instead I just get a blank page. Any idea why that is happening?

Oh, and thanks for the tip on the PDO database classes. I'll check them out.

Handle your own error messages

If your PHP script is supplying the header, the web server won't "take over" and pull the error message for you. It assumes that the script will handle it.

You can follow the header() call with the html you want to appear along with the error. The easiest way would probably be to just include your error page after the header() call:

Code:

...
$row = mysql_fetch_array($result, MYSQL_ASSOC);
// NEW CODE
if (!$row) {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
include('404.php');exit;
} else {
/// the rest of your code, indent it as it is now within the "else" clause
$first_name = stripslashes($row['first_name']);
$last_name = stripslashes($row['last_name']);
// and here's where the contents of the page will be.
..
.