2

I'm looking for a short, built-in way to get a flat array from the values (I'm not interested in the array keys) of a multidimensional array in PHP.

Is there something any built-in function to get an array of elements (which are not an array) from a multidimensional array? I searched for array_flat or similar keywords but found nothing.

Although I'm looking for an efficient way to get a flat array in PHP, what I really would like is to use array_filter in the following: way.

$result = array_filter($array, '!is_array')

Or maybe:

$result = array_filter($array, 'is_array === false')

However, the code above does not work.

The following solutions work, but they are not what I want.

1st solution:

$result = array_diff(array_values($array), array_filter(array_values($array), 'is_array'));

2nd solution:

$result =  (array_filter(array_values($args), function($value) {
  if(!is_array($value)) {
    return $value;
  }
}));;

I could also try to use foreach or array_map, but I want to write less code.

Why is this? Basically, to help me with file uploads and form validation, I'm building a class called Validator, which will take callbacks (as many as I want) and will execute then. It is possible to pass a callback to run before validation, during validation, and after validation. These are the main callbacks; for each main callback, it is possible to pass an 'onfailure' callback to run if the main callback fails and an 'onsuccess' callback if it succeeds. The Validator class will be pretty flexible and customized regard its arguments when adding a function, so I need to create a slightly complex code to find which argument is which. The arguments may have nested arrays, and that's why I wanted an efficient way to flatten the nested arrays.

The addCallback method of my Validtor Class will be able to receive the following arguments:

    'aftervalidation', $callback, $args
    ['onvalidation', 'callback' => $callback, 'args' => $args]
    ['onvalidation', [callback => $callback, 'args' => $args], ]
    ['onvalidation', [$callback, 'args' => $args], ['onsuccess' => $callback, 'args'=> args]]
    ['aftervalidation', ['callback', 'args' => $args], ['onsuccess' => $callback, $args]]
    ['beforevalidation', ['callback;, 'args' => $args], ['onsuccess' => $callback,]]
    ['aftervalidation', [$callback, 'args' => $args], ['onsuccess' => $callback', 'args' => args]]
    ['onvalidation', ['callback' => $callback, 'args' => $args], ['onsuccess' => $callback', $args]]
    ['beforevalidation', ['callback' => $callback, $args], ['onsuccess' => $callback']]
    ['aftervalidation', [$callback, 'args' => $args], 'onsuccess' => [$callback]]
    ['onvalidation', [$callback, 'args' => $args], 'onsuccess' => [$callback, args]]
    ['onvalidation', [$callback, 'args' => $args], 'onsuccess' => [$callback, 'args' => $args]]
    ['onvalidation, [$callback, 'args' => $args], 'onsuccess' => ['callback' => $callback, 'args' => $args]]

Besides these nested arrays, the $args may be an array of args for the callback. So I need to flat these arrays to figure out which arguments is which.

Notes: For personal reasons, to create my custom function for it is not an option.

PHP version is 7.3

2 Answers2

2

It is not recommend as its raise notice but you can use array-keys and array-flip (with adding @ to avoid the notice) as:

$a = @array_keys(array_flip($arr));

This will work as array_flip will encounter an notice as array cannot be key -> so it practically filter the non-array - BUT this is not the best practice! I do recommend you write your custom function - didn't understand why you cannot do so...

Live example: 3v4l

dWinder
  • 11,597
  • 3
  • 24
  • 39
2

I think you want the scalar values to be retained (but you haven't yet shown any sample data, so I can't be sure).

Code: (Demo)

$array = [3, "AA", [1,2], 444, ["V"]];
var_export(array_filter($array, 'is_scalar'));

Output:

array (
  0 => 3,
  1 => 'AA',
  3 => 444,
)

Thr PHP Docs: https://www.php.net/manual/en/function.is-scalar.php

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • Nice - better answer than mine - I loved the example data ;) – dWinder Jul 22 '19 at 13:18
  • There's a fair chance that yours is more performant, but I go out of my way to avoid the stfu operator. Furthermore, yours is indexed -- if it matters. (Sorry to pinch your input array, I'm on my phone.) – mickmackusa Jul 22 '19 at 13:18
  • 1
    @dWinder on the other hand, some scalar values may be mutated by your key technique and duplicate values will parish. – mickmackusa Jul 22 '19 at 13:25
  • No problem - I put it there for share. And I'm totally agreed about stfu - I tried to make it as clear as I can it is bad practice. You are right about the duplication - good point!. I wondering if I should keep my post or delete it - let future users decide what they prefer. – dWinder Jul 22 '19 at 13:27
  • It seems to be EXACTLY what I was looking for!! – Student of Science Jul 22 '19 at 13:28
  • By the way, I provided sample code on the question. – Student of Science Jul 22 '19 at 13:31
  • ...yeah, you'll get better at posting in time ... ;) – mickmackusa Jul 22 '19 at 13:32