1

I have a very complex array which contains many other very complex nested arrays. I want to break up some of the inside array groups into separate variables outside of the main variable for readability, however I'm not sure what the correct syntax is for having a list of multiple arrays in a single variable.

Wrapping the list of arrays in an array while declaring the variable isn't an option, as the variable will be inserted inside the wrapper array later on in the $array variable, so the list of arrays need to be on their own and not inside an array in the $sub_arrays variable.

<?php

$sub_arrays = array(), array(), array(); // syntax error

$array = array(
    'template' => array(
        array(
            array(),
            array(
                array(),
                // syntax error
                $sub_arrays,

                // this works, but need to be declared outside
                // array(), array(), array(),
                array(),
            )
        ),
    ),
);

print_r($array);

https://3v4l.org/2EvRA

Alternatively, separating some of the sub arrays into another .php file and using include() and return would also be an option instead of the variable? But I'm not sure about the syntax of that either.

Separation would be good not just for readability, but in case a particular group of arrays need to be reused in another instance as well.

The data is a WordPress block editor (Gutenberg) template with a lot of nested group and column blocks inside other blocks. https://developer.wordpress.org/block-editor/developers/block-api/block-templates/#nested-templates

Is this even possible to do in PHP?

4
  • 1
    Readability is subjective, how is the data coming in, or will it be hard coded? More specifically, are you asking about proper Array syntax or how to include other files? Commented Oct 25, 2019 at 21:30
  • The example is a reduced/simplified case. The data is going to be hardcoded, but things become really unreadable as the 3 arrays in question also contain a whole bunch of other arrays inside of them as well. Commented Oct 25, 2019 at 21:33
  • The data is a WordPress block editor template with a lot of nested group and column blocks inside other blocks. developer.wordpress.org/block-editor/developers/block-api/… Commented Oct 25, 2019 at 21:36
  • Would creating a class instead and extending ArrayObject be an option? Commented Oct 28, 2019 at 20:16

5 Answers 5

4

New Answer:

Based on the comments below I think I understand the problem. I can think of two solutions to this.

First solution: The first one is the easy one, but you need PHP 7.4+ for it to work.

You can use a new feature called the slant operator (...) where by you can "unpack" one array into another. Here is the example:

<?php
$sub_arrays = [array("middle" => "array"), array(), array("external"=>"array")];

$array = array(
    'template' => array(
        array(
            array(),
            array(
               array('first'=>"array"),
                ...$sub_arrays, // use it here
                array('last'=>"array")
            )
        ),
    ),
);

print_r($array);

Live demo: https://3v4l.org/s4Q8u

Second solution: This is a bit more complex that the first one. It involves wrapping the array into a function and dynamically creating the parent array of $sub_arrays. See this:

<?php
$sub_arrays = [array("middle" => "array"), array(), array("external"=>"array")];

function create_array($sub) {
    $parent_array[] = array('first'=>"array");

    foreach($sub as $s)
    {
         $parent_array[] = $s;
    }

    $parent_array[] = array('last'=>"array");

    $array = array(
        'template' => array(
            array(
                array(),
                $parent_array
            ),
        ),
    );

    return $array;
}
print_r(create_array($sub_arrays));

Live demo: https://3v4l.org/1Vahd

I hope this helps.


Old Answer:

Your questions leaves out a lot of details to understand why you are trying to do this.

For example:

Wrapping the list of arrays in an array while declaring the variable isn't an option,

how is $sub_array inserted in $array, at what stage, are they inside a class or a function?

In any case, from what I understood, I think list is what you are looking for.

See this example:

<?php
list($a, $b) = [array('example' => 'test'), array('another' => 'array')];


var_dump($a, $b);

you can also use list for nested arrays like so:

list($a, list($b, $c)) = [array('example' => 'test'), array(array('another' => 'array'), array('I am nested'=>'array'))];

var_dump($a, $b, $c);
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for introducing me to list(), however it's not what I'm looking for as even with list() I'll still need a separate variable for every sub array. I don't want $a, $b and $c each containing a single array, instead just $sub_arrays that contains $a, $b and $c. If I wanted separate variables, I wouldn't need list() as I could just declare my sub arrays like $a = array(); $b = array(); I need something like $sub_arrays = array(), array(), array(); $sub_arrays will be inserted inside $array alongside other arrays before and after the inclusion of $sub_arrays like in the example.
The use case is registering WordPress custom post type using register_post_type() and declaring a block editor template inside the register_post_type() function. The main $array is the 'template' => array() inside $args while the arrays inside $sub_arrays would be the individual blocks i.e array( 'core/image'). I want to declare some blocks directly inside 'template' => array(), but I want to include some blocks from outside. developer.wordpress.org/block-editor/developers/block-api/…
I think I understand the question now. See my updated my answer.
Yes, thank you very much. The (...) operator seems to be doing exactly what I want where all of the 3 inserted + 2 existing sub arrays will be on the same level. 3v4l.org/Dbqt7 It's a pity PHP 7.4 is still in RC phase and might take a bit of time before it's adopted by hosting providers and is actually usable in the real world. However, a small correction of your answer, "..." seems to be called the spread operator in PHP and the splat operator in some other languages, and not a "slant operator" as that name doesn't turn up any results anywhere.
1

Could you try this:

<?php

$sub_arrays = array(array(), array(), array()); // no syntax error

$array = array(
    'template' => array(
        array(
            array(),
            array(
                array_merge(
                array(array()),
                $sub_arrays),
                 array(),
            )
        ),
    ),
);

print_r($array);

To make it work, you have to merge your "outsider" array with the existing one. The existing one must be encapsulated in an array

Comments

1

Im not sure what you are asking for, but if it is how to create array variables and use them later, then here is an example. I took the WordPress example you linked in the comments. This is the template arrays broken down into sections. The structure seems to follow a pattern, hopefully this clarifies it.

$templateTop = array(
    'core/paragraph'        =>  array(
        'placeholder'           =>  'Add a root-level paragraph',
    )
);

$column1 = array(
    'core/column',
    array(),
    array(
        array(
            'core/image',
            array()
        ),
    )
);

$column2 = array(
    'core/column',
    array(),
    array(
        array(
            'core/paragraph',
            array(
                'placeholder' => 'Add a inner paragraph'
            )
        ),
    )
);

$templateColumns = array(
    'core/columns',
    array(),
    array(
        $column1, $column2
    )
);

$template = array(
    $templateTop, $templateColumns
);

1 Comment

I already know how to put 1 array per variable like that, but what if I want to put 2 arrays into 1 variable (or 3 arrays like in my example... or 4, or 5), i.e instead of creating $column1, $column2 - just have a $columns variable that will contain both $column1 and $column2.
1

You may prefer the shorter array syntax available since PHP 5.4

<?php

$arr1 = ['a', 'b', 'c'];      // >= 5.4
$arr2 = array('a', 'b', 'c'); //  < 5.4

See here for information about short syntax and arrays in general: https://www.php.net/manual/en/language.types.array.php

Using the short syntax your nested array may look like this:

<?php

$arr = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];

The example above is a two dimensional nested array. The outer array has three elements which are arrays itself.

In order to include / require an array (or any other value) from another PHP file just do it like so $returnValue = require('./other_file.php').

In other_file.php something like this will work:

<?php

return [
    [
        [1, 2, 3],
        [4, 5, 6],
    ],
    [
        [9, 8, 7],
        [6, 5, 4],
    ],
];

Hope this helps.

Comments

1
+50

I'm going to attempt to simplify the problem, and define some variables as follows

$firstArray = $a; 
$subArrays = [$i, $j, $k]; 
$lastArray = $z;

where $a, $i, $j, $k, and $z are all arrays

I believe what you are trying to achieve is

$result = [$a, $i, $j, $k, $z]

without referencing the variables $a, $i, $j, $k, or $z


This can be achieved using array_merge(), providing that the arrays are not associative with duplicate keys

$result = array_merge([$firstArray], $subArrays, [$lastArray]);

Which is equivalent to

$result = array_merge([$a], [$i, $j, $k], [$z]);

By wrapping the $firstArray and $lastArray in arrays of their own, this puts them at the same level of nesting as the $subArrays before combining them all into one array


Applying this all to your original problem, and using the longer syntax, results in

$sub_arrays = array(array(), array(), array()); // Wrapped

$array = array(
    'template' => array(
        array(
            array(),
            array_merge(
                array(array()), // Wrapped
                $sub_arrays,
                array(array()), // Wrapped
            ),
        ),
    ),
);

2 Comments

Thank you for expanding/improving on Florent's answer above for using array_merge(), now I understand what the idea is a bit better and that all the arrays have to be wrapped in order to be on the same level. Using your example, the output will be equivalent to the spread operator but will actually work on PHP <7.4.
You are welcome! Yeah, it's a bit of a tricky one, bring on the spread :)

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.