Friday 31 August 2018

PHP Create a multidimensional array from the keys

Is there a way to create dynamicaly multidimensional array? I have stored in database "path" for each field=>value like that:

field_name : [slideshow][slide][0][title]
field_value : my title

field_name : [slideshow][slide][0][desc]
field_value : my desc

field_name : [slideshow][slide][1][title]
field value : my other title

field_name : [slideshow][slide][1][desc]
field value : my other desc

field_name : [slideshow][settings][duration]
field value : 300

and now I'm trying to figure out how to make it an array again. Obviously there can be lots of fields and complexity so I wanted to avoid some recursions if possible, cause I'm not sure how it will impact performance.
I was playing around with variable variables and trying something like:
$array_name = 'arr';
${$array_name}[slideshow][slide][1][title] = $field->field_value;
print_r($arr);

but this works only if its literally that, and nothing like this works:
${$array_name}.$field->field_name = $field->field_value;

I basically need to store every field as individual row (e.g. for searches in those fields), values can be diffrent types (even serialized arrays), and contain html.
Any advice appreciate.

The basic idea is to split up your field_name string and loop over the parts backward to build up the array. Some recursion is used to merge the arrays, though any performance impact should be negligible.

Example:

// Set up sample data.
$field = new stdClass();
$field->field_name = '[slideshow][slide][0][title]';
$field->field_value = 'my title';
$fields[] = $field;

$field = new stdClass();
$field->field_name = '[slideshow][slide][0][desc]';
$field->field_value = 'my desc';
$fields[] = $field;

$field = new stdClass();
$field->field_name = '[slideshow][slide][1][title]';
$field->field_value = 'my other title';
$fields[] = $field;

$field = new stdClass();
$field->field_name = '[slideshow][slide][1][desc]';
$field->field_value = 'my other desc';
$fields[] = $field;

$field = new stdClass();
$field->field_name = '[slideshow][settings][duration]';
$field->field_value = '300';
$fields[] = $field;
// End sample data.

// array_merge_recursive() doesn't do what we want with numeric keys, so use this
function merge($base, $array) {
    foreach ($array as $key => $value) {
        if (isset($base[$key]) && is_array($base[$key]) && is_array($value)) {
            $base[$key] = merge($base[$key], $value);
        } else {
            $base[$key] = $value;
        }
    }
    return $base;
}

$result = [];
foreach ($fields as $field) {
    $parts  = array_reverse(explode('][', trim($field->field_name, '[]')));
    $value = $field->field_value;
    foreach ($parts as $part) {
        $value = [$part => $value];
    }
    $result = merge($result, $value);
}
print_r($result);


Output:

Array
(
    [slideshow] => Array
        (
            [slide] => Array
                (
                    [0] => Array
                        (
                            [title] => my title
                            [desc] => my desc
                        )

                    [1] => Array
                        (
                            [title] => my other title
                            [desc] => my other desc
                        )

                )

            [settings] => Array
                (
                    [duration] => 300
                )

        )

)

0 comments:

Post a Comment