1

I have a PHP based website that I am trying to adapt to processing SEO friendly URLs for blogs, stories, etc. I am trying to get .htaccess working so that it can convert:

example.com/blog/b-this-is-a-post

to:

example.com/blog.php?id=b-this-is-a-post

I am getting 404 page errors using the following .htaccess rules. I was getting 500 Internal server errors until I created the noted .htaccess rules.

RewriteEngine On
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^blog/(.*)$ blog.php?id=$1 [NC,QSA]
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

The redirect to HTTPS works fine, but the regex line to convert the blog link to the blog.php file to process it isn't working. What am I doing wrong?

MrWhite
  • 43,179
  • 8
  • 60
  • 84
karlk123
  • 11
  • 2

1 Answers1

1
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^blog/(.*)$ blog.php?id=$1 [NC,QSA]
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

You seem to have mashed two different rules (HTTP to HTTPS and your blog rewrite) together and broken both. The "redirect to HTTPS" cannot work "fine", since it is processed unconditionally and would create a redirect loop (unless HTTPS requests are not processing this .htaccess file?!).

RewriteCond (conditions) are only applied to the first RewriteRule directive that follows. Together, the RewriteRule directive and preceding conditions form a single rule.

Otherwise, your regex is "OK" (except that it is arguably matching too much).

You need to reorder your directives like this:

Options -MultiViews

RewriteEngine On

RewriteCond %{HTTP_HOST} (^|\.)example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

RewriteRule ^blog/(.*)$ blog.php?id=$1 [L,QSA]

Unless you are serving multiple domains then you can remove the initial condition that checks the HTTP_HOST.

MultiViews needs to also be disabled (it may already be), otherwise the blog to blog.php will be missing the id URL parameter.

I've removed the NC flag on the blog rewrite. Ideally, the regex should be more restrictive and only match valid id values, rather than everything. Certain special characters will result in an error with this rule.

Once this is fully tested, the HTTP to HTTPS redirect should be a 301 (permanent) redirect, not a 302 (temporary) redirect as you have currently.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • Thanks for your suggestions. I tried this and still get 404 page not found errors. I did modify the regex to tighten up the search criteria using ^blog/([a-z0-9-]+)$ which still didn't work. – karlk123 Jun 04 '23 at 17:54
  • @karlk123 I'm wondering if your `.htaccess` file is doing anything at all - are `.htaccess` overrides enabled? With the `.htaccess` file you posted in your question, you said the "redirect to HTTPS works fine", however, what you posted should have resulted in a redirect loop (as I mentioned above) - there's no way that could have worked "fine" (if it was doing anything at all). – MrWhite Jun 04 '23 at 18:33
  • The .htaccess file is doing something as it forces https. Now I understand the logic flow better. With an https url, the rewrite rules don't get processed. If I put the blog rewrite rule before the https redirect, I get the message The page isn’t redirecting properly. So the .httaccess file is being processed. A question, if the url is http, then the rewrite rule forcing https has the L flag, so I think things stop, right? – karlk123 Jun 04 '23 at 19:11
  • Here is an update. Some progress. When I have this as the last line `^(.*)/blog/([a-z0-9-]+)$ $1/blog.php?id=$2 [QSA]` in `.htaccess`, I get the appropriate thing displayed except all of my relative links point to the `blog` directory so css, images, etc aren't displayed properly. If I use this line instead `RewriteRule ^/blog/([a-z0-9-]+)$ /blog.php?id=$1 [QSA]`, I get 404 errors. Any idea why this is happening? – karlk123 Jun 05 '23 at 01:31
  • Ok, I am realizing that my relative links are because the original URL had `blog` as the last directory. Is there a way to force php to use the rewritten URL, not the original URL? Is there something in `.htacess` for this? If not I will have to update my links to be direct, not relative. – karlk123 Jun 05 '23 at 01:32