A maneira mais rápida de implodir uma matriz associativa com chaves

114

Estou procurando uma maneira rápida de transformar uma matriz associativa em uma string. A estrutura típica seria como uma string de consulta de URL, mas com separadores personalizáveis ​​para que eu pudesse usar ' &' para links xhtml ou ' &' de outra forma.

Minha primeira inclinação é usar, foreachmas como meu método pode ser chamado muitas vezes em uma solicitação, temo que seja muito lento.

<?php
$Amp = $IsXhtml ? '&amp;' : '&';
$Parameters = array('Action' => 'ShowList', 'Page' => '2');
$QueryString = '';
foreach ($Parameters as $Key => $Value)
        $QueryString .= $Amp . $Key . '=' . $Value;

Existe uma maneira mais rápida?

Matpie
fonte
4
Não se esqueça de que, se estiver gerando HTML, a sintaxe correta é & amp; não &, iow isto está errado <a href="?name=joe&age=22"> JOE </a> sim, funciona, mas é HTML inválido.
TravisO

Respostas:

174

Você pode usar http_build_query()para fazer isso.

Gera uma string de consulta codificada por URL a partir da matriz associativa (ou indexada) fornecida.

Greg
fonte
Estava tentando encontrar esse método na API do PHP, este é definitivamente o caminho a percorrer. Caso contrário, a alternativa é usar um método de implode modificado, como uk2.php.net/manual/en/function.implode.php#84684, mas http_build_query () será apropriadamente mais rápido.
Mark Davidson
Eu me pergunto se esse é realmente o caminho mais rápido para a questão geral. Existe alguma codificação nesta função. Então, se não for por um URL, isso é realmente mais rápido do que array_walk e se você não quiser codificá-lo?
e-motiv
10
o problema é http_build_queryescapar char especial
Sísifo
1
Eu comparei serialize (), json_encode () e http_build_query (). http_build_query () ganhou por uma pequena margem sobre serialize (), e json_encode sendo o mais lento de longe.
ErnestV
5
Ele também codifica caracteres especiais, então esta não é uma boa opção
awavi
33

Como um aparte, eu estava procurando encontrar a melhor maneira de implodir uma matriz associativa, mas usando meus próprios separadores etc ...

Então, fiz isso usando a função array_walk () do PHP para me permitir juntar um array associativo em uma lista de parâmetros que poderiam ser aplicados a uma tag 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

Obviamente, você poderia colocar isso em sua própria função de alguma forma, mas dá uma ideia de como você pode juntar um array associativo usando seu próprio método. Espero que ajude alguém :)


fonte
6
Se a sintaxe de create_function está confundindo alguém, consulte php.net/manual/en/function.create-function.php
Matt Fletcher
array_walk é mais lento de foreach e mais complicado para leitura. Veja em: reddit.com/r/PHP/comments/1uuc34/…
Enyby
Achei esta versão útil como a primeira solução, pois http_build_query () codifica URLs.
Ernesto Allely,
32

Se você não está preocupado com a formatação exata, você quer algo simples, mas sem as quebras de linha, print_rvocê também pode usar json_encode($value)para uma saída formatada rápida e simples. ( observe que também funciona bem com outros tipos de dados )

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

Esta é minha solução, por exemplo, para um div data-attribute:

<?

$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>
user4846194
fonte
18

Uma maneira é usar print_r(array, true)e ele retornará a representação de string da matriz

dino.keco
fonte
1
$ request_str = print_r ($ _ REQUEST, true); // nivelar matriz para arquivo de log
zzapper
2
Mas isso resulta no formato print_r, não como key=valueassociado a um separador fornecido.
Rikki
1
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) ;
Softmixt
fonte
1

Uma linha única para a criação de strings de atributos HTML (com aspas) a partir de uma matriz simples:

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

Exemplo:

$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"
WackGet
fonte
1

Minha solução:

$url_string = http_build_query($your_arr);
$res = urldecode($url_string); 
Kostikovmu
fonte
0

E quanto a este mais curto, mais transparente, mas mais intuitivo com 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"
FantomX1
fonte
-2

Esta é a versão mais básica que consigo pensar:

public function implode_key($glue = "", $pieces = array())
{
    $keys = array_keys($pieces);
    return implode($glue, $keys);
}
Justin
fonte
12
Isso só implode as chaves, não implode key=valuecom um separador escolhido!
Rikki
-3
echo implode(",", array_keys($companies->toArray()));

$companies->toArray()- isso é apenas para o caso de você $variableser um objeto, caso contrário, basta passar $ empresas.

É isso aí!

Hardik Raval
fonte
Isso apenas adiciona as chaves à string; os valores estão perdidos.
FluffyKitten