How to make a clean .htaccess? - .htaccess

i have problem with htaccess and not quite good at it. I want to know how to make a url clean.
Here is the original
http://site.com/page.php?p=index1/index2
and i want this type of url
http://site.com/page/index/index2
and how do i get the p value which is index1/index2 if i what to $_get it from the database?

The pattern ([^/]+) matches everything up to but not including / into $1 and the remainder is captured in (.*) into $2.
RewriteEngine On
# Don't rewrite real existing files & directories (like css,js,img)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Add .php to the first group (like page.php) and stick the rest into p
RewriteRule ^([^/]+)/(.*)$ $1.php?p=$2
Inside of PHP, retrieve the value of p via:
$_GET['p']

Related

.htaccess redirect question mark with no parameters

I have several URLs with question marks that need to be removed. For example, I need to redirect this URL:
http://example.net/?/services
To this URL:
http://example.net/services
I have many more like this, so I would like something that can catch everything with the question mark and properly redirect it. Many of the answers I found were trying to use QUERY_STRING as the condition for the rewrite, but without parameters this does not help. After some digging I found a RewiteCond that works, but the RewriteRule redirects to the homepage, rather than the URL without the question mark. What I have currently is this:
# Remove question mark from string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(index\.php)?\?([^&\ ]+)
RewriteRule ^ /%1? [L,R=301]
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
The first block is the rewrite that I have so far, and the next two are for the CMS url routing. What seems to be happening is that my rewrite in the first block is not keeping the rest of the url. I have tried several combinations and can't seem to figure out how to keep the rest of the url intact.
Many of the answers I found were trying to use QUERY_STRING as the condition for the rewrite, but without parameters this does not help.
Yes, this is exactly what the first URL, with a question mark, contains. So, I'm not sure why "this does not help"? In the URL http://example.net/?/services, /services is the query string. Whether there are key/value pairs (ie. "parameters") is irrelevant.
To redirect URLs of the form http://example.net/?/services, that consist of no URL-path and only a query string, try something like:
# Remove question mark from string
RewriteCond %{QUERY_STRING} ^/(.+)
RewriteRule ^$ /%1? [R,L]
%1 is a backreference to the captured group in the last matched CondPattern (ie. (.+), which captures services). This assumes that the query string (after the ?) always starts with a slash, as in your example. (Incidentally, this is also what your front controller is doing, in reverse, so I assume it must be correct.)
The trailing ? on the substitution removes the original query string from the request.
Make sure you clear your browser cache, as any earlier/erroneous 301s will have been cached by the browser.
If this is intended to be a permanent (301) redirect then change R to R=301, but only when you are sure it's working OK.

How to pass specific query strings in a URI using .htaccess file? (e.g. from domain.com/ce/hello-world/ce/ to domain.com/hello-world/ce/ )

I'm developing a website and have a htaccess rule as follows:
RewriteRule ^(ac|bc|cd)/(.*) $2?folder=$1 [L,QSA]
But, I want to pass all requests having /ab/ or /bc/ or /cd/ or any URI with two letters between slashes /../ right after the domain.com (i.e. domain.com/ab/, domain.com/ac/, domain.com/ad/, ...) from http://domain.com/ab/hello-world/ to http://domain.com/hello-world/, or from http://domain.com/ab/cf/hello-world/ to http://domain.com/cf/hello-world, or from http://domain.com/ce/hello-world/ce/ to http://domain.com/hello-world/ce/. Note that I only wanna pass the above query strings which appear right after .com (e.g. .com/ax/ or .com/re/, etc) not in the middle or end of the URI.
You can try this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(ac|bc|cd)/(.+) $2?folder=$1 [L,QSA]

mod_rewrite to php file unless directory exists

I have a mod_rewrite rule working to direct non-existing directories to a php file which does a database get based on the $1.
Everything works fine unless the directory does exist, which displays the proper directory, but it also appends the query string when it's not necessary.
I have been scouring the web for the past few hours and trying different methods with no luck.
Does anyone know how to keep this functioning as-is, but get rid of the query string?
Thanks much.
Here is my code:
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z\-]+)/$ $1 [R]
RewriteRule ^([0-9a-zA-Z\-]+)$ product.php?product=$1
What ends up happening is the browser displays the URL as http://domain.com/existing_dir/?product=existing_dir
try that, it removes / on its own without repeating whole process
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*?)/?$ product.php?product=$1
if You insists on limiting special characters, that would do:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9a-zA-Z\-]+?)/?$ product.php?product=$1
+ is 1 or more repeatition, * is 0 or more, and +?, *? are modifiers for not hungry matching - it allows /? to match anything
Additionally in Your example, first RewriteRule is been executed conditionally (when directory does not exists), the second one is executed always (if first whould not break the process) so even if directory exists
Mod_rewrite doesn't affect the query string, it will always be tagged on to the end of the new URL unless you tell mod_rewrite to have an empty query string. This is done by adding just a ? at the end of the new string. So the first line should look like this:
RewriteRule ^([0-9a-zA-Z\-]+)/$ $1? [R]

How do you add a second possible variable to a clean url?

I have created a htaccess rewrite code for URLs so when a user goes to myurl.com/testing/ it shows them index.php?page=testing however I would like to have a second or maybe third page so it could look like myurl.com/testing/2832/9283 and would show users index.php?page=testing&var1=2832&var2=9283.
This is the code I currently have:
RewriteRule ^([^\/]+)/([^\/]*)/$ index.php?page=$1&var1=$2
RewriteRule ^([^\/]+)/([^\/]*)$ index.php?page=$1&var1=$2
This works but I want to make the variables optional. If I do not have a second variable (i.e. just myurl.com/testing/) then it says it cant find the file.
# 3-level deep parameters
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)(/([^/]+))?(/([^/]+))?(/)?$ /index.php?page=$1&var1=$3&var2=$5 [QSA,L]
This rule will not touch already existing files and folders.
This rule will rewrite:
/help/tracking/123456/ => /index.php?page=help&var1=tracking&var2=123456
/help/tracking => /index.php?page=help&var1=tracking&var2=
/help => /index.php?page=help&var1=&var2=
You were having page=index.php because your rule rewrites already rewritten URLs (A lot of people forgetting, that when rewrite happens, it goes to next iteration and starting to test all rules again). This rule has conditions (extra checks) to ignore already existing files and folders.
Why not just set multiple RewriteRules for each case?
RewriteRule ^([^/]+)/?$ index.php?page=$1
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?page=$1&var1=$2
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?page=$1&var1=$2&var2=$3

.htacces RewriteRule not working

Hi people#stackoverflow,
Maybe I have a fundamental misconception about the working of RewriteRule. Or maybe not. Nevertheless, I'm trying to figure this out now for two days, without any progress.
This is the currrent situation:
I have a Joomla website with SEF and mod_rewrite turned on.
This results in the URL:
mysite.com/index.php?option=com_remository&Itemid=7
being rewritten to:
mysite.com/sub-directory/sub-directory/0000-Business-files/
These are the lines that are currently used in my .htaccess (all standard Joomla)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
# RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
RewriteRule (.*) index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
This is what I want to achieve:
When a visitor uses this URL
mysite.com/sub directory/sub directory/0000 Business files/
it should lead him to the right page.
Although I know it's not the best idea to use spaces in a URL, I'm confronted with the fact that these 'spacious' URL's are used in a PDF, that's already been issued.
I thought I could use mod_rewrite to rewrite these URL's. But all I get is 'page not found'
I've added this rule on top of the .htaccess file:
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
But this is not working. What am I doing wrong? Or, also possible, am I missing the point on when and how to use mod_rewrite?
rgds, Eric
First off, the default behavior of apache is usually to allow direct URLs that map to the underlying file system (relative to the document root), and you should use RewriteRule when you want to work around that. Looking at your question, it seems like you want to browse the filesystem and so you should not use a RewriteRule.
If mysite.com/sub+diretory/sub+directory/0000+Business+files/ doesn't work (without your rule), I'm wondering: do you have that directory structure on your server? I.e. does it look like this?
[document root]/index.php
[document root]/sub directory/sub directory/0000 Business files/
If not, I'm not sure I understand what you're trying to achieve, and what you mean by the visitor being "lead to the right page". Could you provide an example URL that the user provides, and the corresponding URL (or file system path) that you want the user to be served.
Regarding your rewrite rule, I'm not even sure that it is allowed, and I'm surprised you don't get a 500 Internal Server Error. RewriteRule takes two arguments (matching pattern and substitution) and optionally some flags, but because of the space between $1 and $2 you're supplying three arguments (+ flags).
EDIT: I got the pattern wrong, but it still doesn't make much sense. It matches against any URL that has at least one dash in it, and then picks out the parts before and after the first dash. So, for a URL like "this-is-a-url-path/to-a-file/on-the-server", $1 would be "this" and $2 would be "is-a-url-path/to-a-file/on-the-server". Again, if I had some example URLs and their corresponding rewrites, I could help you find the right pattern.
On a side note, spaces aren't allowed in URLs, but the browser and server probably does some work behind the scenes, allowing your PDFs to be picked up correctly.

Resources