Vladimir Kornea wrote on 8 Sep 2006:
"This function is confused by ampersands (&) being encoded as HTML entities (&)"
Well, it would be - it's not supposed to be passed html entities, that's a different encoding scheme. This function does correctly decode url encoded params for you though (with the rawurlencode rather than urlencode, ie '+' is translated to a space).
parse_str
説明
void parse_str ( string str [, array &arr] )URL経由で渡されるクエリー文字列と同様にstr を処理し、現在のスコープに変数をセットします。2番目の引数 arr が指定された場合、 変数は、代わりに配列の要素としてこの変数に保存されます。
注意: 現在の QUERY_STRING を取得するには、変数 $_SERVER['QUERY_STRING'] を使用する事ができます。また、 PHPの外部から来る変数 のセクションも読んでください。
注意: オプションの2番目のパラメータのサポートはPHP 4.0.3で追加さされま した。
parse_url(), pathinfo(), http_build_query(), get_magic_quotes_gpc(), urldecode() も参照ください。
parse_str
jgbreezer at gmail dot com
31-Jan-2007 09:52
31-Jan-2007 09:52
Olivier Mengué
08-Oct-2006 06:02
08-Oct-2006 06:02
Vladimir: the function is OK in how it deals with &.
& must only be used when outputing URLs in HTML/XML data.
You should ask yourself why you have & in your URL when you give it to parse_str.
Vladimir Kornea
09-Sep-2006 06:15
09-Sep-2006 06:15
This function is confused by ampersands (&) being encoded as HTML entities (&).
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str, $output);
print_r($output);
Array
(
[first] => value
[amp;arr] => Array
(
[0] => foo bar
[1] => baz
)
)
PEPE_RIVAS at repixel dot net
29-Aug-2006 10:21
29-Aug-2006 10:21
CONVERT ANY FORMATTED STRING INTO VARIABLES
I developed a online payment solution for credit cards using a merchant, and this merchant returns me an answer of the state of the transaction like this:
estado=1,txnid=5555444-8454445-4455554,monto=100.00
to have all that data into variables could be fine for me! so i use str_replace(), the problem is this function recognizes each group of variables with the & character... and i have comma separated values... so i replace comma with &
<?php
$string = "estado=1,txnid=5555444-8454445-4455554,monto=100.00";
$string = str_replace(",","&",$string);
parse_str($string);
echo $monto; // outputs 100.00
?>
motin at demomusic dot nu
15-Apr-2006 10:13
15-Apr-2006 10:13
When you have scripts run through the command-line (like locally via cron), you might want to be able to use _GET and _POST vars. Put this in top of your scheduled task files:
<?
parse_str ($_SERVER['argv'][1], $GLOBALS['_GET']);
parse_str ($_SERVER['argv'][2], $GLOBALS['_POST']);
?>
And call your script by:
/usr/local/bin/php /path/to/script.php "id=45&action=delete" "formsubmitted=true"
Cheers!
avi at amarcus dot com
04-Sep-2005 10:32
04-Sep-2005 10:32
If you are trying to preserve a complex array, the function serialize might be better than http_build_query or other methods of making a query string.
ET
01-Sep-2005 07:14
01-Sep-2005 07:14
In reply to what kerosuppi posted:
[quote]This does not work as expected.[/quote]
No, it works exactly as expected.
The call <?php parse_str($this->query_string);?> "sets variables in the current scope" (just like said in the manual).
You are using this call in the constructor. Once the constructor is finished, the scope of this function has ended so it's logical that you can't access the variables anymore.
Your workaround though is a good one.
Hope this helps,
ET
Tore Bjlseth
29-Jun-2005 09:59
29-Jun-2005 09:59
As of PHP 5, you can do the exact opposite with http_build_query(). Just remember to use the optional array output parameter.
This is a very useful combination if you want to re-use a search string url, but also slightly modify it:
Example:
<?
$url1 = "action=search&interest[]=sports&interest[]=music&sort=id";
$str = parse_str($url1, $output);
// Modifying criteria:
$output['sort'] = "interest";
$url2 = http_build_query($output);
echo "<br>url1: ".$url1;
echo "<br>url2: ".$url2;
?>
Results in:
url1: action=search&interest[]=sports&interest[]=music&sort=id
url2: action=search&interest[0]=sports&interest[1]=music&sort=interest
(Array indexes are automatically created.)
vargasangelo_1990 at hotmail dot com
20-Jun-2005 03:46
20-Jun-2005 03:46
this can be another option for STR PARSING and use it as a $_GET variable.
<?php
$str= "op=downloads&id=1&details=1";
function parse_to_get($str=false){
if($REQUEST_URI==$str): $ex = explode("/".$PHP_SELF."?", $str); $str = $ex[1]; endif;
if($str):
$a = explode("&", $str);
foreach($a as $e){
if($e):
list($k,$v)=explode("=", $e);
$_GET[$k]=$v;
endif;
}
endif;
extract($_GET);
}
parse_top_get("index.php?page=info&name=jonh&id=4245&app=server");
?>
:)
//Trukin
kerosuppi
30-May-2005 01:22
30-May-2005 01:22
This does not work as expected.
<?php
class someclass
{
var $query_string;
function someclass($a_query_string)
{
$this->query_string = $a_query_string;
parse_str($this->query_string);
}
function output()
{
echo $this->action;
}
}
$a_class = new someclass("action=go");
$a_class->output();
?>
Use this instead.
<?php
class someclass
{
var $arr;
function someclass($a_query_string)
{
parse_str($a_query_string, $this->arr);
}
function output()
{
echo $this->arr['action'];
}
}
$a_class = new someclass("action=go");
$a_class->output();
?>
mortoray at ecircle-ag dot com
25-May-2005 04:18
25-May-2005 04:18
In Kent's solution you may wish to switch "urldecode" into "rawurldecode" if you'd like to get rid of the [annoying] plus '+' converted to space ' ' translation.
kent at nospam dot ioflux dot com
07-May-2005 12:13
07-May-2005 12:13
You may want to parse the query string into an array.
<?php
/**
* Similar to parse_str. Returns false if the query string or URL is empty. Because we're not parsing to
* variables but to array key entries, this function will handle ?[]=1&[]=2 "correctly."
*
* @return array Similar to the $_GET formatting that PHP does automagically.
* @param string $url A query string or URL
* @param boolean $qmark Find and strip out everything before the question mark in the string
*/
function parse_query_string($url, $qmark=true)
{
if ($qmark) {
$pos = strpos($url, "?");
if ($pos !== false) {
$url = substr($url, $pos + 1);
}
}
if (empty($url))
return false;
$tokens = explode("&", $url);
$urlVars = array();
foreach ($tokens as $token) {
$value = string_pair($token, "=", "");
if (preg_match('/^([^\[]*)(\[.*\])$/', $token, $matches)) {
parse_query_string_array($urlVars, $matches[1], $matches[2], $value);
} else {
$urlVars[urldecode($token)] = urldecode($value);
}
}
return $urlVars;
}
/**
* Utility function for parse_query_string. Given a result array, a starting key, and a set of keys formatted like "[a][b][c]"
* and the final value, updates the result array with the correct PHP array keys.
*
* @return void
* @param array $result A result array to populate from the query string
* @param string $k The starting key to populate in $result
* @param string $arrayKeys The key list to parse in the form "[][a][what%20ever]"
* @param string $value The value to place at the destination array key
*/
function parse_query_string_array(&$result, $k, $arrayKeys, $value)
{
if (!preg_match_all('/\[([^\]]*)\]/', $arrayKeys, $matches))
return $value;
if (!isset($result[$k])) {
$result[urldecode($k)] = array();
}
$temp =& $result[$k];
$last = urldecode(array_pop($matches[1]));
foreach ($matches[1] as $k) {
$k = urldecode($k);
if ($k === "") {
$temp[] = array();
$temp =& $temp[count($temp)-1];
} else if (!isset($temp[$k])) {
$temp[$k] = array();
$temp =& $temp[$k];
}
}
if ($last === "") {
$temp[] = $value;
} else {
$temp[urldecode($last)] = $value;
}
}
/**
* Breaks a string into a pair for a common parsing function.
*
* The string passed in is truncated to the left half of the string pair, if any, and the right half, if anything, is returned.
*
* An example of using this would be:
* <code>
* $path = "Account.Balance";
* $field = string_pair($path);
*
* $path is "Account"
* $field is "Balance"
*
* $path = "Account";
* $field = string_pair($path);
*
* $path is "Account"
* $field is false
* </code>
*
* @return string The "right" portion of the string is returned if the delimiter is found.
* @param string $a A string to break into a pair. The "left" portion of the string is returned here if the delimiter is found.
* @param string $delim The characters used to delimit a string pair
* @param mixed $default The value to return if the delimiter is not found in the string
* @desc
*/
function string_pair(&$a, $delim='.', $default=false)
{
$n = strpos($a, $delim);
if ($n === false)
return $default;
$result = substr($a, $n+strlen($delim));
$a = substr($a, 0, $n);
return $result;
}
?>
11-Mar-2005 09:26
yet another simpler way to do the reverse this function.
<?php
/* BSD LINCENSE */
function build_str($query_array) {
$query_string = array();
foreach ($query_array as $k => $v) {
$query_string[] = $k.'='.$v;
}
return join('&', $query_string);
}
// example of use
// set a query string
$test_query = "a=b&c=d";
// parse a string
parse_str($test_query, $query_array);
//print it
print_r($query_array);
// test the build_str function
if ( build_str($query_array) == $test_query ) {
echo "It works";
} else {
echo "It doesn't work";
}
?>
nospam at fiderallalla dot de
03-Feb-2005 07:29
03-Feb-2005 07:29
Maybe you need an opposite which works with arrays:
<?php
function query_str ($params) {
if ( !is_array($params) || count($params) == 0 ) return false;
$fga = func_get_args();
$akey = ( !isset($fga[1]) ) ? false : $fga[1];
static $out = Array();
foreach ( $params as $key=>$val ) {
if ( is_array($val) ) {
query_str($val,$key);
continue;
}
$thekey = ( !$akey ) ? $key : $akey.'['.$key.']';
$out[] = $thekey."=".$val;
}
return implode("&",$out);
}
?>
anatilmizun at gmail dot com
13-Oct-2004 08:10
13-Oct-2004 08:10
I wrote a pair of functions using parse_str() that will write values in an array to a textfile and vice versa, read those values from the textfile back into the array. Quite useful if you need to store lots of data but don't have access to SQL.
Save the array by calling cfg_save($filename,$array) and load it back using $array=cfg_load($filename)
<?php
$newline="";
function cfg_load($cfgfile){
global $newline;
$setting="";
if(file_exists($cfgfile)){
$setting=fopen($cfgfile, "r");
$ookk="";
while($ook=fgets($setting)){
#strip comment
$commt=strpos($ook,"##");
if($commt!==false) $ook=substr($ook,0,$commt);
#append
if($ook!="") $ookk=$ookk."&". str_replace($newline,"\n",str_replace("&","%26",trim($ook)));
}
fclose($setting);
parse_str($ookk, $setting);
}
return $setting;
}
function cfg_save($cfgfile,$setting){
global $intArray;
$intArray="";
for($i=0;$i<2000;$i++)
$intArray[]=$i;
if(is_array($setting)){
$allkeys=array_keys($setting);
foreach($allkeys as $aKey)
cfg_recurse($setting[$aKey], $aKey, $outArray);
}
$cfgf=fopen($cfgfile,"w");
foreach($outArray as $aLine)
fputs($cfgf,stripslashes($aLine)."\r\n");
fclose($cfgf);
}
function cfg_recurse($stuffIn, $keysofar, &$toAppend){
global $intArray, $newline;
if(is_array($stuffIn)){
$allkeys=array_keys($stuffIn);
if(array_slice($intArray,0,sizeof($allkeys))==$allkeys)
$nokey=true;
else
$nokey=false;
foreach($allkeys as $aKey){
if(!$nokey) $toKey=$aKey;
cfg_recurse($stuffIn[$aKey], $keysofar."[".$toKey."]", $toAppend);
}
}else
$toAppend[]=$keysofar."=".str_replace("\n",$newline,$stuffIn);
}
?>
Note that these functions support nested arrays of unlimited levels ;)
Matt Curtis
09-Sep-2004 12:46
09-Sep-2004 12:46
If the querystring contains duplicate keys in the key-value pairs, parse_str will only return the last instance of the value. For example, in the following:
<?php
$mystr = "test1=blah&test2=bleh&test1=burp";
parse_str($mystr, $myarray);
echo $myarray['test1'];
?>
The value output will be 'burp'.
I wrote a function that takes a querystring and returns the the key-value pairs as a two-dimensional array so each duplicate key is available:
<?php
$str = "test1=blah&test2=bleh&test1=burp";
$valsarray = parse_str_ext($str);
echo $valsarray['test1'][0];
echo $valsarray['test1'][1];
echo $valsarray['test2'][0];
function parse_str_ext($toparse) {
$returnarray = array();
$keyvaluepairs = split("&", $toparse);
foreach($keyvaluepairs as $pairval) {
$splitpair = split("=", $pairval);
if(!array_key_exists($splitpair[0], $returnarray)) $returnarray[$splitpair[0]] = array();
$returnarray[$splitpair[0]][] = $splitpair[1];
}
return $returnarray;
}
?>
Output will be:
blah
burp
bleh
17-Jun-2004 09:23
Note that variables cannot contain a DOT (.) in PHP. So, DOT will be replaced by underscore.
e.g. variables like "variable.something" will be converted into "variable_something".
01-Apr-2004 03:58
The documentation does not appear to mention that parse_str also urldecodes each item in the resulting array.
There also appears to be a bug in earlier versions of PHP that causes these urldecoded strings to also be escaped. (Certainly I was having problems with %22 being turned into /" on my server, but not on my development box, despite forcing magic quotes off).
dante at lorenso dot com
06-Jul-2003 02:11
06-Jul-2003 02:11
You can perform the opposite of this function if you like with a function like I've built below:
/**
* Reverse of parse_str(). Converts array into
* string with query format
*/
function query_str ($params) {
$str = '';
foreach ($params as $key => $value) {
$str .= (strlen($str) < 1) ? '' : '&';
$str .= $key . '=' . rawurlencode($value);
}
return ($str);
}
-- Dante