2

I have a PHP code which runs on PHP7 but not in PHP 5, which PHP version in my server, that is my code:

Array (
    [0] => stdClass Object (
        [userId] => 15
        [name] => name0
        [userName] => hh
        [centerName] => center10
    )

    [1] => stdClass Object (
        [userId] => 16
        [name] => name1
        [userName] => test
        [centerName] => center10
    )

    [2] => stdClass Object (
        [userId] => 1
        [name] => name2
        [userName] => ll
        [centerName] => center1
    )
)

$ids = array_unique(array_column($results, 'centerName'));
print_r($ids);

I get what I expected in PHP7 but I get an empty array in PHP5.

How can I adapt my code to work in PHP5?

u_mulder
  • 54,101
  • 5
  • 48
  • 64
Ali A. Jalil
  • 873
  • 11
  • 25
  • by the way if you need a polyfil, here's the link https://github.com/ramsey/array_column/blob/master/src/array_column.php, but if you just want a quick fix on one line, just use mulder's answer, it will work – Kevin May 23 '19 at 08:36

3 Answers3

3

As from manual, ability to use array of objects as parameter to array_column is added since php7.0.

In php5 you simply cannot use array_column to get columns from array of objects. So, you need to use some other code, a simple foreach for example:

$uniqueValues = [];
foreach ($results as $item) {
    $uniqueValues[$item->centerName] = 1;
}
print_r(array_keys($uniqueValues));
u_mulder
  • 54,101
  • 5
  • 48
  • 64
1

In the manual to array_column you can get code how to use array_column legacy code on older versions of PHP.
I like this method as it also incorporate the third parameter.

if (!function_exists('array_column')) {
    function array_column($array, $columnKey, $indexKey = null)
    {
        $result = array();
        foreach ($array as $subArray) {
            if (is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
                $result[] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
            } elseif (array_key_exists($indexKey, $subArray)) {
                if (is_null($columnKey)) {
                    $index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                    $result[$index] = $subArray;
                } elseif (array_key_exists($columnKey, $subArray)) {
                    $index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                    $result[$index] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
                }
            }
        }
        return $result;
    }
}

And in your case the code would be the above and:

$ids = array_keys(array_column($results, 'name' ,'centerName'));
print_r($ids);

This puts the centername as keys and name as value meaning it will remove all duplicates automatically, then just grab the keys.

Array_column is a great function to have in your project.

Andreas
  • 23,610
  • 6
  • 30
  • 62
  • _Array\_column is a great function to have in your project_. I couldn't agree more! There are some great things you can do with it: look at [this PR](https://github.com/laravel/framework/pull/27583) I submitted to utilise that third parameter. – JustCarty May 23 '19 at 15:07
1

I thought I'd offer another solution, despite the solutions provided by @u_mulder and @Andreas being great answers.

function new_array_column($input , $column_key, $index_key = null) {
    $result = array();
    array_walk($input, function($value, $key) use (&$result, $column_key, $index_key) {
        $result[empty($index_key) ? $key : is_object($value) ? $value->{$index_key} : $value[$index_key]]
        = empty($column_key) ? $value : (is_object($value) ? $value->{$column_key} : $value[$column_key]);
    });
    return $result;
}

This accepts all the parameters that the new array_column does, but is kept nice and concise by using the array_walk.

The code looks horrible but it is fairly straight forward, but here is a brief description:

  1. Determine whether an $index_key was passed, if it was then set that key now, otherwise use the original key.
  2. Check whether a $column_key was specified.
    2.1. If no $column_key is passed, then use the entire value.
    2.2. Otherwise, use the value from that column.

I have tested this on PHP 5.3.0, which is the earliest version this code will work on. (The earlier version don't accept an anonymous function in the array_walk function, it must be passed as a string).

JustCarty
  • 3,839
  • 5
  • 31
  • 51