.htaccess RewriteRule query isn't working - .htaccess

I can't get the following RewriteRule to work.
I have a PHP SQL query to display a web page. It requires a RewriteRule rule which I'm trying to achieve in a .htaccess file.
Here is the full URL at the moment.
www.example.com/category/sub-cat/page.php?art_url=a-page-of-mine
I can't get it to do
www.example.com/category/sub-cat/a-page-of-mine
My Code below:
Options +MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
ErrorDocument 404 /error-404.php
#error 404
RewriteRule ^error/?$ error-404.php [NC,L]
RewriteRule ^category/sub-cat/(0-9a-zA-Z]+) category/sub-cat/page.php?art_url=$1 [NC,L]
Can someone help me out?

AS I said in the comments
Missing a few things here (0-9a-zA-Z]+) like [- as in ([-0-9a-zA-Z]+)
This is going to bite you too...
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Match everything that doesn't have a dot and add .php to it with the [L] last flag. I would bet it will never pass that one in the first place.
Generally you want the more specific rules first, followed by the more generic ones last.
Also if I recall correctly the NC i no case, so you can get rid of the A-Z and just do [-a-z0-9]+
A better way
I try to avoid query string rewrites and rely on the URI method of rewriting common in MVC frameworks
example.com/index.php/category/sub-cat/a-page-of-mine
And then use a router and HTACCESS to only remove the index.php it's much simpler that way.
I have a pretty bare bones router on my GitHub page that shows how to route URL's like that.
https://github.com/ArtisticPhoenix/MISC/tree/master/Router
One big issue with messing with the query string is you can lose the ability to use $_GET the way it's designed to be used for things like search forms etc. So it's better to route not rewrite. Also the MVC way gives you a single entry point for all requests to go through which can make it easier to manage things like Constants, and Autoloaders....

Oh well, this is broken of course:
(0-9a-zA-Z]+)
The charclass lacks the opening [ and doesn't contain/match a literal - as well.

Right. To get this working I needed to add QSA as in [QSA,NC,L]. After how many weeks!!??

Related

"Resolve to the same URL" and .htaccess file for HTML built website

A while ago I made my first website using only HTMl code and some basic inline CSS.
I don't have the experience and the intuitive knowledge of how things work in this world that is why even the most basic errors I have to solve or tweaks I have to make gives me headache.
My website looks like it's duplicated because when you enter the www or the non www version, then both work and for the search engines it looks like there are two identical websites, which is not good for me.
One tool showed me an error saying: "https://domain.lv and https://www.domain.lv should resolve to the same URL, but currently do not."
I've tried different methods to solve this by editing my .htaccess file, but nothing works. I'm sure there is some dumb mistake I am making because I don't know how should even basic things look like when they are right.
This here is my .htaccess file now (for this I used the word domain as a placeholder for my real domain name):
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.domain\.lv [NC]
RewriteRule ^(.*)$ https://domain.lv/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [NC,L]
ErrorDocument 404 /404.html
Do you see what is wrong here and how I get it right?
And maybe someone could give me a sample file of how .htaccess file should look like for websites built from scratch?
I will appreciate any help.
Cheers!

I can't get the second rewrite rule to work in my .htaccess file

I am working locally on Windows 7 with wamp server (v2.5). I have one working rewrite rule for the main front controller in my project, like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [NC,L]
It successfully strips .php from the queries. From this main front controller index.php I have a link to another front controller named theme.php, where I use menu links w/o the.php file extension, like this:
theme/regions
in stead of
theme.php/regions
For that to work I need to add a second rewrite rule to add the php exension, like so:
RewriteRule ^theme($|/$) theme.php/$1 [NC,L]
The only thing I get is a 404 page though :-(.
I would be very grateful for some hints on how to go about this.
You need to put your theme rule before the general route to index.php. And you need to reference what comes after the /theme/ so something like:
RewriteRule ^theme(/?.*)$ theme.php$1 [L]
Additionally, this rule won't work if you have Multiviews turned on, but, this is actually something that's perfectly suited for Multiviews anyways, so you could just try turning that on instead of using a rule to rewrite theme:
Options +Multiviews
Your second RewriteRule works independently of the others and should be placed above the others in your question.
In addition, the format is wrong - you don't need to capture or append anything.
RewriteRule ^theme/?$ theme.php [NC,L]

Complex URL rewriting with .htaccess

Here is what i am trying to achieve
www.example.com/category
www.example.com/category/subcategory
www.example.com/category/subcategory/product
www.example.com/static-page (like /about-us, /contact, /our-services)
(category, subcategory, products, static-pages etc are dynamic text and there is a permalink foreach thing in the database)
if you see all above requests, you will notice that they are just like extending the directory sturcutre one step each time when the link is clicked, e.g, first was category, and then when I clicked on the subcatogery, I was sent to category/subcategory/ and the finally to product page
Anybody can help me how to acheive all this, i have tried lot to achieve this but in vain yet.
Currently i am using this .htaccess
RewriteRule c/(.*)/(.*)/ cat-details.php?permalink=$1&subcat=$2
RewriteRule c/(.*)/(.*) cat-details.php?permalink=$1&subcat=$2
RewriteRule news/(.*)/(.*)/ news-detail.php?news-id=$1&permalink=$2
RewriteRule news/(.*)/(.*) news-detail.php?news-id=$1&permalink=$2
RewriteRule d/(.*)/(.*)/(.*)/(.*)/ download-detail.php?download-id=$1category=$2&subcategory=$3&permalink=$4
RewriteRule d/(.*)/(.*)/(.*)/(.*) download-detail.php?download-id=$1category=$2&subcategory=$3&permalink=$4
As you can see i have to add c/, news/, d/ etc for each link, i am trying to get rid of this and want to make links pretty whitout proceeding c/, news/, d/ etc
About the only way you're going to be able to do this in Apache proper, is to provide info on which URLs map to which scripts. Apache lets you do this via the RewriteMap directive, but that won't work in .htaccess files. Without it, and without the news/ or c/, Apache doesn't have enough info to route the URLs properly.
What you could do, is simply rewrite every URL that doesn't refer to an existing file, to a script that knows which scripts to run in response. A "router" or "front controller" script, they call it. Something like this:
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteRule (.*) router.php?path=$1 [QSA]
And in the script, you examine $_GET['path'], decide which script should handle the request, and load/include/require it.
I have found a way myself, just posting it if it could help anyone else in trouble just like me :p
RewriteRule ^([^/]*)\/$ /romuniverse/cat.php?permalink=$1 [L]
RewriteRule ^([^/]*)/([^/]*)\/$ /romuniverse/sub-cat.php?permalink=$1&subcat=$2 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)\.rar$ /romuniverse/download-detail.php?download-id=$1&category=$2&subcategory=$3&permalink=$4 [L]

.htaccess directory redirect for version releasing

I had an idea which is killing me, as I am not very good with htaccess.
I have the url http://(www./non-www.)example.com/dir/page/file.
But I want to redirect this to the directory root/release/.../dir/page/file
So
root/.htaccess
root/release/1.0/...
root/release/1.5/...
root/release/2.0/...
root/admin/1.0/...
root/admin/1.5/...
root/admin/2.0/...
etc
And if they browse to example.com/admin you go to example.com/admin/2.0. But I think the tricky bit is that I dont want example.com/release/version or example.com/admin/version to be seen.
Or I could just have the two versions hosted release/stable and release/beta.
I hope that makes sense to someone,
Thanks
Sounds like the easiest thing would be to make a page like example.com/admin that meta-redirects to example.com/admin/2.0, then you just do a mod-rewrite to go back to the generic url. As you increase the versions, just change the meta refresh, because your .htaccess mod-rewrite will have reg-ex that matches to your version numbering system.
example:
First for the example.com/admin file, implement a meta-refresh in the header:
<meta http-equiv="refresh" content="0;URL='example.com/admin/2.0'">
Now do a re-write from the 2.0 (or from any version) back to where you want to go:
#first, we need to define the request, in this case, admin/any number
RewriteCond %{THE_REQUEST} /admin/([0-9]*)
# now we need to make it look like it's just the plain admin page
RewriteRule ^$ /admin [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^admin /admin/([0-9]*) [L]
you'll need to fix my reg-ex matches to make it 2 "point" 0

.htaccess mod_rewrite problem - shot myself in the foot?

I have a page called category.php5 that uses $_GET["category"] to fetch the right content from the database. I want to pretty it up so is looks like:
sinaesthesia.co.uk/category/psoriasis
which would equal:
sinaesthesia.co.uk/category.php5?category=psoriasis
I have successfully done this sort of rewriting before, but since I can't get it to work now, I'm worred that I might have rules in place that are somehow screwing me. Here is my entire .htaccess file - the last couple of lines are supposed to do the above rewrite:
RewriteEngine On
#remember to change this to aromaclear
RewriteCond %{HTTP_HOST} !^sinaesthesia\.co.uk$ [NC]
RewriteRule ^(.*)$ http://sinaesthesia.co.uk/$1 [R=301,L]
#Translate default page to root
RewriteCond %{THE_REQUEST} ^GET\ .*/index\.(php5|html)\ HTTP
RewriteRule ^(.*)index\.(php5|html)$ /$1 [R=301,L]
#translate any .html ending into .php5
RewriteRule ^(.*)\.html$ /$1\.php5
#change / for ?
RewriteRule ^(.*)\.html/(.*)$ /$1\.html?$2
#strip .html from search res page
RewriteRule ^(.*)search/(.*)$ /$1search_results\.html/search=$2
#translate product details link from search res page
RewriteRule ^products/(.*)/(.*)/(.*)$ /product_details.php5?category=$1&title=$2&id=$3 [L]
#Translate products/psorisis/chamomile-skin-cream-P[x] to productview.php5?id=1
RewriteRule ^products/.*-P([0-9]+) /productview.php5?id=$1 [L]
#Translate /category/psoriasis to /category.php5?category=$1
RewriteRule ^category/(.*) /category.php5?category=$1 [L]
When I manually enter category.php5/category=psoriasis, it works great. When I enter category.php5/category/psoriasis, it doesn't. I'm worried that my line that changes a html/ to html? is an error, however when I take that line out, it still doesn't work. Everything else works as expected.
As a general strategy, strip down your file by commenting everything out, then re-enable things piece by piece until you find the rule that causes it to break.
Bear in mind that browsers sometimes cache redirects, so starting a fresh browser instance is a good idea. A useful service is http://web-sniffer.net/ which will give you an uncached result.
In general, looking at your set of redirects, this seems a little convoluted to me because of the chaining/sieve -type system you seem to be using. Instead, I would recommend starting with URLs that can be identified specifically, e.g. starting with
RewriteRule ^category/(.*) /category.php5?category=$1 [L]
and then leaving the rather messy .html => .php conversion stuff towards the end, if you end up needing it at all. I've done a lot of sites using redirects and have never needed generic conversions like that, so they should be avoidable.
Also bear in mind that .* means matching anything or nothing, so you probably want to use .+ instead.
Ah: because I have a document called category.php5 and I'm trying to use category/psoriasis, the server tries to resolve that as category.php5/psoriasis, which fails. Fixed it now!

Resources