Can mod_rewrite convert any number of parameters with any names? - regex

I'm a total n00b at mod_rewrite and what I'm trying to do sounds simple:
instead of having domain.com/script.php?a=1&b=2&c=3 I would like to have:
domain.com/script|a:1;b:2;c:3
The problem is that my script takes a large number of parameters in a variety of combinations, and order is unimportant, so coding each one in the expression and expecting a certain order is unfeasible. So can a rule be set up that simply passes all of the parameters to the script, regardless of order or how many parameters? So that if someone types
domain.com/script|a:1;b:2;j:7 it will pass all those params and values just the same as it would with domain.com/script|b:2;a:1; ?
Thanks!

I would use PHP to parse the requested URL path:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$params = array();
foreach (explode(',', substr($_SERVER['REQUEST_URI_PATH'], 6)) as $param) {
if (preg_match('/^([^:]+):?(.*)$/', $param, $match)) {
$param[rawurldecode($match[1])] = rawurldecode($match[2]);
}
}
var_dump($params);
And the mod_rewrite rule to rewrite such requests to your /script.php file:
RewriteRule ^script\|.+ script.php [L]

Related

Rewrite rule accepting #

I have the current RewriteRule:
RewriteRule ^search/([0-9a-zA-Z-\s-:]+)(/?)$ search.php?search=$1 [NC,L,NE]
I'm wanting to have an url like this /search/#ff2266/, to accept hex (with the #) colors in the url and then have this value in the $_GET['search'] variable. But not only this, but I'm having problem with the #.
Is there any way i could do something like this: ([#0-9a-zA-Z-\s-:]+) ?
I've tried the rule:
RewriteRule ^search/(.*)(/?)$ search.php?search=$1 [NC,L,NE]
And then in the search.php the following code:
echo "var_dump($_GET): ";
var_dump($_GET);
and with the url /search/#f44336/ the result is:
var_dump(Array): array(0) { }
See, the part of a URI after the # is called "fragment" and is by definition only available/processed on client side (see https://en.wikipedia.org/wiki/Fragment_identifier).
On the client side, this can be accessed using javaScript with window.location.hash.
If you want to access that number in your search file, you could pass it to there without the hash char and use it that way.

fastcgi_cache_key exclude some args in request uri

My fastcgi_cache_key is:
fastcgi_cache_key "$host$request_method$request_uri";
My $request_uri has timestamp and signature in it:
/abc/xyz?product_id=10529125896&shop_id=17224077&shop=abc.com&path_prefix=%2Fa%2Fcomment&timestamp=1503044416&signature=882102c51c7b7bd4c5d8521a6565fc70c27b908547316f1123eb4af13b19f2da
So, the cache always MISS (because it has different timestamp and signature). My question is:
I want to create new var and use that var for fastcgi_cache_key. That var will has something like this:
myvar
/abc/xyz?product_id=10529125896&shop_id=17224077&shop=abc.com
fastcgi_cache_key will like this:
fastcgi_cache_key "$host$request_method$myvar";
How can I do that ? Thanks so much.
There are two ways to do it.
if ($request_uri ~ "([^\?]*)\?(.*)timestamp=([^&]*)&?(.*)") {
set $args $2$4;
}
fastcgi_cache_key "$host$request_method$args";
This will remove the timestamp. You can either modify the pattern to ignore one more field or you can use it twice to remove the field from $args.
Next option is to use openresty or Nginx with lua which allows you to execute Lua script in your code. if conditions are not considered good. But then having lua increases your software requirement

WordPress - Rewrite rules with multiple parameters

I'm setting up a WordPress page that would normally accept two querystring parameters. Our host prefers the use of rewrite rules instead of querystrings, so I have to take that approach.
So where I'd normally do this:
domain.com/animal-page.php?animal=dog&color=brown
I have to do this:
domain.com/animal-page/animal/dog/color/brown
The problem I am running into is that the second querystring parameter is optional.
A rewrite rule like this wouldn't work:
add_rewrite_rule(
'([\-\w+]*)/animal/([\w+]*)/color/([\w+]*)',
'index.php?pagename=$matches[1]&animal=$matches[2]&color=$matches[3]',
'top'
);
...because if the color parameter is left off the URL (which is a possibility), that Regex fails.
I've also tried making query param (color) and value (brown) optional in the Regex, and it still doesn't work:
add_rewrite_rule(
'([\-\w+]*)/animal/([\w+]*)(\/color\/?)([\w+]*)',
'index.php?pagename=$matches[1]animal=$matches[2]&$matches[3]=$matches[4]',
'top'
)
My question is: Is there a way to make the second query parameter optional? I want the page to react appropriately if the 'color' parameter is left off the URL.
Thanks,
In this case you will need to make two separate rules:
add_rewrite_rule(
'([\-\w+]*)/animal/([\w+]*)/?$',
'index.php?pagename=$matches[1]&animal=$matches[2]',
'top'
);
and
add_rewrite_rule(
'([\-\w+]*)/animal/([\w+]*)/color/([\w+]*)',
'index.php?pagename=$matches[1]&animal=$matches[2]&color=$matches[3]',
'top'
);

Wordpress rewrite rule regex

I'm trying to pass a detail as a get variable using the Wordpress Rewrite Rule API. I'm not great with regex and it's driving me mad. I have tried every combination of the below and I'm not getting anywhere:
function dcc_rewrite_tags() {
add_rewrite_tag('%propref%', '([^&]+)');
}
add_action('init', 'dcc_rewrite_tags', 10, 0);
function dcc_rewrite_rules() {
add_rewrite_rule('^/[^/]*/([^/]*)/?', 'index.php?p=2&propref=$matches[1]', 'top');
}
add_action('init', 'dcc_rewrite_rules', 10, 0);
The url structure is mysite.com/page/get-variable/. I'm just trying to pass the last bit between the slashes as the get variable "propref". Most variations I've tried, it says it can't find the page or drops the last section of slashes.

Nginx url rewrite fine tuning

I'm having trouble fine tuning a regex for Nginx url rewrite rules, What I am trying to do is take the first two pieces of the url and convert them to variables (nothing too fancy, and should be simple).
e.g. I type in http://www.webserver.com/piece1/piece2 and get http://www.webserver.com/rewtest.php??val1=piece1&val2=piece2
So far I have:
location / {
rewrite ^/(.*)/(.*)/? /rewtest.php?val1=$1&val2=$2 last;
return 404;}
}
which does seem to work. The problem is if the user types http://www.webserver.com/piece1/piece2/ it gives val 1 as piece1/piece2 (as 1 variable, not 2).
Also if the user were to type http://www.webserver.com/piece1/ I currently get piece1 in var 1, which is great. BUT if the user types http://www.webserver.com/piece1 it gives me an error and I'd like to get the same (var 1=piece1).
Any help greatly appreciated as I am new to regexs!
Seems as if / is also recognized by "."...try:
location / {
rewrite ^/([^/]+)/([^/]+)/? /rewtest.php?val1=$1&val2=$2 last;
return 404;}
}