URL rewrite php query strings - php

I have two urls doing some queries which I'm struggling to rewrite in the manner I want.
First
/shop/index.php?category=catslug
which I want to be
/shop/category
Second
/shop/index.php?product=slug
to
/shop/category/product
I have this currently:
RewriteRule ^shop/([A-Za-z0-9-]+)/?$ shop/index.php?category=$1 [L]
RewriteRule ^shop/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ shop/index.php?product=$1 [NC,L]
The problem is that one of the rules is ruining anything that starts with shop so that things like shop/cart doesn't work. I'm so confused. Is this possible?

Note that for shop/cart, the cart part matches the [A-Za-z0-9-]+ part of the first RewriteRule. So it is rewritten to shop/index.php?category=cart.
The way to avoid this, hoping that you have a relatively small number of fixed URLs, is to have a RewriteRule before your 2 rules like
RewriteRule ^shop/(cart|this|that|other|thing) - [L]
RewriteRule ^shop/([A-Za-z0-9-]+)/?$ shop/index.php?category=$1 [L]
RewriteRule ^shop/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ shop/index.php?product=$1 [NC,L]
For requests matching one of the pipe-delimited strings (such as cart), - means don't change the request, and [L] means last (don't continue to the next rules).

Related

.HTACCESS adding to slugs

So, I'm currently building a REST API in PHP.
I managed to get slugs working for the most part.
If I request /api/admin/v1/users/1, it will return the user I need.
However, I also need to be able to add to it, e.g. /api/admin/v1/users/1/keys.
The HTACCESS file managing the slug is in the folder itself (/users/).
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [L]
I tried adding another line, but I think I messed up (I'm not that advanced with HTACCESS)
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
This didn't do anything, it still returns the user object.
RewriteRule ^(.*)$ user.php?slug=$1 [L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
The first rule matches everything, so the second rule is never processed. But since the first rule matches everything it will also rewrite itself (to user.php?slug=user.php) on the second pass by the rewrite engine.
You can resolve these issues by making the regex more restrictive. From your example URL it looks like the slug is numeric - in which case you can restrict the regex to match digits (0-9) only.
For example:
RewriteRule ^(\d*)$ user.php?slug=$1 [L]
RewriteRule ^(\d+)/keys$ keys.php?slug=$1 [L]
Note that the first rule also matches an empty URL-path, ie. no slug at all (as does your original rule). The second rule does not permit an empty slug (it would never match anyway).
The second rule don't work because the L flag stay for: last - stop processing rules
So you need to edit to:
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [QSA, L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [QSA, L]

htaccess 3 different urls in one php file

I have 3 step in one php file:
This is my htacess now:
RewriteRule ^igra/(.*)$ "/index.php?page=igra&id=$1"
RewriteRule ^igra/(.*)/sezona/(.*)$ "/index.php?page=igra&id=$1&season=$2"
RewriteRule ^igra/(.*)/sezona/(.*)/liga/(.*)$ "/index.php?page=igra&id=$1&season=$2&league=$3"
When i go in browser something like index.php?page=igra&id=$1 or index.php?page=igra&id=$1&season=$2 or index.php?page=igra&id=$1&season=$2&league=$3 sure with real values it works fine, but when i try to access with this pretty links it always show me the first rewrite rule..
I hope u understand me what i need here, best regards..
Your first rule is capturing everything, so the subsequent rules never get executed. Just switch them around:
RewriteRule ^igra/(.*)/sezona/(.*)/liga/(.*)$ /index.php?page=igra&id=$1&season=$2&league=$3 [L]
RewriteRule ^igra/(.*)/sezona/(.*)$ /index.php?page=igra&id=$1&season=$2 [L]
RewriteRule ^igra/(.*)$ /index.php?page=igra&id=$1 [L]
Notice also the addition of the L flag.

.htaccess ReWrites cancelling each other out ... Any Ideas?

I have a couple of rules in my .htaccess file in order to make the URLs a bit cleaner, however, they seem to be cancelling each other out.
The first rule is just to remove the .php from page names,
example : mysite.com/join rather than mysite.com/join.php
RewriteEngine On
Rewrite Condition : %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
The second rule is to make it easier for Users to share their profiles on my site,
example : mysite.com/user1 rather than the actual URL mysite.com/profile.php?user=user1
RewriteRule ^([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]
I've been playing round with them, and they essentially cancel each other out - Any ideas on how I can get them both working?
Thanks
The problem you have is that both conditions are almost identical i.e. anything that ^([_A-Z0-9a-z-+]+)$ matches will also be matched by ^([^.]+)$, so someone accessing mysite.com/user1 will get redirected to mysite.com/user1.php since that is the first rule that is encountered, and it has the L flag to prevent processing more rules. To prevent this happening you need to make the rules different, e.g. perhaps require user pages to be mysite.com/users/user1? Then you could write the rules as
RewriteRule ^([^./]+)$ $1.php [NC,L]
RewriteRule ^users/([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]
Note that you need to add / to the characters not to be matched in the first rule, otherwise it will still match mysite.com/users/user1.
Edit
A couple of other alternatives:
If you were willing to have actions (e.g. join) use URLs such as mysite.com/action/join then you could keep users at the top level e.g.
RewriteRule ^action/([^.]+)$ $1.php [NC,L]
RewriteRule ^([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]
Or if you know the names of all your actions you could put them in an alternation (this would require that you couldn't have a user called e.g. join):
RewriteRule ^(join|login|logout|delete)$ $1.php [NC,L]
RewriteRule ^([_A-Z0-9a-z-+]+)$ profile.php?user=$1 [S=1]

Htaccess rewriting URL - multiple levels

This is probably a duplicate, I'm sorry in advance.
I'm having a bit of a thick moment and need some help with a rewrite rule:
RewriteRule ^([a-zA-Z0-9_-]+)/?$ /index.php?name=$1 [L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)?$ /index.php?name=$2 [L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)?$ /index.php?name=$3 [L]
This is currently how we rewrite one of our sites - until we had a bug with 4 levels E.g. /about/company/people/dean.
I could just add another rule to rewrite the 4th level to the index page - but is there a nice way of doing this?
Basically, the overall result - when a url of type '/a/b/c/d/e/f/g' is requested, it will rewrite to '/index.php?name=g' - or whatever is the last element in the url.
Stick to the end of string anchor. It should catch the last chunk after /:
RewriteRule .*/([a-zA-Z0-9_-]+)/?$ /index.php?name=$1 [L]

Reoccurring htaccess command

I need to continue this indefinatly in length without writing it out everytime.
Is there a way to achieve this?
RewriteRule ^(\w+)/?$ index.php?page=$1 [QSA]
RewriteRule ^(\w+)/(\w+)/?$ index.php?page=$1&$1=$2 [QSA,L]
RewriteRule ^(\w+)/(\w+)/(\w+)/?$ index.php?page=$1&$1=$2&$2=$3 [QSA,L]
So all the way through $1=$2 then $2=$3 so page=blog&blog=article&article=date&date=2012
My PHP then takes this and runs analysis on this. So could be as as $1 -> $11 Long URL I know means that I can still enable adding.
AAA.com/blog/article/date/2012/?colour=blue
Not as such. To get an replacement $5 placeholder, you do need a match group.
One could of course optionalize it group-wise:
RewriteRule ^(\w+)(?:/(\w+))?(?:/(\w+))?(?:/(\w+))?(?:/(\w+))?(?:/(\w+))?(?:/(\w+))?/?$ index.php?page=$1&$1=$2&$2=$3&$3=$4&$4=$5&$5=$6 [QSA,L]
But then you had a few &=&=&= trailing for absent entries. Usually it should result in an empty $_GET[""], but PHP even ignores that. So, might be an option. I don't feel it's a more readable or concise RewriteRule though.

Categories