简体   繁体   中英

PHP is there a way to add elements calling a function from inside of array

I want to add multiple values from inside of array calling a function:

$header = array(
  'name',
  'surname',
  _create_days(),
  'total'
);

So output be like

$header = array(
  'name',
  'surname',
  '2016-01-01',
  '2016-01-02',
  ....
  'total'
);

I've tried with array_push, array_merge but didn't work.

It doesn't work the way you wrote it in the question. The function _create_days() is called and it returns a value that replaces the function call. Even if the function returns multiple values in an array, the array as a whole is placed in the outer array you want to build.

The solution is to write the function _create_days() to return an array of values and merge this returned array into the outer array using array_merge() for example:

function _create_days()
{
    return array(
        '2016-01-01',
        '2016-01-02',
    );
}

$header = array_merge(
    array(
        'name',
        'surname',
    ),
    _create_days(),
    array(
        'total',
    )
);

Another option is to use a placeholder when you build $header and replace it later with the values returned by _create_days() using the function array_splice() :

$header = array(
    'name',
    'surname',
    '@days@',           // this is the placeholder
    'total',
);

// Replace the placeholder with the values returned by _create_days()
array_splice(
    $header,
    array_search('@days@', $header),
    1,
    _create_days()
);

In order to make the code flexible I used the function array_search() to find the position of the placeholder in $headers . This way, if you add or remove elements before '@days@' the code still works without any adjustment.

If you're willing to iterate through the array after you've created it, you can simply use special values for callbacks that you want to call:

Example:

<?php

function _create_days() {
    return [
        '2016-01-01',
        '2016-01-02',
    ];
}

$header = [
  'name',
  'surname',
  ['_create_days'], // We know it's a callback because it's an array
  'total',
];

$headerNew = [];

foreach ($header as $value) {
    if (is_array($value)) {
        // If the length of $value is above 1 then it's a class callback, else just set it to the first item
        $callback = count($value) > 1 ? $value : $value[0];

        // Get the actual array from the callback
        $value = call_user_func($callback);

        // Merge the $headerNew array with the new values
        $headerNew = array_merge($headerNew, $value);
    } else {
        // It's not a callback, just use the actual value
        $headerNew[] = $value;
    }
}

print_r($headerNew);

Output:

Array
(
    [0] => name
    [1] => surname
    [2] => 2016-01-01
    [3] => 2016-01-02
    [4] => total
)

DEMO


Note:

If you have any actual arrays in the $header array this makes things a little more difficult, as we can't check if you're using an array. For that you can simply create an instance of a class:

<?php

// (_create_days function)

class ValueCallback {
    protected $callback;

    public function __construct($callback) {
        if (is_array($callback)) {
            $callback = count($callback) > 1 ? $callback : $callback[0];
        }

        $this->callback = $callback;
    }

    public function getValue() {
        return call_user_func($this->callback);
    }
}

$header = [
  'name',
  'surname',
  new ValueCallback('_create_days'),
  'total',
];

$headerNew = [];

foreach ($header as $value) {
    if ($value instanceof ValueCallback) {
        // Get the actual array from the callback
        $value = $value->getValue();

        // Merge the $headerNew array with the new values
        $headerNew = array_merge($headerNew, $value);
    } else {
        // It's not a callback, just use the actual value
        $headerNew[] = $value;
    }
}

print_r($headerNew);

DEMO

From PHP7.4, just unpack/spread your function's return value directly into the result array with ( ... -- the spread operator).

Code: ( Demo )

function _create_days() {
    return ['2016-01-01', '2016-01-02'];
}

$header = [
    'name',
    'surname',
    ..._create_days(),
    'total',
];

var_export($header);

Output:

array (
  0 => 'name',
  1 => 'surname',
  2 => '2016-01-01',
  3 => '2016-01-02',
  4 => 'total',
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM