3

Let's say I have the following string in my variable:

$arr['data_|_multilanguage_|_en_|_field'] = 23;

I want to transform that into a multidimensional array as follows:

$arr['data']['multilanguage']['en']['field'] = 23;

I did a recursive function

foreach ($arr as $outer_key => $outer_value) {

    $parts = explode('_|_', $outer_key);

    $reference =& $arr;
    $final_key = count($parts) - 1;
    
    foreach ($parts as $key => $part) {
        if (!$final_key == $key) {
                    
            if (empty($reference[$part])) {
                $reference[$part] = array();
            }

            $reference =& $reference[$part];

        } else {
            $reference[$part] = $arr[$str];
            unset($arr[$outer_key]);
        }
    }
}

The problem is that the var_dump shows that the children are reference. Is there a better way?

3

3 Answers 3

2

You just have a wrong if() statement :

 if (!$final_key == $key) {}

! will be evaluated before ==.
Change it for :

 if ($final_key != $key) {}

(you've got another little issue in your final $reference[$part] = assignment, I corrected it in the following code)

$arr['data_|_multilanguage_|_en_|_field'] = 23;

foreach ($arr as $outer_key => $outer_value) {

    $parts = explode('_|_', $outer_key);

    $reference =& $arr;
    $final_key = count($parts) - 1;

    foreach ($parts as $key => $part) {

        if ($final_key != $key) { 

            if (empty($reference[$part])) {
                $reference[$part] = array();
            }

            $reference =& $reference[$part];

        } else {
            $reference[$part] = $outer_value;
            unset($arr[$outer_key]);
        }
    }
}

And here is your result !

array(1) {
  ["data"]=>
  array(1) {
    ["multilanguage"]=>
    array(1) {
      ["en"]=>
      &array(1) {
        ["field"]=>
        int(23)
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

and $reference[$part] = $arr[$str]; should be $reference[$part] = $outer_value;
@palindrom I just saw it while writing my post, thanks.
thanks this solution (with some minor modifications) it worked for a problem I was having :)
0

This should work I think, pass in your (existing) array, wanted key (why not use dot notation instead of '_|_' ?), and your desired value

function array_set(&$array, $key, $value)
    {
        if (is_null($key)) return $array = $value;

        $keys = explode('_|_', $key);

        while (count($keys) > 1)
        {
            $key = array_shift($keys);

            // If the key doesn't exist at this depth, we will just create an empty array
            // to hold the next value, allowing us to create the arrays to hold final
            // values at the correct depth. Then we'll keep digging into the array.
            if ( ! isset($array[$key]) || ! is_array($array[$key]))
            {
                $array[$key] = array();
            }

            $array =& $array[$key];
        }

        $array[array_shift($keys)] = $value;

        return $array;
    }

Comments

0
<?php
$arr = array();
$arr['data_|_multilanguage_|_en_|_field'] = 23;
$arr['data_|_multilanguage_|_en_|_field2'] = 32;
$arr['data_|_multilanguage_|_fr_|_field'] = 57;
$arr['data_|_test'] = 57;
$arr['data_|_testing_|_var'] = 57;

function doArray(&$newarr,$keys,$value) {
    if(count($keys) > 1) {
        $key = array_shift($keys);

        if(!isset($newarr[$key]) || !is_array($newarr[$key])) {
            $newarr[$key] = array();
        }

        doArray($newarr[$key],$keys,$value);
    } else {
        $newarr[array_shift($keys)] = $value;
    }
}

$newarr = array();
foreach($arr AS $key => $value) {
    $keys = explode("_|_",$key);

    doArray($newarr,$keys,$value);
}

echo '<pre>';
print_r($newarr);
echo '</pre>';
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.