Correct way of dealing with error documents when using a php bootstrap
I'm setting up a site using a php bootstrap. It seems the ErrorDocument
directives are given up in preference for the RewriteRule
's. That's ok though, the headers are still sent correctly, so I guess I have to monitor them in the php and redirect to the correct error document manually. The problem though is that while before I was sending a few specific errors to custom pages and the rest were left with the default apache error message, now, I can see how I can redirect my specific pages, but I lose all the default messages. I can't add support for all possible errors. And, I haven't tried it, but I guess this will extend to redirect status codes too, something that I will require since this site is replacing an old one on the same server.
What is the correct way to go about this? I'm hoping I'm just doing something wrong in my .htaccess
, the salient parts of which follow:
# .htaccess
# redirect error documents - commented since they don't work anyway
# ----------------------------------------------------------------------
#ErrorDocument 404 /error/404/
#ErrorDocument 403 /error/403/
#ErrorDocument 401 /error/401/
#ErrorDocument 500 /error/500/
# Redirect to b开发者_运维技巧ootstrap
# ----------------------------------------------------------------------
RewriteEngine on
RewriteBase /
RewriteRule !\.(ico|jpg|png|svg|js|css)$ index.php
# Prevent hotlinking
# ----------------------------------------------------------------------
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?.*\.mysite\.net/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule \.(ico|jpg|png|svg|js|css)$ - [F]
Thanks for your help.
Good question, we work it through PHP.
We use a proprietary framework that we built. We have a table that contains all the valid urls, or "Routes" (much like in code igniter or kohana). We do two things.
Setup the htaccess so that if a file exists on the physical server, then show that file. so the htaccess looks something like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?r=$1 [L,QSA]
explanation - rewrite any url, such as www.domain.com/myurl to go to index.php?r=myurl, except when the url is a file (!-f) or a directory (!-d) that exists on the server.
Then we have our bootstrap file, index.php do something like this:
$route = $_GET['r'];
db::where('route', $route);
$result = db::get('routes')->fetch();
if(!$result) show_error('404');
and then we have defined show_error('404') as
function show_error($type){
switch($type){
case '404':
default:
header("HTTP/1.0 404 Not Found");
include('404.html');
exit;
break;
}
}
Using this technique, most of the other errors, like 403 no access etc. will still be served from apache. Because if there is a password protected directory, for example, then the rewrite will cause the server to display that directory, which will then ask for a password, and if no valid one is supplied it will serve the 403.
Good luck!
The ErrorDocument
directives are configuration options for Apache, that it uses when sending some kind of error code. If you redirect all traffic to PHP, then it becomes PHP's responsibility to respond with an error-document. Since PHP won't do anything by default, it becomes your responsibility.
The proper thing to do, is to issue an appropriate error-code using header
, and then echo out whatever document you want displayed. You can use the same documents as Apache would, if you like. Simply include
it. Eg.:
function respond404() {
header("HTTP/1.0 404 Page Not Found");
include("/error/404/index.html");
exit;
}
As far as I know, there is no way to get hold of these apache settings from with in PHP, so you either have to manually parse the .htaccess
file, or you have to duplicate the information between your Apache settings and your PHP application. There aren't that many error codes anyway - You only need to cover those in the 4xx and 5xx range. See here
精彩评论