Here is my .htaccess
file, it's in the /
directory and is working. I want to remove .php
extensions from my site. So, I use the following rule to do so. RewriteRule ^([^\.] )$ $1.php [NC,L]
.
This works but I also want to redirect my blog articles which use dynamic links with this RewriteRule ^([^?]*) route.php?blog=$1
these blogs pull an ID from a database and embed it into the URL and this works correctly.
My issue is that when I add the first paragraph code to remove .php
extensions my blog redirect stops working. Below I will add my PHP code, for review in case I've done something wrong.
Options FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*) route.php?blog=$1
RewriteRule ^([^\.] )$ $1.php [NC,L]
# Error Documents
#ErrorDocument 404 /error_404.php
#ErrorDocument 403 /error_403.php
<?php
// open database //
include($_SERVER['DOCUMENT_ROOT']."/config.php");
$blog = explode("/",$_REQUEST['blog']);
$months = array('','January','Feburary','March','April','May','June','July','August','September','October','November','December');
switch(count($blog))
{
case 3 : {
if($blog[0]=="blog")
{
if(intval($blog[2]) > 0)
{
// get selected blog
$sql = "select * from articles a, categories c where a.cat = c.catid and a.id = '".$blog[2]."' limit 0,1";
$res = $db->query($sql);
$rowcount = $res->num_rows;
if($rowcount > 0)
{
$id = $blog[2];
$blog = mysqli_fetch_assoc($res);
include($doc_path."/blog-single.php");
}
}
}
} break;
}
blog-single.php
<?php
$sql = "select * from categories c, articles a, relatedposts r where r.related_blog = ".$blog['id']." and a.id = r.related_post and c.catid = a.cat order by a.datetime";
$rows = $db->query($sql);
$found = $rows->num_rows;
if($found > 0)
{
?>
CodePudding user response:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^?]*) route.php?blog=$1 RewriteRule ^([^\.] )$ $1.php [NC,L]
The "problem" here is that the first rule rewrites any request (that does not map to a file or directory) to route.php
, passing the requested URL-path in the blog
URL parameter. Consequently, the second rule (that appends .php
to any URL-path that does not contain a dot) is never successful.
You need to reverse the rules and first check that the corresponding .php
file exists before appending the .php
extension. Any requests that are not mapped to a .php
file will then fall through to route.php
.
For example:
# Append ".php" extension if the ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.] )$ $1.php [L]
# Otherwise, drop through to "route.php"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (. ) route.php?blog=$1 [L]
The original subpattern [^?]*
is not necessary, since the query string is not passed in the URL-path matched by the RewriteRule
pattern.
Aside:
Note that neither of these rules handle requests to the document root (ie. the homepage) - as with your original directives. In other words, what do you expect to happen with a request for https://example.com/
? Should this also be rewritten to route.php
(is it already)? If so, then set the DirectoryIndex
directive accordingly. For example, at the top of the .htaccess
file:
DirectoryIndex route.php
Note that this will result in any request for the "homepage" being sent to route.php
, but without the blog
URL parameter (it would be empty anyway).
UPDATE: Although, looking at your PHP script, it doesn't look like you are expecting the document root (ie. an empty URL-path) being handled by route.php
(your first script I assume)? In fact, your script would seem to expect 3 URL path segments only? In which case, you should consider making your regex more restrictive in .htaccess
to prevent your script being unnecessarily called. This will allow the request to fall through to Apache's 404 error document.