Convert a structured array of strings into a nested array for PHP

November 25, 2012

It’s a long title, I agree, but I’ll try to explain simply what I wanted to do.

Let’s consider the following PHP associative array.

<?php

$data = array(
    &#39;mysql_host&#39;            =&gt; &#39;localhost&#39;,
    &#39;mysql_db&#39;              =&gt; &#39;mydatabase&#39;,
    &#39;mysql_password&#39;        =&gt; &#39;mypass&#39;,
    &#39;foo&#39;                   =&gt; &#39;bar&#39;,
    &#39;some_very_long_path&#39;   =&gt; &#39;some data&#39; 
);

?>

I want to convert to a nested array like:

<?php

$data = array(
    &#39;mysql&#39; =&gt; array(
        &#39;host&#39; =&gt; &#39;localhost&#39;,
        &#39;db&#39;   =&gt; &#39;mydatabase&#39;,
        &#39;password&#39; =&gt; &#39;mypass&#39;
    ),
    &#39;foo&#39; =&gt; &#39;bar&#39;,
    &#39;some&#39; =&gt; array(
        &#39;very&#39; =&gt; array(
            &#39;long&#39; =&gt; array(
                &#39;path&#39; =&gt; &#39;some data&#39;
            )
        )
    )
);

?>

Ideas beyond that, is to convert the array into an YAML config, but the important part is that I can’t assume how deeply nested will be the array. Here the corresponding YAML configuration file, for example purpose.

mysql:
    host: localhost
    db: mydatabase
    password: mypass
foo: bar
some:
    very:
        long:
            path: some data

So, here the solution that I came up, using a reference, to keep track of the positionning of the constructed array.

<?php

function postToArray ($post) {
    $config = array();

    foreach ($post as $key =&gt; $value) {

        $reference = &amp;$config;
        $path = explode(&#39;_&#39;, $key);

        for ($i=0; $i &lt; sizeOf($path); $i++) {
            if ($i == sizeOf($path)-1) {
                $reference[$path[$i]] = $value;
            } else {
                if (!array_key_exists($path[$i], $reference)) {
                    $reference[$path[$i]] = array();
                }
                $reference = &amp;$reference[$path[$i]];
            }
        }
    }

    return $config;
}

?>

I’ll be more than happy if someone could point me at a better solution. Hope it could help someone else than myself.

EDIT: thanks to Nicoon, for his solution on Reddit, that use a recursive function, and point out that HTTP allow this already nicely.

Tweet

Related-ish Posts

About

I'm Nicolas Paris, aka Nic0, I like to share about programming and Linux tricks. Follow me on Twitter, where the content is pretty much like here, mainly programming stuff. Or visite my website