HTACCESS | Adding a second rewrite rule? - php

I'm trying to write my .htaccess to support two vanity url's, the code will speak for itself as I'm not very good with .htaccess.
RewriteRule ^([a-zA-Z0-9-]+)/?$ index.php?p=$1&s=$2 [L,QSA]
Upon going to for example http://website.com/home/test
I get a 404, but $_GET["p"] still returns back home if I go to just website.com/home.
Why am I getting a 404 when adding in my second variable in the url?

You get a 404 because /home/test does not match the expression ^[a-zA-Z0-9]+/?$. The second group after the first / exists beyond your $ string terminator. You need to add a second () group, which is optional. I have replaced the a-zA-Z0-9 character classes with [^/]+ which matches everything up to the next slash.
The (?:) indicates a non-capturing group encompasing the first /, with a capturing group () inside it to retrieve the $2 component. The entire construct is made optional with ? before the final $ terminator.
RewriteEngine On
RewriteRule ^([^/]+)(?:/([^/]+)/?)?$ index.php?p=$1&s=$2 [L,QSA]

Related

Decipher this .htaccess line

# Redirect all users to access the site WITH the 'www.' prefix
RewriteCond %{HTTP_HOST} !^www\. [NC]
**RewriteCond %{HTTP_HOST} !\.([a-z-]+\.[a-z]{2,6})$ [NC]**
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Ok, so in the above code I think the 1st line says "if the URL does not have www." and then the 3rd line says to "rewrite the URL with the www. as a 301 redirect", but the 2nd line I believe is to take into consideration subdomains and exclude them, but can anyone tell me what this !\.([a-z-]+\.[a-z]{2,6})$says exactly?
Another question: if mod_rewrite is enabled do I still need to add RewriteEngine Onto the top of the .htaccess file? What happens if I don't?
The regular expression on the second line matches, if the string:
! does not have
\. a literal dot, followed by
[a-z-] multiple characters of the a-z,- range, followed by
\. another literal dot, followed by
[a-z]{2,6} between 2 and 6 characters from the a-z range
$ before the end of the string
The parenthesis "(..)" allow capturing of a matched substring.
This can then be used in following expression/substitutions.
The NC flag will cause the match to performed case-insensitive.
In your case this will trigger a rewrite if the incoming URL
does not start with www. (1st line)
does not end with sth that looks like .hostname.tld (2nd line)
See https://regex101.com/ for a good playground to experiment with regular expressions.

Capturing encoded slashes and Ignoring unencoded slashes

I have a web application that recently had its spec changed to allow for slashes in names of some of its documents. Resultantly, I have had to change my .htaccess file to also match slashes. However, the issue is that I only want to match slashes that are encoded i.e. catch %2F but not /.
Consider the following URL:
http://www.example.com/document/edit/STAT%2F12/
My .htaccess looks like:
RewriteRule ^document\/([a-z0-9-]+)?\/?([a-z0-9-\W\s]+)?\/?$ documents.php?request=$1&id=$2& [NC,QSA,L]
The above request catches the $id as 'STAT/12/' instead of 'STAT/12'. In other words, it matches the trailing slash even though it isn't encoded.
Please note, I have switched on AllowEncodedSlashes On.
That's because the section of your regexp [a-z0-9-\W\s] is catching the slash. If Apache supports it, use a non-greedy capture, or use a different character class.
RewriteRule ^document\/([a-z0-9-]+)?\/?([a-z0-9-\W\s]+?)?\/?$ documents.php?request=$1&id=$2& [NC,QSA,L]
Non-greedy or lazy capture is the ? after the + and will capture as few characters as possible, so it stops before the trailing /.
https://regex101.com/r/uK8zM3/1
The URL encoded stuff will arrive at your server encoded, so if all you need is to capture %2F where you weren't before, just allow % in addition to whatever worked previously. Your character class above allows whitespace for example, I don't think you want to be doing that in a URL!

How can i create better urls using .htacces modrewrite

This are my urls right nowm for my products
http://www.example.com/product.php?product=32723
I want to achieve this
http://www.example.com/product/32723-brand-model-productname
I have been modifying my .htaccess but really with no clue on how to achieve this.
You must match your URL with a RewriteRule pattern and rewrite it to the target URL
RewriteRule ^/product/(\d+)- /product.php?product=$1
This pattern matches any URL starting with /product/ and captures the following digits (\d+) followed by a dash -. The substitution URL will be /product.php?product= with the captured digits $1 appended.
To capture some part of the match, you enclose it in parenthesis (...). Read more on regular expressions used in mod_rewrite at Apache mod_rewrite Introduction - Regular Expressions.
This question is so common I just put up the whole answer with code here:
http://www.prescia.net/bb/coding/5-141018-simple_friendly-url

Delimiters and multiple parameters

I'm trying to use the mod_rewrite module to create smooth URLs. So for example my example.com/pages/group/index.php?id=1&slug=example-keyword would become example.com/group/1-example-keyword.
The problem I'm having is with the second parameter and how it is split. As the second parameter uses dashes how could I fix this as at the moment it throws 404 errors.
.htaccess rule
RewriteRule ^group/([^-]*)-([^-]*)$ /pages/group/index.php?id=$1&slug=$2 [L]
Your regular expression explicitly prohibits dashes in the first and second groups.
Try this using . (any character) instead of [^-] (any character except -) in your second group:
RewriteRule ^group/([^-]*)-(.*)$ /pages/group/index.php?id=$1&slug=$2 [L]
In this expression, everything after group/ but before the first - will be captured in group 1, and everything after the first - will be captured in group 2.

Using .htaccess to make fancy URLs with a wide variety of characters

I'm wanting to make a URL look pleasing to the eye.
from
/index.php?a=grapes
to
/grapes
Although, I'm having a few problems. I wanted a to have a wider variety of characters like a-z A-Z 0-9 / _ - . [ ].
from
/index.php?a=Grapes.Are.Green/Red[W4t3r-M3l0n_B1G_Gr4p3]
to
/Grapes.Are.Green/Red[W4t3r-M3l0n_B1G_Gr4p3]
In the index.php file I have
<?php
$a = $_GET["a"];
echo $a;
?>
just to test the URL is working correctly.
Right now what I have in .htaccess
RewriteEngine On
RewriteRule ^([a-zA-Z0-9/_]+)?$ index.php?a=$1
only accepts a-z A-Z 0-9 / _.
If I add - into the square brackets and have it as one of the
characters which a equals I get the 404 error.
If I add . into the square brackets I get index.php outputted.
If I add [ or ] I get the 404 error.
If anyone has a solution I'd love to see it. Also, if anyone has time please could you explain each part of the RewriteRule saying what the part does. Thanks!
The problem is that some of your character are "special":
Special characters:
(full stop) - match any character
* (asterix) - match zero or more of the previous symbol
+ (plus) - match one or more of the previous symbol
? (question) - match zero or one of the previous symbol
\? (backslash-something) - match special characters
^ (caret) - match the start of a string
$ (dollar) - match the end of a string
[set] - match any one of the symbols inside the square braces.
(pattern) - grouping, remember what the pattern matched as a special variable
So if you want to use them in a url, you have to scape them.
For example
.s?html? matches ".htm", ".shtm", ".html" or ".shtml"
RewriteEngine On
RewriteRule ^(.*)$ index.php?a=$1 [QSA]
The [QSA] thing at the end is what made it work :) Thanks to jedwards for suggesting to use ^(.*)$ which accepts all characters.

Categories