Apache: How to rewrite some dynamic URLs - apache

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]

Related

.htaccess redirect based on a part of URL

After site crash a redirect php script doesn't work as expected.
We try to fix it, but in the meantime we are looking for a quick solution to redirect search engine results so our visitors can at least visit after clicking a relative web page.
The url structure or the search engines result are something like this:
https://www.example.com/MainCategory/SubCategory_1/SubCategory_2/Product?page=1
and I'd like to redirect using the "SubCategory_2" part of the URL to something like this
https://www.example.com/SubCategory_2.php
so until we fully repair the script at least our visitors will se a relative web page.
I'm quite stuck... Any ideas?
Thank you
To redirect the stated URL, where all parts are variable (including an entirely variable, but present query string) then you can do something like the following using mod_rewrite near the top of your root .htaccess file (or crucially, before any existing internal rewrites):
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule ^[^/]+/[^/]+/([^/]+)/[^/]+$ /$1.php [QSD,R=302,L]
The QSD flag is necessary to discard the original query string from the redirected response.
The above will redirect:
/MainCategory/SubCategory_1/SubCategory_2/Product?page=1 to /SubCategory_2.php
/foo/bar/baz/qux?something to /baz.php
You can test it here using this htaccess tester.
UPDATE:
unfortunately without success. I get 404 error.
You'll get a 404 if the directive did not match the requested URL, or /SubCategory_2.php does not exist.
Is the URL redirected? What do you see in the browser's address bar?
If there was no redirect then the above rule did not match the requested URL and the rule did nothing. Either because:
The URL format is not as stated in the question.
The rule is in the wrong place in the .htaccess file. As stated, this rule needs to be near the top of the config file.
I found a basic solution here htaccess redirect if URL contains a certain string I crate something like this RewriteRule ^(.*)SubCategory_2(.*)$ https://example.com/SubCategory_2.php[L,R=301] and works just fine. My problem is that this is a "static solution" since "SubCategory_2" is a variable.
Ok, but that is a very generic (arguably "too generic") solution for the problem you appear to be attempting to solve. This matches "SubCategory_2" anywhere in the URL-path (not just whole path segments) and preserves any query string (present on your example URL) through the redirect. So, this would not perform the stated redirect on the example URL in your question.
However, the directive you've posted (which you say "works just fine") cannot possibly work as written, at least not by itself. Ignoring the missing space (a typo I assume) before the flags argument, this would result in an endless redirect loop, since the target URL /SubCategory_2.php also matches the regex ^(.*)SubCategory_2(.*)$.
Also, should this be a 301 (permanent) redirect? You seem to imply this is a "temporary" solution?
HOWEVER, it's not technically possible to make "SubCategory_2" entirely variable in this "basic solution" and search for this variable "something" in a larger string and redirect to "something.php". How do you know that you have found the correct part of a much larger URL? You need to be more specific about what you are searching for.
In your original question you are extracting the 3rd path segment in a URL-path that consists of 4 path segments and a query string. That is a perfectly reasonable pattern, but you can't extract "something" when you don't know what or where "something" is.

Apache Rewrite Rule gives 404 Paypal IPN Redirection

I have been trying to get a rewrite rule working to redirect my old paypal IPN URL to my new one, I have tried the following in the .htaccess file and cant seem to get it to work, any help would be greatly appreciated!!
# BEGIN PayPal Fix
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^/wc-api/WC_Gateway_Paypal/
^/hosting/modules/gateways/callback/paypal.php [R=307,L]
</IfModule>
END PayPal Fix
Another thread on stackoverflow about a similar issue: Change the IPN url on existing subscription
See jon G's post about his rewrite, that is exactly what im trying to accomplish!
Thank you for any and all guidance!
There seem to be some problems with your rewrite rule.
The minor problem is that it is unusual to write such a rule in two lines. In fact, I am not sure if this is allowed in the form you use; I would expect that there would have to be at least a line continuation character. So I would put the rule into a single line first.
But the main problem is in the target of your rewrite rule. While the first part of a rewrite rule is a search pattern (regular expression), the second part (target) isn't, so you should leave away the leading ^.
Your rule then should look like this:
RewriteRule ^/wc-api/WC_Gateway_Paypal/ /hosting/modules/gateways/callback/paypal.php [R=307,L]
But I am wondering why there is no script name in your search pattern. Do you really want to map a directory to a script? Or does WC_Gateway_Paypal just appear as directory, but in fact already is mapped to a script by a rewrite rule which is evaluated before?

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?

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

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]

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!