Unable to solve .htaccess url rewriterule, gives 404 for all pages - php

I want to show URL like below examples:
1) http://www.domainname.com/detail/name/123.html
2) http://www.domainname.com/detail/124.html
In both URLs I want to show if "name" exist then want to display URL with "name" otherwise without "name".
1) RewriteRule ^detail/(.*).html$ detail.php?id=$1 [QSA]
2) RewriteRule ^detail/(.*)/(.*).html$ detail.php?id=$2 [QSA]
First rule is working file without "name". Second rule is not working and gives 404 for all pages.
Thanks in Advance.

You can use just one rule to handle both cases:
RewriteRule ^detail/(?:[^/]+/)?([^./]+)\.html$ detail.php?id=$1 [L,NC,QSA]

The problem you are having, is that the first rule matches both your first and second case. Obviously when id is name/123 your application can't handle it. What you want to do is limiting the characters to non-slash characters. After all, that means it can only match the last path segment. Besides that, force yourself to always escape literal dots in a regex. A dot matches pretty much anything if you don't do that...
RewriteRule ^detail/([^/]+)\.html$ detail.php?id=$1 [QSA,L]
RewriteRule ^detail/[^/]+/([^/]+)\.html$ detail.php?id=$1 [QSA,L]

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]

make exception for previous rule in htaccess

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]

How to implement URL rewriting two rules with the same extension?

My htaccess code:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)-([0-9]+)\.html$ post-details.php?post_id=$2 [L]
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.html$ post-details-year.php?post_year=$1&post_month=$2 [L]
The first rule is working and giving me the correct output but the second one is not; it jumped to the first rule with "post_details.php" desired "Post-details-year.php".
Additionally when I change the file extension:
Example:
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.html$ post-details-year.php?post_year=$1&post_month=$2 [L]
to
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.cgi$ post-details-year.php?post_year=$1&post_month=$2 [L]
the rewriting engine starts going over the your rules one by one until it find one that fits.
The problem was that your first rule was very powerful, and it catched URLs you didn't want it to.
When you try and access post-year-123.html, the first rule matches post-year to ([a-zA-Z0-9_-]+) part of the regex, and 123 to ([0-9]+), which then just redirects you according to the first rule.
If you switch them, and put the second rule first, it will first try to match it and will success, thus sending you to the place you want.

htaccess not reading php file

I seem to be lost in a big pile of code. I have the following piece of .htaccess code:
RewriteRule ^user/(.*)$ index.php?p=user/$1 [L]
RewriteRule ^user/(.*)/(.*)$ index.php?p=user/$1&id=$2 [L]
Now, I have a file called profile.php, inside that I use $_GET to get the ID. But when I go to /user/profile/1, it does nothing. When I go there without a ID, my script works. Can somebody help me out and tell me what I am doing wrong?
Thank you. Sorry for the confusing message.
Try these 2 rules:
RewriteRule ^user/([^/]+)/([^/]+)/?$ index.php?p=user/$1&id=$2 [L,QSA]
RewriteRule ^user/([^/]+)/?$ index.php?p=user/$1 [L,QSA]
Explanation:
Reason why your rule aren't working because your regex is wrong. You first rule ^user/(.*)$ has .* which is matching everything after /user/ hence your 2nd rule never fires and $_GET['id'] is always empty.
By changing that to [^/]+ my rule is matching only until next / is found hence both rules co-exist fine.
QSA is just nice flag to have here to preserve any existing query string.

Rewrite rule change the URL structure

I am trying to redirect my old pages to my new updated link structure pages because the old ones are now giving 404
Old
domain.com/artist-some-name
New
domain.com/artist/some_name.html
Where the - and _ between some name is put there instead of a space
So basically i want to replace the - seperator with the / which i can with
RewriteRule ^artist-(.+)$ /artist/$1.html [R=301,L]
But i can't work out how i can change the some-name to some_name so it will redirect properly
EDIT
RewriteRule ^artists-(.+)-(.+)$ /artist/$1_$2.html [R=301,L]
RewriteRule ^artists-(.+)$ /artist/$1.html [R=301,L]
Seems like this works for both if spaces in url or not
RewriteRule ^artist-(.+)-(.+)$ /artist/$1_$2.html [R=301,L]
Give these a try:
RewriteRule ^artist-([a-z]+)-([a-z]+)$ /artist/$1_$2.html [NC,R=301,L]
RewriteRule ^artist-([a-z]+)$ /artist/$1.html [NC,R=301,L]
You need to limit the wild cards so that only letters are included. If you need to include numbers ('digits' in regex), then you can add 0-9 just next to the a-z. Alternatively, you can use \d+, for short.

Categories