The
array_column()
Function
PHP 5.5 had already introduced a very useful function allowing you to retrieve a column from an array:
$data = [
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
];
var_dump(array_column($data, 2));
In this example, we retrieve the second column of the array (remember, counting starts from zero):
array(2) {
[0] =>
int(2)
[1] =>
int(7)
}
In PHP 7, the array_column()
function has been
expanded, and also works on an array of objects. When trying to
understand what it does, it is easier to think of a whole new
function, because, array_column()
either works on a
two-dimensional array of scalar values or a one-dimensional array of
objects. Passing a two-dimensional array of objects will not yield
the expected results.
Here is how to use array_column()
on an array of
objects:
class Something
{
public int $foo;
public function __construct(int $foo)
{
$this->foo = $foo;
}
}
$objects = [new Something(1), new Something(2), new Something(3)];
var_dump(array_column($objects, 'foo'));
We define an object with a public property foo
, and
create an array of instances. Calling array_column()
on
this array of objects will return an array of foo
values. Think of this as extracting a ‘column’ (as in: property)
from those objects:
array(3) {
[0] =>
int(1)
[1] =>
int(2)
[2] =>
int(3)
}
Public properties, however, are definitely not considered a best
practice. Or, to be more explicit: you should never, ever make a
property public, because this allows everybody to modify it. In the
above example, anybody could call
$something->foo = 'not-an-integer'
, for instance. It
gets even worse when properties hold references to other objects. In
short: public properties allow anybody to bypass any restrictions
that you have put on a property.
To make use of array_column()
without committing the
crime of declaring a property as public, interceptor methods can be
used:
class Something
{
private int $foo;
public function __construct(int $foo)
{
$this->foo = $foo;
}
public function __isset(string $property): bool
{
return $property === 'foo';
}
public function __get(string $property): ?int
{
if (!isset($this->$property)) {
return null;
}
return $this->$property;
}
}
This way, we can declare the property foo
as
private, and still access it using $something->foo
,
which internally will trigger the __get()
interceptor
method, passing foo
as the argument. Please note that
__isset()
will be called prior to __get()
,
so if no __isset()
method is defined,
array_colum()
will not work as expected.