PHP. Можно ли использовать array_column с массивом объектов

Можно ли передать array_column массив объектов?
Я реализовал интерфейс ArrayAccess, но он не имеет никакого эффекта.
Должен ли я реализовать еще один?

 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) с 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) 

PHP 5

array_column не работает с массивом объектов. array_map этого используйте array_map :

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

PHP 7

array_column()

Функция теперь поддерживает массив объектов, а также двумерные массивы. Учитываются только публичные свойства, а объекты, которые используют __get() для динамических свойств, также должны реализовывать __isset() .

См. https://github.com/php/php-src/blob/PHP-7.0.0/UPGRADING#L629 – Спасибо Белу за подсказку!

Можно ли передать array_column массив объектов?

PHP 7

Да, см. http://php.net/manual/en/function.array-column.php

PHP 5> = 5.5.0

В PHP 5 array_column не работает с массивом объектов. Вы можете попробовать:

 // 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: для ясности я предпочитаю не использовать array_column и использовать array_map с анонимной функцией

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

или простой foreach

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

Возможное решение – подготовить массив массивов:

 $objectsList = []; foreach ($objs as $obj) { $objectsList[] = (array)$obj; } $propList = array_column($objectsList, 'prop'); 

Хотя нельзя использовать array_column для дочерних объектов, вы можете использовать их для массивов. Это, конечно, не путь, но это путь.

Использование array_map/get_object_vars (не работает в вашем случае из-за содержащего массива)

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

Использование json_decode/json_encode

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

https://eval.in/597950

Примечание. Использование json не приводит к тому же результату, что и при использовании истинной рекурсивной функции. Вы потеряете защищенные и частные свойства объекта. Но в некоторых ситуациях это прекрасно.

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

Для будущего посетителя.

 $arrayColumnData = array_map(function($e) { return is_object($e) ? $e->your_column : $e['your_column']; }, $yourArray); 

Благодарю.

Если вы не хотите изменять каждый фрагмент кода, который вы уже писали, потому что ваш prod-сервер находится на php5, а не php7

Вот портативная функция

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

Затем вы можете использовать его при использовании array_column в php7

Это не лучшая производительность из-за array_fill, но она работает.

Примечание. Вы можете переопределить собственный массив array_column php с этой функцией, поэтому вам не нужно ничего менять при переключении php7 / php5