将查询字符串解析为数组

Posted

技术标签:

【中文标题】将查询字符串解析为数组【英文标题】:Parse query string into an array 【发布时间】:2011-07-20 20:13:30 【问题描述】:

如何将下面的字符串变成数组

pg_id=2&parent_id=2&document&video 

这是我要找的数组,

array(
    'pg_id' => 2,
    'parent_id' => 2,
    'document' => ,
    'video' =>
)

【问题讨论】:

parse_str() 的文档没有很好地解释它。 This is better(我的重点):“如果没有 parse_str() 的第二个参数,查询字符串参数将 填充本地符号表考虑到这一点的安全隐患,现在不推荐使用不带第二个参数的 parse_str()。" 【参考方案1】:

您需要parse_str 函数,并且需要设置第二个参数以将数据放入数组而不是单个变量中。

$get_string = "pg_id=2&parent_id=2&document&video";

parse_str($get_string, $get_array);

print_r($get_array);

【讨论】:

我对这个答案有疑问,因为如果您多次使用同一个键,它就不起作用(是的,因为在 php 数组中键是唯一的)。所以?key=lorem&key=ipsum 将导致array(["key"]=>"ipsum") 问题是,是否有一个函数来获取s.th。像这样array(["key"]=>array("lorem", "ipsum")) 还是我必须自己创建这个函数? 从技术上讲,如果 ?key=lorem&key=ipsum 是 URL 上的查询字符串,PHP 也会将其视为您只提供了 key=ipsum。而且我认为重用密钥并期望一致的结果或保留密钥的所有实例被认为是无效的。至少对于发送到 PHP 的查询字符串来说,有效的方法是 ?key[]=lorem&key[]=ipsum,因此您的本地方法可能会查找任何出现的 &x=,其中 x 出现多次并替换为 x[](并将 ? 视为与 &) 相同 @Mabi - 哦,看,其他人同意你的观点并已经创建了自己的函数 - php.net/manual/en/function.parse-str.php#76792 这很有帮助!几周前我决定这样做?key[]=lorem&key[]=ipsum。但感谢分享链接! 需要注意的是包含“+”的字符串,例如 myemail+alias@gmail.com。这些将由 parse_str 解析为空格。 key=myemail alias@gmail.com.【参考方案2】:

有时parse_str() 单独注释是准确的,它可以显示例如:

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

parse_str() 会返回:

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

最好将parse_str()parse_url() 结合起来,如下所示:

$url = "somepage?id=123&lang=gr&size=300";
parse_str( parse_url( $url, PHP_URL_QUERY), $array );
print_r( $array );

【讨论】:

我猜它期待$_SERVER['QUERY_STRING'] 如何排列成字符串 url ex。 : 数组 ( [somepage?id] => 123 [lang] => gr [size] => 300 ) 输出 = somepage?id=123&lang=gr&size=300【参考方案3】:

使用parse_str()

$str = 'pg_id=2&parent_id=2&document&video';
parse_str($str, $arr);
print_r($arr);

【讨论】:

也许添加一些关于 parse_str 某些用法的弃用? (但没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的)。【参考方案4】:

如果您在将查询字符串转换为数组时遇到问题,因为编码的 & 符号

&

那么一定要使用html_entity_decode

示例:

// 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' =>
)

【讨论】:

这对于删除不需要的 & 至关重要【参考方案5】:

使用http://us1.php.net/parse_str

注意,它的用法是:

parse_str($str, &$array);

不是

$array = parse_str($str);

请注意,上述仅适用于 PHP 5.3 及更早的版本。在 PHP 5.4 中删除了调用时传递引用。

【讨论】:

这是`parse_str($str,$arr);` 而不是parse_str($str,&$arr); 严重错误 即“&$arr”与“$arr”(& 不同)。 @user8241064:这不只是形式参数吗? (是的,你已经离开了大楼,但也许其他人可以插话?) @pushrbx:不清楚应该为更高版本的 PHP(或所有版本的 PHP)使用什么。就好像您建议 nothing 适用于更高版本的 PHP(可能不是这种情况或您的意思)。你能澄清一下吗?在建议另一个编辑之前,最好先在 cmets 中进行。 @PeterMortensen 我的编辑假设读者知道“调用时通过引用传递”的含义并且它已被删除。我的意思是,在 PHP 的未来版本中,正确的语法应该是 parse_str($str, $array); 而不是 parse_str($str, &$array);。同样根据 SO 指南,我认为应该有这些信息。【参考方案6】:

有几种可能的方法,但对你来说,已经有一个内置的parse_str function:

$array = array();
parse_str($string, $array);
var_dump($array);

【讨论】:

也许添加一些关于 parse_str 某些用法的弃用? (但没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的)。【参考方案7】:

这是一种将当前 URL 中的查询解析为数组的单行方法:

parse_str($_SERVER['QUERY_STRING'], $query);

【讨论】:

【参考方案8】:

您可以使用 PHP 字符串函数 parse_str() 后跟 foreach 循环。

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

【讨论】:

【参考方案9】:

你可以试试这个代码:

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

输出:

Array
(
    [pg_id] => 2
    [parent_id] => 2
    [document] =>
    [video] =>
)

【讨论】:

解释一下。例如,想法/要点是什么?请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。【参考方案10】:

这是在mysql 和SQL Server 中拆分查询的PHP 代码:

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;

例子:

查询前

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

查询后

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

【讨论】:

【参考方案11】:

对于这个特定的问题,选择的答案是正确的,但如果 URL 中有多余的参数(例如额外的“e”),则函数将静默失败,而不会引发错误或异常:

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

所以我更喜欢像这样使用自己的解析器:

//$_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"  

现在每个参数的所有匹配项都在其自己的数组中,如果需要,您可以随时将它们合并到一个数组中。

希望有帮助!

【讨论】:

您永远不应该使用具有不同值的相同查询参数名称。这是没有意义的,因为无论如何只会接受一个。 @Cristian:“您永远不应该使用具有不同值的相同查询参数名称。”你是对的,但答案是,“......函数的 URL 将静默失败,而不会引发错误或异常。”这可能会破坏应用程序。虽然这个答案不是很好,但它确实突出了一个问题。尤其是如果您的应用程序可能被某人任意发出请求并抛出额外参数而崩溃。

以上是关于将查询字符串解析为数组的主要内容,如果未能解决你的问题,请参考以下文章

PHP 将url查询字符串解析为数组

将 JSON 查询字符串解析为 JSON 对象

php怎么将mysql查询的数组中 的(数字)字符串类型转为数字类型

使用gson解析怎么将json字符串解析为数组

利用PHP的字符串解析特性Bypass

将字符串解析为 int 数组