Eldar Rakhimberdin
Eldar Rakhimberdin

Reputation: 1102

PHP. Is it possible to use array_column with an array of objects

Is it possible to pass in array_column an array of objects?
I have implemented ArrayAccess interface, but it has no effect.
Should I implement another one?

class Foo implements ArrayAccess {

    public $Id, $Title;

    public function offsetExists($offset)
    {
        return isset($this->{$offset});
    }    

    public function offsetGet($offset)
    {
        return $this->{$offset};
    }

    public function offsetSet($offset, $value)
    {
        $this->{$offset} = $value;
    }

    public function offsetUnset($offset)
    {
        unset($this->{$offset});
    }
}

$object = new \Foo();
$object->Id = 1;
$object->Title = 'Test';

$records = array(
    $object, 
    array(
        'Id' => 2,
        'Title' => 'John'
    )
);

var_dump(array_column($records, 'Title')); // array (size=1) 0 => string 'John' (length=4)

Upvotes: 90

Views: 78856

Answers (6)

miken32
miken32

Reputation: 42700

Just so there's an explicit answer using array_column(): the code as given in the question will work with modern PHP versions since 7.0. array_column() will happily work with public object properties and/or array keys in the array elements:

$object = new \stdClass();
$object->Id = 1;
$object->Title = 'Test';
$records = [$object, ['Id' => 2, 'Title' => 'John']];
print_r(array_column($records, 'Title'));

Output:

Array
(
    [0] => Test
    [1] => John
)

Upvotes: 1

Tofandel
Tofandel

Reputation: 3585

Here is a function that will work on both php7 and php5

function array_column_portable($array, $key) {
    return array_map(function($e) use ($key) {
        return is_object($e) ? $e->$key : $e[$key];
    }, $array);
}

You can then use it as you use array_column in php7

Upvotes: 4

Okto
Okto

Reputation: 89

Possible solution is prepare that array of objects:

$objectsList = [];

foreach ($objs as $obj) {        
    $objectsList[] = (array)$obj;
}

$propList = array_column($objectsList, 'prop');

Upvotes: 0

cgaldiolo
cgaldiolo

Reputation: 3867

Is it possible to pass in array_column an array of objects?

PHP 7

Yes, see http://php.net/manual/en/function.array-column.php

PHP 5 >= 5.5.0

In PHP 5 array_column does not work with an array of objects. You can try with:

// object 1
$a = new stdClass();
$a->my_string = 'ciao';
$a->my_number = 10;

// object 2
$b = new stdClass();
$b->my_string = 'ciao b';
$b->my_number = 100;

// array of objects
$arr_o = array($a,$b);

// using array_column with an array of objects
$result = array_column(array_map(function($o){return (array)$o;},$arr_o),'my_string');

PS: for clarity I prefer to not use array_column and use array_map with an anonymous function

$result = array_map(function($o){ return $o->my_string; }, $arr_o);

or a simple foreach

$result = array();
foreach($arr_o as $o) {
    $result[] = $o->my_string;
}

Upvotes: 17

yckart
yckart

Reputation: 33408

While it's not possible to use array_column on child-objects, you can cast them to arrays. This is of course not the way to go, but it's a way.

Using array_map/get_object_vars (doesn't not work in your case, due the containing array)

array_column(array_map('get_object_vars', $thingy), 'property');

Using json_decode/json_encode

array_column(json_decode(json_encode($thingy), true), 'property');

https://eval.in/597950

Note: Using json brings not the same result as using a true recursive function. You’ll lose protected and private properties of the object. But in some situations its fine.

function object_to_array($object) {
  if (is_object($object)) $object = get_object_vars($object);
  return is_array($object) ? array_map(__FUNCTION__, $object) : $object;
}

Upvotes: 1

Daniel W.
Daniel W.

Reputation: 32340

PHP 5

array_column doesn't work with an array of objects. Use array_map instead:

$titles = array_map(function($e) {
    return is_object($e) ? $e->Title : $e['Title'];
}, $records);

PHP 7

array_column()

The function now supports an array of objects as well as two-dimensional arrays. Only public properties are considered, and objects that make use of __get() for dynamic properties must also implement __isset().

See https://github.com/php/php-src/blob/PHP-7.0.0/UPGRADING#L629 - Thanks to Bell for the hint!

Upvotes: 173

Related Questions