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]
Related
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]
I have the following htaccess rule
RewriteRule ^([a-zA-Z-_0-9]+)/([a-zA-Z-_0-9]+)$ ?page=$1&action=$2 [L]
For example if I want to add something or edit something the url will be like:
www.website.com/page_name/add
And that rule is applicable for all pages except for one page named portfolio.. for this page I want first to get a category value and than add or edit stuffs.
I tried under the first rule to put this rule:
RewriteRule ^portfolio/([a-zA-Z-_0-9]+)$ ?page=portfolio&category=$1 [L]
To get a link like that:
www.website.com/portfolio/demos
Or
www.website.com/portfolio/desings
But always the first rule that works (consider the 2nd parameter like an action and not like an category).
Any idea for make exception for that specific page to treat what comes after like an "cat" and not like an "action"?
The L flag in HTACCESS tells Apache to ignore anything after that rule if the pattern is a match (which it is in your example).
Swap the rules around:
RewriteRule ^portfolio/([a-zA-Z-_0-9]+)$ ?page=???&category=$1 [L]
RewriteRule ^([a-zA-Z-_0-9]+)/([a-zA-Z-_0-9]+)$ ?page=$1&action=$2 [L]
Also, notice that in the first rule, there is no second parameter (since there's only one pattern), so I'm not sure where you intend to send the user...
First exclude portifilio from first rule so , replace this line :
RewriteCond %{REQUEST_URI} !^/portfolio
RewriteRule ^([a-zA-Z-_0-9]+)/([a-zA-Z-_0-9]+)$ ?page=$1&action=$2 [L]
Also in this rule :
RewriteRule ^portfolio/([a-zA-Z-_0-9]+)$ ?page=$1&category=$2 [L]
you will be able match against the number only not page name , it should be like this :
RewriteRule ^portfolio/([a-zA-Z-_0-9]+)$ ?page=portfolio&category=$1 [L]
OR
RewriteRule ^(whatever)/([a-zA-Z-_0-9]+)$ ?page=$1&category=$2 [L]
This is the full set of rewrite code in my htaccess file, but I'm only having problems with a conflict in the last 3 rules. The final rule writes the URL I want, but returns travel.php instead of travel2.php
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{http_host} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^journal/([^/]*)$ /journal2.php?url=$1 [L]
RewriteRule ^travel/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel.php?country=$1&url_string=$2
RewriteRule ^travel/([a-zA-Z0-9-]*)$ /travel2.php?cat=$1
RewriteRule ^travel/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel2.php?cat=$1&subcat=$2
This is what I'm after from those last 3:
/travel/country/title-url-string (currently works & displays correct content)
/travel/category (currently works & displays correct content)
/travel/category/subcat (currently displays URL as I want it, but returns travel.php content instead of travel2.php)
I originally had an ID number in the travel.php rule, and removing that has resulted in the conflict. I'm aware two of the rules have the same pattern, so how can I best go about getting the results I want? Thanks for any help. :)
From last 3 rewrite rules:
1 & 3 check the same pattern where first one always take effect.
Further, as your category and country values cannot be distinguished each other here, I would suggest to append a unique identifier to the url as below:
RewriteRule ^travel/country-([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel.php?country=$1&url_string=$2
RewriteRule ^travel/category-([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel2.php?cat=$1&subcat=$2
So your matching urls would be:
/travel/country-countryname/title-url-string
/travel/category-categoryname/subcat
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).
On my website I am trying to rewrite a long URL to a SEO friendly one.
I've got the following code, but it doesnt seem to affect anything! However if I type dgadgdfsg into my htaccess, it throws an internal server error. So I am presuming it is something with Rewrite Rule.
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [L]
I have confirmed that mod_rewrite is on.
This is the current URL
http://mysite.com/missing-people/user-profile.php?userID=1&firstName=Liam&lastName=Gallagher
and this is what I want it too appear like
http://mysite.com/1/Liam/Gallagher
Change your RewriteRule to this (slightly modified from your version)
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [QSA,L]
If that doesn't work try putting a R flag for testing purpose (which will make your browser change the original URI to: /missing-people/user-profile.php?userID=1&firstName=Liam&lastName=Gallagher
Presuming your userID is comprised only of digits and firstName and lastName are only alphanumeric.
RewriteEngine On
RewriteRule /(\d+)/(\w+)/(\w+)/ /missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [L]
A more strict version that does the same thing except it sets boundaries for the beginning and the end of the evaluated regex.
RewriteEngine On
RewriteRule /^(\d+)\/(\w+)\/(\w+)$/ /missing-people/user-profile.php?userID=$1&firstName=$2&lastName=$3 [L]