APACHE mod_rewrite change variable name in query string - php

I'm trying to change a variable name in a query string, so it's usable by my PHP code.
The query gets posts from an external system, so I can't control that they are posting a variable name with a space in it. And that makes it impossible for me to use the PHP $_GET function.
I need to change variable%20name to ?new1
And I need to change variable2 to new2
There are many variables passed in the query, but only these two need to be changed. The rest can stay the same or even disappear.
So ?variable%20name=abc&variable2=xyz
Needs to end up as ?new1=abc&new2=xyz
Also, they may not be in this order and there may be more variables
So ?variable%20name=abc&blah=123&blah2=456&variable2=xyz
Could end up as ?new1=abc&new2=xyz
OR as ?new1=abc&blah=123&blah2=456&new2=xyz
Either way would be fine!
Please give me the mod_rewrite rule that will fix this.
Thank you in advance!

Parsing the query string with mod_rewrite is a bit of a pain, has to be done with RewriteCond and using %n replacements in a subsequent RewriteRule, probably easier to manually break up the original query string in PHP.
The full query string can be found (within PHP) in $_SERVER['QUERY_STRING'].
You can split it up using preg_split() or explode(), first on &, then on =, to get key/value pairs.
Using custom%20cbid=123&blahblahblah&name=example as an example.
$params = array();
foreach (explode("&", $_SERVER['QUERY_STRING']) as $cKeyValue) {
list ($cKey, $cValue) = explode('=', $cKeyValue, 2);
$params[urldecode($cKey)] = urldecode($cValue);
}
// Would result in:
$params = array('custom cbid' => 123,
'blahblahblah' => NULL,
'name' => example);

Related

Stringing together variables, str_replace. Tidier way to do this?

I have a bunch of variables that I want to string together. They all need to be tidied up by removing spaces and commas, and converting to dashes (I'm constructing a URL).
I have a very basic understanding of PHP, but I feel my code below could be tidier and more efficient. Could you point me to some resources or make some suggestions please?
Here's what I have:
$propNum = $prop->Address->Number;
$propStreet = $prop->Address->Street;
$propTown = $prop->Address->Town;
$propPost = $prop->Address->Postcode;
$propFullAdd = array($propNum, $propStreet, $propTown, $propPost);
$propFullAddImp = implode(" ",$propFullAdd);
$propFullAddTidy = str_replace(str_split(' ,'),'-', strtolower($propFullAddImp));
echo $propFullAddTidy;
From the output of your existing code, it seems like you may want an output that looks something like:
12345-example-street-address-example-town-example-postcode
In this case, you could use this solution:
//loop through all the values of $prop->Address
foreach($prop->Address as $value) {
//for each value, replace commas & space with dash
//store altered value in new array `$final_prop`
$final_prop[] = str_replace([' ', ','], '-', $value);
/*
Removing `str_split(' ,')` and subbing an array makes the loop "cheaper" to do,
Because the loop doesn't have to call the `str_split()` function on every iteration.
*/
}
//implode `$final_prop` array to dash separated string
//also lowercase entire string at once (cheaper than doing it in the loop)
$final_prop = strtolower(implode('-', $final_prop));
echo $final_prop;
if you remove the comments, this solution is only 4 lines (instead of 7), and is completely dynamic. This means if you add more values to $prop->Address, you don't have to change anything in this code.
A different method
I feel like this would usually be handled by using http_build_query(), which converts an array into a proper URL-encoded query string. This means that each value in the array would be passed as it's own variable in the URL query.
First, $propFullAdd is not necessary (in fact, it may be detrimental), $prop->Address already contains the exact same array. Recreating the array like this completely removes the ability to tell which value goes to which key, which could be problematic.
This means that you can simplify your entire code by replacing it with this:
echo http_build_query($prop->Address);
Which outputs something like this:
Number=12345&Street=Example+Street+Address&Town=Example+Town&Postcode=Example+Postcode

PHP: rawurldecode() not showing plus sign

I have a URL like this:
abc.com/my+string
When I get the parameter, it obviously it replaces the + with a space, so I get my string
I replaced the + in the url with %2B, then I use rawurldecode(), but the result is the same. Tried with urldecode() but I still can't get the plus sign in my variable, it's always an empty space.
Am I missing something, how do I get exactly my+string in PHP from the url abc.com/my%2Bstring ?
Thank you
In general, you don’t need to URL-decode GET parameter values manually, since PHP already does that for you, automatically. abc.com?var=my%2Bstring -> $_GET['var'] will contain my+string
The problem here was that URL rewriting was in play. As http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_b explains,
mod_rewrite has to unescape URLs before mapping them, so backreferences will be unescaped at the time they are applied.
So mod_rewrite has decoded my%2Bstring to my+string, and when you rewrite this as a query string parameter, you effectively get ?var=my+string. And when PHP applies automatic URL decoding on that value, the + will become a simple space.
The [B] flag exists to make mod_rewrite re-encode the value again.
Like this:
echo urldecode("abc.com/my%2Bstring"); // => abc.com/my+string
echo PHP_EOL;
echo rawurldecode("abc.com/my%2Bstring"); // => abc.com/my+string
Further if you want to get the actual my+string, you can utilize the powers of parse_url function which comes with PHP itself, although you have to provide a full URL into it.
Other way is just to explode the value by a / and get it like this:
$parts = explode('/', 'abc.com/my+string'); // => Array(2)
echo $parts[1] ?? 'not found'; // => string|not found
Also read the documentation on both: urldecode and rawurldecode.
Example here.

Find and concatenate result in a pattern

I have a long PHP file and I want to copy all the variable names only and build an insert sql query. Is there a way where I can search for a pattern using regular expression and concatenate the find result till I collected all the variable and spit it out in a statement?
I am using TextMate and am familiar with regular expression search. Regex search result give $0,$1 and so forth argument. Do not know if this possible though. Solution in any editor will do not just text mate.
I have just too many variable (+100) don't feel like copy every single one. Here my sample file
$ID = $_POST['id'];
$TXN_TYPE = $_POST['txn_type'];
$CHARSET = $_POST['charset']
$CUSTOM = $_POST['custom'];
You could try something with get_defined_vars(). However this function also lists GLOBAL vars. You can use this snippet to remove them if you don't want them and display only the vars you defined
$variables = array_diff(get_defined_vars(), array(array()));
However this snippet generates Notices and I haven't found a way to solve them yet.
If you've only got $_POST variables you can loop through the $_POST array itself
You create the SQL programmatically while looping through the array.
My own solution is, do the inverse. It is not probably possible.
Leave only the variable names Remove all the rest. Use
[space].+ regex to remove everything that is after the variable name.
clean the file so that only variable names are left. then do a couple more find and replace to bring the variable name in the form you want.
If you're looking to match only the variable names (not the $_POST array indices), then the regular expression is pretty much provided in the PHP documentation:
\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
This will, of course, include $_POST, but that should be easy enough to remove. If not, you could do it with negative lookahead (if TextMate supports it):
\$(?!_POST($|[^a-zA-Z0-9_\x7f-\xff]))[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

play with PHP GET

can anyone help me to play with GET urls for example I have a link like this:
?id=5&lang=1
So my question is how can I make this one:
?id=5,1
I don't want to show the &lang, only I want is that the &lang to replace with , "comma" can anyone help me?
You can use mod_rewrite to rewrite ?id=5,1 to ?id=5&lang=1 internally.
Otherwise, the value of id will be 5,1. Your application would then need to know that id contains more than the id. It could then parse out the language from the id. However, this will become confusing when you introduce more parameters.
Assuming you have already built the URL in the way you have specified, you can break the id field based on the comma and extract the real id and lang field
$urlPieces = explode(",", $_GET['id']);
$id = $urlPieces[0];
$lang = $urlPieces[1];
You are able to do this, but it's not very clean, in terms of the proper $_GET variable values. The solution automatically type casts the values to integers:
sscanf($_GET['id'], '%d,%d', $id, $lang);
// $id = int(5)
// $lang = int(1)
Two solutions:
Firstly, you could simply reformat the parameters when they arrive in your PHP program. With ?id=5,1, you'll get a PHP $_GET array with id '5,1'. This you can simply split using the explode() function to get the two values you want.
The second solution is to use the Apache mod_rewrite feature, to modify the URL arguments before they arrive at PHP. For this, you'll need to understand regular expressions (regex), as mod_rewrite uses this for it's work. You should google 'mod_rewrite' and 'regex' to find out more.
However mod_rewrite is typically used to get rid of GET arguments entirely. For example the URLs of the questions on this site do not have any get arguments, but the server translates the arguments between the slashes into GET arguments. This is considered better practice than simply than changing how the arguments look, as it is more user-friendly and SEO friendly.
Hope that helps.
$id = $id . ',' . $lang;
<a href="?<?php echo $id; ?>">

Getting array param out of query string with PHP

(NOTE: This is a follow up to a previous question, How to pass an array within a query string?, where I asked about standard methods for passing arrays within query strings.)
I now have some PHP code that needs to consume the said query string- What kind of query string array formats does PHP recognize, and do I have to do anything special to retrieve the array?
The following doesn't seem to work:
Query string:
?formparts=[a,b,c]
PHP:
$myarray = $_GET["formparts"];
echo gettype($myarray)
result:
string
Your query string should rather look like this:
?formparts[]=a&formparts[]=b&formparts[]=c
If you're dealing with a query string, you are looking at the $_GET variable. This will contain everything after the ? in your previous question.
So what you will have to do is pretty much the opposite of the other question.
$products = array();
// ... Add some checking of $_GET to make sure it is sane
....
// then assign..
$products = explode(',', $_GET['pname']);
and so on for each variable. I must give you a full warning here, you MUST check what comes through the $_GET variable to make sure it is sane. Otherwise you risk having your site compromised.

Categories