HTACCESS error 404 not working as expected
Problem:
The requested URL / welcome.php was not found on this server.
In addition, a 404 Not Found error was encountered while trying to use an ErrorDocument to process the request.
Here he is:
-
When I go to www.mysite.com/page it works great, it also works if I go to mysite.com/404
-
But when I miss something and go to www.mysite.com/pag (instead of the page), I get the above error.
I am also using PHP in my index file (welcome.php) to define the value $_GET
and dynamically render the correct page. It might have something to do with it.
Test site: http://mrobertsdesign.ca/home (you can see the error at http://mrobertsdesign.ca/hom )
I've looked everywhere for answers, have been on this for the past 12 hours just trying to figure out why it doesn't work. The bottom line is I'm not sure what is causing the problem ... All help is appreciated!
Any ideas?
My .htaccess file:
<Files .htaccess>
order allow,deny
deny from all
</Files>
ErrorDocument 404 http://mrobertsdesign.ca/404
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^www\.mrobertsdesign\.ca [NC]
RewriteRule ^(.*)$ http://mrobertsdesign.ca/$1 [R=301]
RewriteRule ^([a-zA-Z0-9]+)/?$ welcome.php?page=$1 [NC]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ welcome.php?category=$1&page=$2 [NC]
DirectoryIndex comingsoon.php welcome.php
My index file (welcome.php):
<?php
$web_url = "http://mrobertsdesign.ca";
$path = '';
$page = $_GET['page'];
$pages = array('home','about','work','contact','404');
if ((basename($_SERVER['__FILE__'])) == 'welcome.php'){
if (!empty($page)) {
$url = '/' . $page;
} else {
$page = 'home';
$url = '/' . $page;
}
header('Location: ' . $url, true, 301); exit();
}
if (!empty($page)) {
if(in_array($page,$pages)) {
if (!empty($category)) {
$path = $category . '/' . $category . '_' . $page;
} else {
$path = 'content_' . $page;
}
}else {
$page = '404';
$url = '/' . $page;
header('Location: ' . $url, true, 404); exit();
}
}
else {
$page = 'home';
$path = 'content_' . $page;
}
if($page == 'home'){
// stuff for home here
}else if($page == 'about'){
$page_title = "About";
}else if($page == 'work'){
$page_title = "Work";
}else if($page == 'contact'){
$page_title = "Contact";
}else if($page == '404'){
$page_title = "Oops! (404)";
}
$page_class = 'page-' . $page;
// Page Start
include('includes/header.php');
include('includes/' . $path . '.php');
include('includes/footer.php');
?>
When it changes:
else {
$page = 'home';
$url = '/' . $page;
}
For this:
else {
http_response_code(404); exit;
}
The error changes to an internal server error for both the welcome .php and the 404 error page:
Internal Server Error The server
encountered an internal error or misconfiguration and was unable to fulfill your request.
Please contact the server administrator cgiadmin@yourhostingaccount.com and let them know when the error occurred and what you might have done, possibly caused the error.
More information about this error may be available in the server error log.
Additionally, a 500 Internal Server Error was encountered while trying to use the ErrorDocument to process the request.
More information that I observed:
-
My .htaccess file is overwriting values ββlike
/welcome.php?page=about
in/about
and/welcome.php?category=about&page=me
in/about/me
, so if I go to/about
, it goes to the about page (and there is no / about / me or any second level of pages at the moment anyway). -
If I skip this and navigate to
/abou
either/anything-here
or/anything-here/anything-here-too
, it displays an error message that says it cannot find my index (welcome.php) and my 404 error page. -
However, if I go to
/welcome.php?page=abo
(instead ofabout
, something that is not a real page) it displays my 404 error page. -
If I go to
/any-page.fileextention
(e.g. / about.php - which doesn't actually exist) it displays a 404 error page, also if I go to/one/two/three
it also displays a 404 error page. -
If you go to the page
/welcome.php
(my index page) it will display the correct page, and if you select part of the file extension, for example/welcome.ph
, it will display a 404 error page. If you go to a 404 error page, it will also display correctly in/404
.
The error seems to be triggered when a file is treated as a filesystem (eg, /about
versus /about.php
or /welcome.php?page=about
or /welcome.php?page=abo
) for two levels (eg, /about
and /about/me
).
The /welcome.php?page=mypage
address literally already points to /welcome.php
, but the /about
address is just a filesystem that the .htaccess file has to interpret as a value $_GET
for my /welcome.php
page, which works when the value $_GET
is a real value, but when it doesn't return it appears as an error and discards everything ...
The problem is not even an error document at the moment, it cannot find /welcome.php
and /404
when the address is read as a filesystem with wrong values $_GET
... This is not trying to find /abou/welcome.php
, because there is a file extension and will eventually be loaded on a real 404 page, and it doesn't try to navigate to /abou/404
because in my .htaccess file I provided the full path to my 404 page when http://mrobertsdesign.ca/404
. Here I am lost.
- How does stackoverflow achieve what it does with this .htaccess file where you can remove a portion of the url and it will either try to fill it with the closest similar url or throw a 404 error page?
Answer!
As stated @Phil_1984_
, the following line was conflicting with the request ErrorDocument
, which caused a 404 not found error for my page, /welcome.php
and ErrorDocument
:
else {
$page = 'home';
$url = '/' . $page;
}
His original idea was to change the line to the following:
else {
http_response_code(404); exit;
}
Which got me thinking, I already have dynamic layout, I can just return the value $_GET
to the page instead of redirecting the whole page to a 404 page - which turns out to be the reason for the problem.
The solution was instead of trying to redirect the entire page (technically back to itself, since the entire site is built from this PHP script and a series of inclusions) to a 404 page, to just turn the value $_GET
back to $path
so that the include file include('includes/' . $path . '.php');
read it and just include the 404 document to page (since that would be any way, the only difference is that the url doesn't change).
else {
$page = '404';
$path = 'content_' . $page;
}
source to share
Answer!
As stated @Phil_1984_
, the following line was conflicting with the request ErrorDocument
, which caused a 404 not found error for my page, /welcome.php
and ErrorDocument
:
else {
$page = 'home';
$url = '/' . $page;
}
His original idea was to change the line to the following, which didn't work for me (via a 500 error):
else {
http_response_code(404); exit;
}
What got me thinking, I already have a dynamic layout setup, I can just return the value $_GET
to the page instead of redirecting the entire page to a 404 page - which turns out to be the cause of the problem.
The solution was instead of trying to redirect the entire page (technically back to itself since the whole site is built from this PHP script and a series of inclusions) to a 404 page to just turn the value $_GET
back to $path
so the include file include('includes/' . $path . '.php');
read it and just include the 404 document to page (since that would be any way, only the difference is that the url doesn't change).
else {
$page = '404';
$path = 'content_' . $page;
}
source to share
From the Apache docs:
https://httpd.apache.org/docs/2.2/custom-error.html
Make sure the path is correct and AllowOverride is allowed.
source to share