I have an object that is a collection of objects, behaving like an array. It's a database result object. Something like the following:
$users = User::get();
foreach ($users as $user)
echo $user->name . "\n";
The $users
variable is an object that implements ArrayAccess
and Countable
interfaces.
I'd like to sort and filter this "array", but I can't use array functions on it:
$users = User::get();
$users = array_filter($users, function($user) {return $user->source == "Twitter";});
=> Warning: array_filter() expects parameter 1 to be array, object given
How can I sort and filter this kind of object?
You could use
ArrayObject
instead ofArrayAccess
, it has multiple native sort functionality:ArrayObject::asort
ArrayObject::ksort
ArrayObject::natcasesort
ArrayObject::natsort
ArrayObject::uasort
ArrayObject::uksort
You can't. The purpose of the
ArrayAccess
interface is not just to create an OOP wrapper for arrays (although it is often used as such), but also to allow array-like access to collections that might not even know all their elements from the beginning. Imagine a web service client, that calls a remote procedure inoffsetGet()
andoffsetSet()
. You can access arbitrary elements, but you cannot access the whole collection - this is not part of theArrayAccess
interface.If the object also implements
Traversable
(viaIterator
orIteratorAggregate
), an array could at least be constructed from it (iterator_to_array
does the job). But you still have to convert it like that, the native array functions only accept arrays.If your object stores the data internally as an array, the most efficient solution is of course to implement a
toArray()
method that returns this array (and maybe callstoArray()
recursively on contained objects).