PHP.是否可以将array_column与对象数组一起使用


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

是否可以在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)

PHP 5

array_column不适用于对象数组。改为使用array_map

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

PHP 7

array_column()

该函数现在支持对象数组以及二维阵列。只考虑公共财产,并且将__get()用于动态属性的对象也必须实现CCD_ 6。

请参阅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;
}

这里有一个函数可以在php7和php5-上工作

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

然后,您可以像在php7 中使用array_column一样使用它

虽然不能在子对象上使用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;
}

可能的解决方案是准备对象数组:

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