PHP: rawurldecode() not showing plus sign - php

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.

Related

PHP Get method, escaping the "&" value

i have this Download link that will be using a GET method, here's my code:
echo "<a href='dlexcel.php?pname=".s1."&year=".s2."'>DOWNLOAD</a>";
that will be recieve by dlexcel.php
$_GET['pname'].$_GET['year'];
the problem is, s1 is string that can contain the a value &. and the string itself is not complete when $_GET is called.
i already used str_replace and preg_replace but i dont know how to. i need to pull the & out and replace it with something else, i just dont know how or what.
You need to use
urlencode($s1)
when encoding a string to be used in a query part of a URL
Try http_build_query(). http://www.php.net/http_build_query
echo '<a href="dlexcel.php?', http_build_query(array(
'pname' => $s1,
'year' => $s2
), '">DOWNLOAD</a>');
This takes care of encoding data, while building the entire query string from an array for you, meaning you aren't manually hacking it together. Remember, there is more than just & that you must encode.

Why is the string length showing up in the URL?

I am trying to pass an array through a url. I have tried encoding the URL, serializing the URL, serializing and encoding the URL, and no matter what I do, the length of the strings is coming up in the url.
For example, if I pass the array through a URL this way:
<a href='http://splitsum.com/samples/your_store/checkout_form2.php?arr=<?PHP echo serialize($order); ?>'>Next Page</a>
The resulting URL looks like this (with the string count printed out):
.....s:15:%22shipping_method%22;s:20:%22Flat%20Rate%20(Best%20Way)%22;.....
Does anyone know why this is happening? I can var_dump the entire array (and see the string counts on the page) but I cant seem to print individual values in the array. Could it have something to do with a problem in the URL and the printing of the string length?
Thanks!
Because you're using serialize(). You should be using urlencode() instead.
serialize is intended to take internal arbitrary data structures, and encode them into a portable format for re-use in a PHP system somewhere else. It does NOT produce code that is guaranteed valid in a URL context. Basically you're using a hammer to pound in a screw. Use a screwdriver instead.
Note that urlencode will not accept an array. Perhaps http_build_query() would be more appropriate
The length is appearing because you're using serialize. That how it outputs. It's used to store a PHP variable, so that it can be loaded back into PHP again. It's output format contains the length of arrays/strings.
This is the wrong tool for this job. You want to use http_build_query here instead.
<a href='http://splitsum.com/samples/your_store/checkout_form2.php?<?PHP echo http_build_query(array('arr' => $order)); ?>'>Next Page</a>
Then $_GET['arr'] in checkout_form2.php will be your $order array.

Are there any tricks to avoid having to urlencode a url in a querystring

I'm trying to put a script together for a client that needs to be able to accept a web address in a query string without it first being urlencoded. An example would be like this:
http://foo.com/script.php?url=www.amazon.co.uk/ESET-Smart-Security-User-Year/dp/B005NPFOBM/ref=sr_1_1?s=software&ie=UTF8&qid=1341685530&sr=1-1
However, when I echo out the contents of $_GET['url'] it gives me the following:
www.amazon.co.uk/ESET-Smart-Security-User-Year/dp/B005NPFOBM/ref=sr_1_1?s=software
So basically it seems to choke on the first ampersand - i'm guessing because it thinks that its another variable.
Aside form urlencoding, are there any tricks to getting this working? I could probably POST it from a form, but this defeats the idea of the script.
For this specific use case, you should use $_SERVER['QUERY_STRING'] instead. This will give you the full query string in one go, you can then split it yourself.
In your example, PHP is assuming that the & is the delimiter for the next GET variable.
you could ask the query parameters, and add them to the URL you received. List the remaining parameters in $_GET in the proper order, and add them add the end of $_GET['url'].
$_GET['url']
+ '&ie=' + $_GET['ie']
+ '&qid=' + $_GET['qid']
+ '&sr=' + $_GET['sr']
Be careful that you might get an extra parameter url someday.
http://foo.com/script.php?url=www.amazon.co.uk/ESET-Smart-Security-User-Year/dp/B005NPFOBM/ref=sr_1_1?s=software&ie=UTF8&qid=1341685530&sr=1-1&url=http://someAmazoneStuff

PHP http_build_query special symbols

I want to create an url out of an array with the help of http_build_query (PHP). This is the Array:
$a = array("skip" => 1, "limit" => 1, "startkey" => '["naturalProduct","Apple"]')
After calling
$s = http_build_query($a);
I get the following string $s:
skip=1&limit=1&startkey=%5B%22naturalProduct%22%2C%22Apple%22%5D
My problem is, that I would need an url like this:
skip=1&limit=1&startkey=["naturalProduct","Apple"]
which means, that I don't want to convert the following symbols: ",[]
I have written a conversion function which I call after the http_build_query:
str_replace(array("%5B", "%22", "%5D", "%2C"), array('[', '"', ']', ','), $uri);
My question now: Is there a better way to reach the expected results?
My question now: Is there a better way to reach the expected results?
Yes, there is something better. http_build_query­Docs by default uses an URL encoding as outlined in RFC 1738. You just want to de-urlencode the string. For that there is a function that does this in your case: urldecode­Docs:
$s = http_build_query($a);
echo urldecode($s);
I hope you are aware that your URL then is no longer a valid URL after you've done that. You already decoded it.
You don't need to decode the special characters - they are automatically decoded when PHP's $_GET superglobal is generated. When I do print_r($_GET) with your generated string, I get this:
Array ( [skip] => 1 [limit] => 1 [startkey] => [\"naturalProduct\",\"Apple\"] )
Which has decoded every character, but hasn't unescaped the double quotes. To unescape them, use stripslashes():
echo stripslashes($_GET['startkey']);
This gives
["naturalProduct","Apple"]
Which you can then parse or use however you wish. A better solution, as ThiefMaster mentions in the comments, is to disabled magic_quotes_gpc in your php.ini; it's deprecated and scheduled for removal completely in PHP6.

APACHE mod_rewrite change variable name in query string

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);

Categories