233

How can I turn a string below into an array?

pg_id=2&parent_id=2&document&video 

This is the array I am looking for,

array(
    'pg_id' => 2,
    'parent_id' => 2,
    'document' => ,
    'video' =>
)
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Run
  • 54,938
  • 169
  • 450
  • 748
  • 1
    The documentation for [parse_str()](https://www.php.net/manual/en/function.parse-str.php) does not explain it well. [This is better](https://stackoverflow.com/questions/53792310/parse-str-need-someting-on-php7/53792394#53792394) (my emphasis): *"Without the second argument to parse_str(), the query string parameters would* ***populate the local symbol table***. *Given the security implications of this, using parse_str() without a second argument has now been deprecated."* – Peter Mortensen Sep 19 '21 at 19:51

12 Answers12

389

You want the parse_str function, and you need to set the second parameter to have the data put in an array instead of into individual variables.

$queryString = "pg_id=2&parent_id=2&document&video";
 
parse_str($queryString, $queryArray);

print_r($queryArray);
8ctopus
  • 2,617
  • 2
  • 18
  • 25
Anthony
  • 36,459
  • 25
  • 97
  • 163
  • 2
    I have a problem with this answer, because it does not work if you use the same key multiple times (yes because in php array keys are unique). So `?key=lorem&key=ipsum` will result in `array(["key"]=>"ipsum")` The question is, is there a function to get s.th. like this `array(["key"]=>array("lorem", "ipsum"))` or do I have to create this function on my own? – MaBi Mar 01 '15 at 18:54
  • 11
    Technically PHP would also treat `?key=lorem&key=ipsum` as if you only provided `key=ipsum` if that were the query string on the URL. And I think it's considered invalid to reuse the key and expect consistent results or that all instances of the key are retained. The valid approach, at least for a query string sent to PHP, would be `?key[]=lorem&key[]=ipsum`, so your homegrown approach might look for any occurrences of `&{x}=` where x occurs more than once and replace with `x[]` (and treating ? as same as &) – Anthony Jun 11 '15 at 07:23
  • 9
    @Mabi - oh, and look, someone else agrees with you and created their own function already - http://php.net/manual/en/function.parse-str.php#76792 – Anthony Jun 11 '15 at 07:31
  • That was helpfull! I deciceded to do it like this `?key[]=lorem&key[]=ipsum` some weeks ago. But thanks for sharing the link! – MaBi Jun 12 '15 at 04:58
  • 2
    Something to watch out for are strings that include '+', like myemail+alias@gmail.com. These will be parsed by parse_str to a space. key=myemail alias@gmail.com. – dudeman Aug 26 '16 at 23:41
  • @dudeman, this is because the symbol `+` is a deprecated, but still supported and extendedly use for spaces. But this can easily fix by replacing `+` for it's encoded value `%2B`. For more info about the spaces encoding: https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20 – Gonzalo Mar 03 '20 at 13:07
  • @Anthony the answer at https://www.php.net/manual/en/function.parse-str.php#76792 is very incomplete and (doesn't apply urldecode to the key/values and falls over if there's no equals sign with a key). – EoghanM May 26 '22 at 10:40
74

Sometimes parse_str() alone is note accurate, it could display for example:

$url = "somepage?id=123&lang=gr&size=300";

parse_str() would return:

Array ( 
    [somepage?id] => 123 
    [lang] => gr 
    [size] => 300 
)

It would be better to combine parse_str() with parse_url() like so:

$url = "somepage?id=123&lang=gr&size=300";
parse_str( parse_url( $url, PHP_URL_QUERY), $array );
print_r( $array );
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
yassine2020
  • 811
  • 6
  • 8
37

Using parse_str().

$str = 'pg_id=2&parent_id=2&document&video';
parse_str($str, $arr);
print_r($arr);
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • Perhaps add something about the deprecation of certain usages of `parse_str`? (But ***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Sep 19 '21 at 19:33
22

If you're having a problem converting a query string to an array because of encoded ampersands

&

then be sure to use html_entity_decode

Example:

// Input string //
$input = 'pg_id=2&parent_id=2&document&video';

// Parse //
parse_str(html_entity_decode($input), $out);

// Output of $out //
array(
  'pg_id' => 2,
  'parent_id' => 2,
  'document' => ,
  'video' =>
)
Casper Wilkes
  • 899
  • 11
  • 14
20

Use http://us1.php.net/parse_str

Attention, its usage is:

parse_str($str, &$array);

not

$array = parse_str($str);

Please note that the above only applies to PHP version 5.3 and earlier. Call-time pass-by-reference has been removed in PHP 5.4.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ionut Bajescu
  • 1,243
  • 1
  • 11
  • 9
  • 3
    It's` parse_str($str,$arr);` and not `parse_str($str,&$arr);` terrible mistake –  Jul 05 '17 at 00:12
  • That is "`&$arr`" vs. "`$arr`" (`&` difference). – Peter Mortensen Sep 19 '21 at 19:23
  • @user8241064: Isn't that just the formal parameters? (Yes, you have left the building, but perhaps somebody else can chime in?) – Peter Mortensen Sep 19 '21 at 19:38
  • @pushrbx: It is not clear what should be used for later versions of PHP (or all versions of PHP). It is as if you are suggesting ***nothing*** applies for later versions of PHP (that is probably not the case or what you meant). Can you clarify? It is probably best in comments here first, before suggesting another edit. – Peter Mortensen Sep 19 '21 at 19:41
  • @PeterMortensen I made my edit with the assumption that the reader knows what is meant by "call-time pass by reference" and that it has been removed. I meant that the correct syntax would be `parse_str($str, $array);` instead of `parse_str($str, &$array);` in future versions of PHP. Also according to SO guidelines, this bit of info should be there I think. – pushrbx Sep 27 '21 at 10:43
19

There are several possible methods, but for you, there is already a built-in parse_str function:

$array = array();
parse_str($string, $array);
var_dump($array);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • Perhaps add something about the deprecation of certain usages of `parse_str`? (But ***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Sep 19 '21 at 19:34
6

This is a one-liner for parsing a query from the current URL into an array:

parse_str($_SERVER['QUERY_STRING'], $query);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hovado
  • 4,474
  • 1
  • 24
  • 30
3

You can try this code:

<?php
    $str = "pg_id=2&parent_id=2&document&video";
    $array = array();
    parse_str($str, $array);
    print_r($array);
?>

Output:

Array
(
    [pg_id] => 2
    [parent_id] => 2
    [document] =>
    [video] =>
)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yagnik Sangani
  • 227
  • 1
  • 8
  • An explanation would be in order. E.g., what is the idea/gist? Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/68964806/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Sep 19 '21 at 19:31
1

You can use the PHP string function parse_str() followed by foreach loop.

$str="pg_id=2&parent_id=2&document&video";
parse_str($str,$my_arr);
foreach($my_arr as $key=>$value){
  echo "$key => $value<br>";
}
print_r($my_arr);
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
1

But PHP already comes with a built in $_GET function. this will convert it to the array by itself.

try print_r($_GET) and you will get the same results.

jerryurenaa
  • 3,863
  • 1
  • 27
  • 17
-3

This is the PHP code to split a query in MySQL and SQL Server:

function splitquery($strquery)
{
    $arrquery = explode('select', $strquery);

    $stry = ''; $strx = '';

    for($i=0; $i<count($arrquery); $i++)
    {
        if($i == 1)
        {
            echo 'select ' . trim($arrquery[$i]);
        }
        elseif($i > 1)
        {
            $strx = trim($arrquery[($i-1)]);

            if(trim(substr($strx,-1)) != '(')
            {
                $stry = $stry . '

                        select ' . trim($arrquery[$i]);
            }
            else
            {
                $stry = $stry.trim('select ' . trim($arrquery[$i]));
            }
            $strx = '';
        }
    }
    return $stry;
}

Example:

Query before

Select xx from xx select xx,(select xx) from xx where y='    cc'
select xx from xx left join (select xx) where (select top 1 xxx from xxx) oder by xxx desc";

Query after

select xx from xx

select xx,(select xx) from xx where y='    cc'

select xx from xx left join (select xx) where (select top 1 xxx from xxx) oder by xxx desc
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dewa Putra
  • 15
  • 3
-5

For this specific question the chosen answer is correct but if there is a redundant parameter—like an extra "e"—in the URL the function will silently fail without an error or exception being thrown:

a=2&b=2&c=5&d=4&e=1&e=2&e=3 

So I prefer using my own parser like so:

//$_SERVER['QUERY_STRING'] = `a=2&b=2&c=5&d=4&e=100&e=200&e=300` 

$url_qry_str  = explode('&', $_SERVER['QUERY_STRING']);

//arrays that will hold the values from the url
$a_arr = $b_arr = $c_arr = $d_arr = $e_arr =  array();

foreach( $url_qry_str as $param )
    {
      $var =  explode('=', $param, 2);
      if($var[0]=="a")      $a_arr[]=$var[1];
      if($var[0]=="b")      $b_arr[]=$var[1];
      if($var[0]=="c")      $c_arr[]=$var[1];
      if($var[0]=="d")      $d_arr[]=$var[1];
      if($var[0]=="e")      $e_arr[]=$var[1];
    }

    var_dump($e_arr); 
    // will return :
    //array(3) { [0]=> string(1) "100" [1]=> string(1) "200" [2]=> string(1) "300" } 

Now you have all the occurrences of each parameter in its own array, you can always merge them into one array if you want to.

Hope that helps!

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Nassim
  • 2,879
  • 2
  • 37
  • 39
  • 1
    You should never have the same query param name with different values. It does not make sense since only one will be accepted anyway. – Cristian Dec 03 '17 at 03:20
  • 3
    @Cristian: “You should never have the same query param name with different values.” You are correct, but the answer states, “…the URL the function will silently fail without an error or exception being thrown.” Which could break an application. While this answer is not great, it does highlight an issue. Especially if your application can be crashed by someone just arbitrarily making a request with extra params thrown in. – Giacomo1968 Dec 08 '17 at 01:15