Apache mod rewrite .htaccess to get params - apache

How can i catch the prams after file name with extension like service.php/view1
for ex:
service.php/newview1
I want to get it like
service.php?view=newview1
how do i write mod-rewrite for this
I tried like
RewriteRule ^services.php/?([a-zA-Z_]+)$ /services.php?category=$1
its not matching the service.php/newview1

When the replacement URI contains a query string, the default behavior
of RewriteRule is to discard the existing query string, and replace it
with the newly generated one. Using the [QSA] flag causes the query
strings to be combined.
You need to add [QSA] flag to end of your current line
Try adding this regex:
([a-zA-Z0-9-_]+) as this also matches any integers and hyphens also.
RewriteRule ^services.php/?([a-zA-Z0-9-_]+)$ /services.php?category=$1 [QSA,L]
I also put the [L] flag so it stop processing further rules.

Related

mod_rewrite regex to match root level whole name page

I'm want to rewrite many pages following the simple schema:
old_page.php to content/new-page.php
I got a problem when apple.php must be rewritten to fruits/red-apple.php because I get into a rewriting loop, so i have to match domain/apple.php
I'm not sure if I can set up RewriteRule or I'll also need rewriteCond ..
You should show us what you're working with, but it sounds like your patterns are simply missing start and end of string anchors. E.g.:
RewriteBase /
RewriteRule ^apple\.php$ fruits/red-apple.php [NS,L]
You may be better off using RewriteMap if you have a lot of rules.

modrewrite alter 1 element of query string

Flash movies are called based on dynamic links on mypage.php. mypage.php has the flash player embedded. The links look like mypage.php?moviefolder=folder1/folder2&swfTitle=sometitle.swf. mypage.php is parsed on each link click (per the href). Folder2 is always the same but movieTitle.swf is dynamic. Sometimes subfolders will be called (folder2/subfolder2/sometitle.swf).
Can mod_rewrite allow the query string to reflect folder2 but instead silently serve folder3 as well as occasional subfolders? I would place all files in folder3. The goal is to have the user not know where the swfs are. Thanks in advance again!
Using a RewriteCond to match the contents of the query string (since they are not read in a RewriteRule directive, you can extract swfTitle=sometitle.swf and substitute folder1/folder3 for folder1/folder2 in the moviefolder.
This will use a regex pattern like ([^&]+) to match everything up to the next & (which denotes another query param).
# Capture everything after folder2 into %1
RewriteCond %{QUERY_STRING} moviefolder=folder1/folder2([^&]+) [NC]
# Capture everything in the swfTitle param into %2
# Both conditions must be matched...
RewriteCond %{QUERY_STRING} swfTitle=([^&]+) [NC]
# Then silently rewrite mypage.php to substitute folder3,
# and pass in the original swfTitle captured above
RewriteRule ^mypage\.php$ mypage.php?moviefolder=folder1/folder3%1&swfTitle=%2 [L]
Hopefully, you won't get a rewrite loop, since the rewritten folder1/folder3 won't match the second time. [NC] allows for a case-insensitive match.
I did manage to successfully test this over at http://htaccess.madewithlove.be/, using the sample input:
http://example.com/mypage.php?swfTitle=thetitle.swf&moviefolder=folder1/folder2/thing
---> http://example.com/mypage.php?moviefolder=folder1/folder3/thing&swfTitle=thetitle.swf
http://example.com/mypage.php?moviefolder=folder1/folder2/thing999zzz&swfTitle=thetitle.swf
---> http://example.com/mypage.php?moviefolder=folder1/folder3/thing999zzz&swfTitle=thetitle.swf

Handling '?' in mod_rewrite

I have a page that asks a user to confirm if he wants to continue or cancel and I use a rewrite rule for it:
RewriteRule ^click/(.+)$ aclick.php?url=$1 [B]
The problem arises when the URL has a question mark. For example:
http://example.com/click/yahoo.com/mobile/?s=ladygaga
My goal is that this URL be re-written as:
http://example.com/aclick.php?url=yahoo.com/mobile/%3fs=ladygaga
So that the continue button will proceed to: 'http://yahoo.com/mobile/?s=ladygaga'
However, the continue button is just linked to 'http://yahoo.com/mobile/'.
Does anyone have an idea to fix this?
Use %{QUERY_STRING} as follows. You have to refer REDIRECT_QUERY_STRING instead of QUERY_STRING.
RewriteRule ^click/(.+) aclick.php?url=$1?%{QUERY_STRING} [B,L]
B flag will escape the string excessively. If you access http://example.com/click/yahoo.com/mobile/?s=ladygaga, the query string will be url=yahoo%2ecom%2fmobile%2f?s=ladygaga. (It does not cause bad influence.)
In case that URL have no query string, redundant "?" is added to the end of query string. To prevent this, use RewriteCond:
# If URL have any query string, then
RewriteCond %{QUERY_STRING} .
RewriteRule ^click/(.+) aclick.php?url=$1?%{QUERY_STRING} [B,L]
# otherwise,
RewriteRule ^click/(.+) aclick.php?url=$1
You can simply written as follows:
RewriteRule ^click/(.+) aclick.php
Program aclick.php can refer environment variables REQUEST_URI, REDIRECT_URL, QUERY_STRING etc.

Apache RewriteRule with RewriteMap

I've got a RewriteMap that looks like this:
Guide 1
Mini-Guide 2
White Paper 3
and I'm including it into Apache via
RewriteMap legacy txt:/var/www/site/var/rewrite_map.txt
I want to create a RewriteRule that will allow only values from the left side of said RewriteMap to be in this position;
RewriteRule ^/section/downloads/(${legacy})/(.*)$ /blah.php?subsection=${legacy:%1}&title=$2
I know I can use ${legacy} on the right side, but can I use it on the left, and if so, how?
In your map file, the left side is the key and the right side is the value. When you create a rule for matching against a map, you input the key and it outputs the value.
Change your RewriteRule to this:
# Put these on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1}&title=$2
The first grouping captures the string in the incoming URL. The $1 in the replacement applies it to the named map. To make a default value, change ${legacy:$1} to ${legacy:$1|Unknown}.
Finally, if you only want the rule to work on values that are in the map file, add a RewriteCond:
RewriteCond ${legacy:$1|Unknown} !Unknown
# Put these on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1}&title=$2
The condition says if the map does not return the default value (Unknown), then run the next rule. Otherwise, skip the rule and move on.
Apache RewriteMap
another variant:
# %1 will be the subpattern number1 afterwards
RewriteCond %{REQUEST_URI} ^/section/downloads/(.*)
# check if there is no mapping for %1
RewriteCond ${legacy:%1} !^$
# if there is rewrite it
RewriteRule ^/(.*) /blah.php?subsection=${legacy:%1}&title=$2 [R]
You said, you want to only allow values found in the map. This isn't possible unless you specify an additional restriction in regex for the capture group. There's no way to do it with the map itself. There's no "map.keys" syntax, as far as I know, that you can apply in the left hand side, the pattern.
BUT,
You can specify a default value if the captured value is not found. This way:
## all on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1|defaultValue}&title=$2
Replace "defaultValue" with whatever you like. For example 0 (zero), or "notfound", if the given arg is not found in the map.
You can then either rewrite the result of that, with another rule, or just allow it to flow through and provide a "404" message at the URL with the default value.
If you choose to use another rule, then it would look like this:
## all on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1|notFoundMarker}&title=$2
## This rule fires if the lookupKey was not found in the map in the prior rule.
RewriteRule ^/blah.php?subsection=notFoundMarker /404.php [L]

Apache mod_rewrite and PHP ?argument=something

I'm trying to get all HTML and PHP files on my site to redirect through the index.php, so that they can have common frames applied to them, a templating solution I coded that I found to be quite elegant. Anywho, I'm having issues with my PHP files, specifically those that have arguments after them.
My regular rule for PHP files is the following:
RewriteCond %{REQUEST_URI} !index.php$
RewriteRule ^(.+).php$ index.php?page=$1&type=1 [NC,L]
This works fine for any pages that have no arguments, but you can see that any PHP documents that have
?argument=something
end up as:
index.php?page=path/to/page?argument=something&type=1
which is not a working solution at all. Now, what's bothering me here is the $ at the end of the rule, shouldn't that cause it to fail if there is anything after the .php?
Anywho, I tried rewriting the rule as:
RewriteRule ^(.+).php\?(.+)$ index.php?page=$1&type=1&$2 [NC,L]
but that simply doesn't trigger at all. It seems that the regex flavor used in mod_rewrite is far different than I'm used to working with, so I'm sure these are simple mistakes I've made, but I can't seem to find decent documentation for this flavor of regex other than the most basic of examples.
Can anyone show me what I'm doing wrong? Thanks.
Try qsa in your rule, which stands for "query string append" - mod_rewrite will then append any query string from the original URL to the rewritten URL
RewriteCond %{REQUEST_URI} !index.php$
RewriteRule ^(.+).php$ index.php?page=$1&type=1 [NC,L,qsa]
RewriteRule doesn't match against the query string, which is why your second attempt did not work. Here's the relevant note from the manual
The Pattern will not be matched
against the query string. Instead, you
must use a RewriteCond with the
%{QUERY_STRING} variable. You can,
however, create URLs in the
substitution string, containing a
query string part. Simply use a
question mark inside the substitution
string, to indicate that the following
text should be re-injected into the
query string. When you want to erase
an existing query string, end the
substitution string with just a
question mark. To combine a new query
string with an old one, use the [QSA]
flag.