generating url parameters from array - php

Let's say I have the following array :
$params
= array(
'foo' => 'bar',
'baz' => array('qux', 'qux2', 'qux3')
);
is there a pre-built function in php so :
the_function($params);
outputs
'foo=bar&baz[]=qux&baz[]=qux2&baz[]=qux3'
?
Note : i am asking for a pre-built function, I can code the function myself. Just making sure I am not coding something already existing.

How come nobody suggested this before. http_build_query() is what you were looking for.
$params = array('foo'=>'bar','baz'=>array('qux','qux2','qux3'));
echo urldecode(http_build_query($params));
// foo=bar&baz[0]=qux&baz[1]=qux2&baz[2]=qux3
A few caveats you might have to be aware of :
the resulting string is urlencoded (use urldecode() as I did above if necesary)
array indexes are present in the query string
Some of the comments in the documentation page can help with the latter if needed. http://php.net/manual/en/function.http-build-query.php

Related

http_build_query without value on parameters (null value)

The PHP function http_build_query is quite handy for building an URL with GET parameters. But sometimes I like to use value-less "boolean" parameters, like so:
/mypage?subscription-id=42&cancel-renewal
Which I then check with a simple isset. Can I achieve this result with http_build_query?
EDIT: Assigning empty values to the parameter does not seem to work :
cancel-renewal => '' results in cancel-renewal=
cancel-renewal => null results in the parameter being omitted
cancel-renewal => false results in cancel-renewal=0
Can I achieve this result with http_build_query?
No. Internally http_build_query appends the = key-value separator no matter what is the value of the parameter.
You can see the source code here (PHP 7.3.3)
Means you either need to accept the cancel-renewal= look of the parameter or may be redesign the path to have something like /mypage/cancel-renewal?subscription-id=42
Third option would be to write your own simple function to build the query string.
Use this;
$query = array("subscription-id" => 42, "cancel-renewal" => "");
$http_query = http_build_query($query);
This will return ?subscription-id=42&cancel-renewal=. And works perfectly fine with isset()

behavior when there are two HTTP GET parameters with the same name

Say your HTTP request is formatted like this:
GET /path/to/file.php?var[]=1&var[]=2
PHP will populate that into an array named $_GET: array('var' => array(1, 2))
My question is... is this a PHP thing or is this behavior governed by an RFC? How would a web accessible node.js or Python script deal with this?
PHP by default will overwrite previous values, and you end up with the LAST key:value pair found in the query string. But in PHP you can use the [] array as fieldname hack:
example.com?foo=bar&foo=baz&foo=qux
example.com?foo[]=bar&foo[]=baz&foo[]=qux
Line #1 produces $_GET like this:
$_GET = array(
'foo' => 'qux'
);
Line #2 produces
$_GET['array'] = array
'foo' => array('bar', 'baz', 'qux');
}
Note that this behavior is PHP specific. Other languages do their own thing. As far as I remember, Perl by default will keep all values as an array.
This is a specific feature of PHP with no related RFCs or other specs. I can't find any specific statements to that effect, but reading this FAQ Q/A seems to imply the same:
http://docs.php.net/manual/en/faq.html.php#faq.html.arrays

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.

PHP array argument

Is there a way to make the arguments of a function act as an array? I'm finding this difficult to explain.
Here's kind of an example.. When you declare an array, you can define the keys => values like so:
$array = array(
"key" => "value",
"other_key" => "other_value"
);
And if I make a function that for an example outputs these onto the document, I could have:
function write($ar)
{
foreach($ar as $key => $value)
echo "$key: $value<br />";
}
write($array); // parse previously mentioned array
What I want to be able to do is omit the need to parse an array like above or below examples..
write(array(
"key" => "value",
"other_key" => "other_value"
));
I know I can use func_get_args() to list any amount of arguments, but is there a similar function that lets you parse key => value pairs rather than just a list of values?
Hope I described this in a way that makes sense, what I essentially want to end up with is something like:
write(
"key" => "value",
"other_key" => "other_value"
);
A function cannot take the argument as an array structure, so your best bet would be to use the method you specified in your second to last example:
write(array(
"key" => "value",
"other_key" => "other_value"
));
You could then have a default array within your function (if desired) so you could merge the two together so you always have a decent set of data.
EDIT
Unless you want to go crazy and pass it through as a string:
write('
"key" => "value",
"other_key" => "other_value"
');
And then parse that out on the other side... but IMO I wouldn't bother, potentially opening yourself up to issues here.
I know I can use func_get_args() to list any amount of arguments, but is there a similar function that lets you parse key => value pairs rather than just a list of values?
No, that's not possible in PHP. However you can fork PHP and implement such a syntax or make a code preprocessor ;)
well, I assume that you can send an object instead of an array and declare like that.
//the class
class CustomType{
public $key1;
public $key2;
}
//the function
function write(CustomType $customType){
}
//call the funcion write
$a = new CustomType();
$a->key1 = 1;
$a->key2 = 2;
write($a);
the above will force the user to send a custom object.
it is better than arrays, but then again, the user can ignore and not set $key2.
BTW, if you choose this method, you might as well do it in JAVA style with getters and setters. like here: http://www.abbeyworkshop.com/howto/java/salesTaxBean/index.html
that is as good as it gets since php is typeless, but i think it is much better then arrays
Edit
One of the bad usage in PHP is using arrays as params.
Almost every framework does that and you can find your self diving into sources in order to understand the array structure.
When you declare a class, you get it as autocomplete in your editor, and if not you just need to open the class to understand its structure.
I believe this is better programming style.

How to pass querystring to testAction in CakePHP 1.2?

In CakePHP putting a querystring in the url doesn't cause it to be automatically parsed and split like it normally is when the controller is directly invoked.
For example:
$this->testAction('/testing/post?company=utCompany', array('return' => 'vars')) ;
will result in:
[url] => /testing/post?company=utCompany
While invoking the url directly via the web browser results in:
[url] => Array
(
[url] => testing/post
[company] => utCompany
)
Without editing the CakePHP source, is there some way to have the querystring split when running unit tests?
I have what is either a hack (i.e. may not work for future CakePHP releases) or an undocumented feature.
If the second testAction parameter includes an named array called 'url' then the values will be placed in the $this->params object in the controller. This gives us the same net result as when the controller is directly invoked.
$data = array ('company' => 'utCompany') ;
$result = $this->testAction('/testing/post', array
(
'return' => 'vars',
'method' => 'get',
'url' => $data)
) ;
I'm satisfied with this method for what I need to do. I'll open the question to the community shortly so that it in the future a better answer can be provided.
None of these answers will woerk in Cake 1.3. You should instead set the following before your testAction call:
$this->__savedGetData['company'] = 'utcompany';
CakePHP does provide some level of url splitting but it only seems to work in the run-time configuration and not the test configuration. I'll contact the CakePHP if this is intentional.
I suggestion for your querystring parser would be to use the PHP function explode.
I believe you can do something like this:
$result = explode ('&', $queryString, -1) ;
which would give you your key-pairs in seperate array slots upon which you can iterate and perform a second explode like so:
$keyPair = explode ('=', $result[n], -1) ;
However, all this being said it would be better to peek under the hood of CakePHP and see what they are doing.
What I typed above won't correctly handle situations where your querystring contains html escaped characters (prefixed with &), nor will it handle hex encoded url strings.
use _GET['parmname'];

Categories