使用键最快地将关联数组压缩为字符串的方法

135
我正在寻找一种快速将关联数组转换为字符串的方法。典型的结构类似于URL查询字符串,但具有可定制的分隔符,因此我可以在XHTML链接中使用“&”或在其他情况下使用“&”。
我的第一反应是使用foreach,但由于我的方法可能在一个请求中被多次调用,所以我担心这可能会太慢。
<?php
$Amp = $IsXhtml ? '&amp;' : '&';
$Parameters = array('Action' => 'ShowList', 'Page' => '2');
$QueryString = '';
foreach ($Parameters as $Key => $Value)
        $QueryString .= $Amp . $Key . '=' . $Value;

有更快的方法吗?


4
如果输出HTML,请不要使用"&"符号,而是应该使用"&"符号作为语法正确的表示方式。例如,"<a href="?name=joe&age=22">JOE</a>"是正确的写法,虽然"<a href="?name=joe&age=22">JOE</a>"也能工作,但它并不是有效的HTML写法。 - TravisO
11个回答

188
你可以使用 http_build_query() 来实现这个功能。

从提供的关联数组(或索引数组)生成一个URL编码的查询字符串。


我自己也在尝试在PHP API中找到这个方法,这绝对是正确的方法。如果不是的话,另一种选择是使用修改后的implode方法,例如http://uk2.php.net/manual/en/function.implode.php#84684,但是http_build_query()会更快。 - Mark Davidson
2
我在想这是否真的是一般问题最快的方法。这个函数中有一些编码。所以,如果不是用于URL,这是否比array_walk更快,如果你不想进行编码呢? - e-motiv
17
问题是 http_build_query 函数无法转义特殊字符。 - Sisyphus
1
我比较了serialize()、json_encode()和http_build_query()。http_build_query()略胜一筹,而json_encode则明显最慢。 - ErnestV
8
它还编码了特殊字符,因此这不是一个好的选项。 - awavi
对于评论者来说,如果您不需要任何特殊字符呢?那么这个解决方案就是完美的。 - OZZIE

46

如果您不关心精确的格式,但是希望得到简单的输出,而又不想要print_r换行符,您也可以使用json_encode($value)来获得快速且简单的格式化输出。(请注意,它对其他数据类型也有效。)

$str = json_encode($arr);
//output...
[{"id":"123","name":"Ice"},{"id":"234","name":"Cake"},{"id":"345","name":"Pie"}]

36

顺便说一下,我在寻找最佳方法来将关联数组implode,并使用自己的分隔符等......

因此,我使用PHP的array_walk()函数来让我将关联数组连接成参数列表,然后应用于HTML标记....

// Create Params Array
$p = Array("id"=>"blar","class"=>"myclass","onclick"=>"myJavascriptFunc()");

// Join Params
array_walk($p, create_function('&$i,$k','$i=" $k=\"$i\"";'));
$p_string = implode($p,"");

// Now use $p_string for your html tag

显然,你可以将它放入自己的函数中,但这给了你一个想法,即如何使用自己的方法连接关联数组。 希望能对某人有所帮助 :)


6
如果有人觉得create_function的语法很难理解,可以查看http://php.net/manual/en/function.create-function.php。 - Matt Fletcher
array_walk比foreach更慢,而且更难读取。请参见:http://www.reddit.com/r/PHP/comments/1uuc34/quick_test_to_see_if_array_walk_is_better_than/ - Enyby
发现这个版本很有用,因为http_build_query()编码URL。 - Ernesto Allely

23

这是我对具有div数据属性的示例的解决方案:

<?

$attributes = array(
    'data-href'   => 'http://example.com',
    'data-width'  => '300',
    'data-height' => '250',
    'data-type'   => 'cover',
);

$dataAttributes = array_map(function($value, $key) {
    return $key.'="'.$value.'"';
}, array_values($attributes), array_keys($attributes));

$dataAttributes = implode(' ', $dataAttributes);

?>

<div class="image-box" <?= $dataAttributes; ?> >
    <img src="http://example.com/images/best-of.jpg" alt="">
</div>

21

一种方法是使用 print_r(array, true),它将返回数组的字符串表示。


1
$request_str = print_r($_REQUEST, true); // 将数组展开以便写入日志文件 - zzapper
3
但是这将输出为print_r格式,而不是以提供的分隔符连接的key=value格式。 - Rikki

9

我的解决方案:

$url_string = http_build_query($your_arr);
$res = urldecode($url_string); 

我喜欢这种方法,因为它看起来比其他冗长的代码简单。尽管这不完全是我们想要的... 我们寻找这种格式:"key: value\r\n...." 所以我使用了这个公式:urldecode(str_replace("=", ": ", http_build_query($headers,"", "\r\n"))) 来得到它。请看下面提出的解决方案。 - fekiri malek

3

使用array_walk,代码更加简短、透明且更易于理解。

$attributes = array(
  'data-href'   => 'http://example.com',
  'data-width'  => '300',
  'data-height' => '250',
  'data-type'   => 'cover',
);

$args = "";
array_walk(
    $attributes, 
    function ($item, $key) use (&$args) {
        $args .= $key ." = '" . $item . "' ";  
    }
);
// output: 'data-href="http://example.com" data-width="300" data-height="250" data-type="cover"

2
function array_to_attributes ( $array_attributes )
{

    $attributes_str = NULL;
    foreach ( $array_attributes as $attribute => $value )
    {

        $attributes_str .= " $attribute=\"$value\" ";

    }

    return $attributes_str;
}

$attributes = array(
    'data-href'   => 'http://example.com',
    'data-width'  => '300',
    'data-height' => '250',
    'data-type'   => 'cover',
);

echo array_to_attributes($attributes) ;

2

使用一行代码从简单数组创建带引号的HTML属性字符串:

$attrString = str_replace("+", " ", str_replace("&", "\" ", str_replace("=", "=\"", http_build_query($attrArray)))) . "\"";

例子:

$attrArray = array("id"    => "email", 
                   "name"  => "email",
                   "type"  => "email",
                   "class" => "active large");

echo str_replace("+", " ", str_replace("&", "\" ", str_replace("=", "=\"", http_build_query($attrArray)))) . "\"";

// Output:
// id="email" name="email" type="email" class="active large"

1
使用array_walk来做这件事。
$arr = [
    "key"  => "value",
    "key2" => "value2",
];

array_walk($arr, function(&$value, $key) {
    $value = "{$key}: {$value}";
});

implode("<br/>", $arr)

结果

key: value<br/>key2: value2<br/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接