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.