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'];
Related
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
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
So I would like to take a string like this,
q=Sugar Beet&qf=vegetables&range=time:[34-40]
and break it up into separate pieces that can be put into an associative array and sent to a Solr Server.
I want it to look like this
['q'] => ['Sugar Beets],
['qf'] => ['vegetables']
After using urlencode I get
q%3DSugar+Beet%26qf%3Dvegetables%26range%3Dtime%3A%5B34-40%5D
Now I was thinking I would make two separate arrays that would use preg_split() and take the information between the & and the = sign or the = and the & sign, but this leaves the problem of the final and first because they do not start with an & or end in an &.
After this, the plan was to take the two array and combine them with array_combine().
So, how could I do a preg_split that addresses the problem of the first and final entry of the string? Is this way of doing it going to be too demanding on the server? Thank you for any help.
PS: I am using Drupal ApacheSolr to do this, which is why I need to split these up. They need to be sent to an object that is going to build q and qf differently for instance.
You don't need a regular expression to parse query strings. PHP already has a built-in function that does exactly this. Use parse_str():
$str = 'q=Sugar Beet&qf=vegetables&range=time:[34-40]';
parse_str($str, $params);
print_r($params);
Produces the output:
Array
(
[q] => Sugar Beet
[qf] => vegetables
[range] => time:[34-40]
)
You could use the parse_url() function/.
also:
parse_str($_SERVER['QUERY_STRING'], $params);
I have a string passed through a campaign source that looks like this:
/?source=SEARCH%20&utm_source=google&utm_medium=cpc&utm_term=<keyword/>&utm_content={creative}&utm_campaign=<campaign/>&cpao=111&cpca=<campaign/>&cpag=<group/>&kw=<mpl/>
when its present I need to cut this up and pass it through to our form handler so we can track our campaigns. I can check for it, hold its contents in a cookie and pass it throughout our site but i am having and issue using preg_match to cut this up and put it into variables so I can pass their values to the handler. I want the end product to look like:
$utm_source=google;
$utm_medium=cpc;
$utm_term=<keyword/>
there is no set number of characters, it could be Google, Bing etc, so i am trying to use preg_match to get the first part (utm_source) and stop past what I want (&) and so forth but I don't understand preg_match well enough to do this.
PHP should be parsing your query sting for you, into $_GET. Otherwise, PHP knows how to parse query strings. Don't use regular expressions or for this, use parse_str.
Input:
<?php
$str = "/?source=SEARCH%20&utm_source=google&utm_medium=cpc&utm_term=<keyword/>&utm_content={creative}&utm_campaign=<campaign/>&cpao=111&cpca=<campaign/>&cpag=<group/>&kw=<mpl/>";
$ar = array();
parse_str($str, $ar);
print_r($ar);
Output:
Array
(
[/?source] => SEARCH
[utm_source] => google
[utm_medium] => cpc
[utm_term] => <keyword/>
[utm_content] => {creative}
[utm_campaign] => <campaign/>
[cpao] => 111
[cpca] => <campaign/>
[cpag] => <group/>
[kw] => <mpl/>
)
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_queryDocs 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: urldecodeDocs:
$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.