simple mod_rewrite q...is the solution simple too? - apache

I've looked at many examples here and all over the internet, but I can't seem to find an answer I understand, or that accurately solves my problem. I'm looking to implement a mod_rewrite directive in an .htaccess file that renames a folder to another name but does not show the name in the url bar.
For example (the user clicks a link that directs them to):
theSite.com/folder1/folder2/folder3/
I want them to see (same as above)
theSite.com/folder1/folder2/folder3/
But I want the browser to silently function in this directory
theSite.com/folder1/some_other_folder/folder3/
I am a PHP developer, writing my first web application. I can configure apache, PHP, mysql and use them like a pro. I'm sorry, but I don't understand the syntax for mod_rewrite. I can't seem to grasp it despite looking at many tutorials as I would need to ask questions before I could move onto the next concept. Thank you for your patience.

Your case is pretty run-of-the-mill. You just need to match the static string, plus a (.*) to match everything that follows it and store it into $1, then substitue some_other_folder.
The [L] flag (and absence of the [R] flag) instructs Apache to rewrite internally without redirecting the browser, and to stop here without matching further rules.
RewriteEngine On
RewriteRule ^folder1/folder2/folder3(.*)$ folder1/some_other_folder/folder3$1 [L]
If folder3 itself is part of the "dynamic" portion, that is, anything after folder2 should be silently rewritten into some_other_folder, leave folder3 out of the rule and just capture everything that follows folder2 into $1.
RewriteEngine On
RewriteRule ^folder1/folder2/(.*)$ folder1/some_other_folder/$1 [L]

I would use following
RewriteRule /folder1/folder2/folder3/ /folder1/some_other_folder/folder3/ [L]

Related

rewrite rule to forward old search to new search

I've search for a few hours now but I can't figure out a solution.
I just put up a new website that has a different search url than the old site. I'm trying to capture the search queries pointed at the old site and send them to the new sites search.
such as:
advanced_search_result.php?search_in_description=1&keywords=alternator
redirecting to the new sites search like:
index.php?route=product/search&search=alternator
I've tried variations of the following without any luck.
RewriteRule ^advanced_search_result\.php?.*keywords=(.*)$ index.php?route=product/search&search=$1 [R=301,L]
any help would be appreciated.
Your issue is that you are trying to map a pattern including the query string which is not possible with a RewriteRule. That is clearly documented. You need to use a RewriteCond for that:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(?:[^&]*&)*keywords=([^\&]*)
RewriteRule ^/?advanced_search_result\.php$ /index.php?route=product/search&search=%1 [R=301,L]
Reason is that in a RewriteRule the pattern is only matched against the path component of the request URL. The query string is not part of that. Matching against the query string is only possible in a RewriteCond using the %{QUERY_STRING} variable, since such a condition can test an arbitrary string against some pattern, not only the path component of the URL. Tokens captured inside such a condition can then be cited by a %1 in a following RewriteRule, as opposed to the $1 which refers to a capture for that rule itself.
The details are explained in the official documentation of the rewriting module which is something you should always consult when working on rewriting or redirection rules. It is very well written and comes with good examples.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Rewrite query string into part of the URL file name?

I have a php site and the URLs are displayed as follow:
http://www.example.com/cheap-call-single.php?country=ALBANIA
I want to re-write it, to display as:
http://www.example.com/cheap-international-calls-ALBANIA.php
I have searched many only generators and they all say to use:
RewriteEngine On
RewriteRule ^cheap-international-calls-([^/]*)\.php$ /cheap-call-single.php?country=$1 [L]
But this is not working for me, please note that the server has the correct Apache setting enabled.
Can someone please help me with the correct syntax?
The rewriteRule you show does the inverse, it takes incoming url in the long form and translate it to the query string version (with ?).
Now the problem is what do you mean when you say: "I want to re-write it, to display as:"
The display and the rewrite are usually different things:
If the 'display' is the url seen by the user in his browser you have :
to push this way of writing urls in your application, so that the received HTML contains the right display, this has nothing to do with mod_rewrite
you may optionally perform HTTP redirections with mod_rewrite, so when you detect the old syntax (cheap-call-single.php?country=ALBANIA) you redirect the user on the right one, then the request is re-executed by the browser (and then you should have a cheap-international-calls-ALBANIA.php file on your server, else it's a final 404)
If you do not have this file on the server (so, what you have is cheap-call-single.php) then the exposed rewriteRule is right and back to step one, it's your application which should show the right url on the HTML side.
Now if your really have cheap-international-calls-ALBANIA.php and you want your application to rewrite incoming request using cheap-call-single.php to this file, based on query string parameters, you'll have some problems. Writing rules on the query string part of the request is always complex, query string arguments may appear in any order, may be written with urlencoding or not, etc. By default rewriteRules are not using the query string part.
This is something like:
RewriteCond %{REQUEST_FILENAME} cheap-call-single\.php [NC]
RewriteCond %{QUERY_STRING} (^|&|%26|%20)country(=|%3D)([^&]+) [NC]
RewriteRule .* /cheap-international-calls-%3.php [L,R]
Untested (not sure for the \.), and yet not managing the fact each letter in the country word would be urlencoded, and not managing the upcase of the country name. You would need a RewriteMap to transform it uppercase. But already have my headache, is this what you really need?

mod_rewrite on parent and subfolder

I ran into some strange behaviour using mod_rewrite under Apache. Here's how the current RewriteRules look:
RewriteRule ^(.*)/collections/(.*)/(.*)/?$ bootstrap.php?controller=category&user=$1&collection=$2&category=$3 [L]
RewriteRule ^(.*)/collections/(.*)/?$ bootstrap.php?controller=collection&user=$1&collection=$2 [L]
My expectations of the above rules is that accessing a URL such as domain.com/BenM/collections/0/1/ should take me to the category controller, while domain.com/BenM/collections/0/ should take me to the collection controller.
At the moment, both URL structures rewrite to bootstrap.php?controller=category....
My understanding was that if the [L] flag is specified, Apache looks no further and performs the rewrite.
Could anyone point in the right direction here, as I just cannot beat this... What should the rewrites look like to achieve the functionality I explained above?
You're dealing with greediness-related issues. Also, you probably want a length of at least one, and you almost certainly don't want slashes in your params.
Potential solution:
^([^/]+)/collections/([^/]+)/([^/]+)/?$
^([^/]+)/collections/([^/]+)/?$

Apache: How to rewrite some dynamic URLs

I need to rewrite some specific URL's on my website but cannot find out how to do it despite searching for quite some time.
The original url that needs to be matched is in this format:
http://www.example.com/gallery/?level=picture&id=49
and I need them to be in this format:
http://www.example.com/index.php?page=gallery&level=picture&id=49
However, the folder also contains some image files as well. I need any URL's pointing directly to images to be left alone, and any URL's pointing to a php page to be rewritten as above.
I know what I want to do, but not how to do it. Basically I need to do this in .htaccess:
if(url contains 'gallery/' AND filetype != bmp/jpg/png/etc){
REPLACE '/gallery/' WITH '/index.php?page=gallery&' AND append original query string variables
}
Any help at all would be greatly appreciated.
So I have found a solution that has taken care of this problem for me. I have this working in my .htaccess file now.
RewriteCond %{REQUEST_URI} !\.(bmp|jpg|jpeg|png|gif)$
RewriteRule ^gallery/$ /index.php?page=gallery [R=302,QSA]
The first line (from what I have been told) excludes the file types listed from being affected by this rule, because as I originally mentioned I did not want the URL rewritten for images.
The second line takes a url like this:
http://www.yoursite.com/gallery/?level=picture&id=52
and turns it in to this:
http://www.yoursite.com/index.php?page=gallery&level=picture&id=52
and it leaves the original query string in place, in addition to the new "page=gallery" variable. It also does a 302 redirect so that the user is shown the correct address in their browser.
Not sure if this is helpful to anyone, but figured that since I posted asking about it, that I would post the solution I found as well.
This may a bit more general than you want, but it'll also avoid rewriting other existing files.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^/gallery/(.+)$ index.php [QSA]

Creating rewrite rules for multiple urls in the same folder

I have been asked by our client to convert a site we created into SEO friendly url format. I've managed to crack a small way into this, but have hit a problem with having the same urls in the same folder.
I am trying to rewrite the following urls,
/review/index.php?cid=intercasino
/review/submit.php?cid=intercasino
/review/index.php?cid=intercasino&page=2#reviews
I would like to get them to,
/review/intercasino
/submit-review/intercasino
/review/intercasino/2#reviews
I've almost got it working using the following rule,
RewriteRule (submit-review)/(.*)$ review/submit.php?cid=$2 [L]
RewriteRule (^review)/(.*) review/index.php?cid=$2
The problem, you may already see, is that /submit-review rewrites to /review, which in turn gets rewritten to index.php, thus my review submission page is lost in place of my index page. I figured that putting [L] would prevent the second rule being called, but it seems that it rewrites both urls in two seperate passes. I've also tried [QSE], and [S=1]
I would rather not have to move my files into different folders to get the rewriting to work, as that just seems too much like bad practise. If anyone could give me some pointers on how to differentiate between these similar urls that would be great!
Thanks
(Ref: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html)
What I would do, is make /submit-review/ post directly to itself (or a php file) then once submitted redirect from within the PHP file.
It can be hard to force htaccess to maintain post values whilst redirecting etc
My friend found a solution to this one.
RewriteRule review/submit.php - [L]
Will catch the first rewrite and then prevent the next one, worked a treat!