PHP: как я могу отсортировать и отфильтровать "массив", то есть Object, реализующий ArrayAccess?
У меня есть объект, который представляет собой набор объектов, ведущий себя как массив. Это объект результата базы данных. Что-то вроде следующего:
$users = User::get();
foreach ($users as $user)
echo $user->name . "\n";
$users
переменная является объектом, который реализует ArrayAccess
а также Countable
интерфейсы.
Я бы хотел отсортировать и отфильтровать этот "массив", но я не могу использовать функции массива:
$users = User::get();
$users = array_filter($users, function($user) {return $user->source == "Twitter";});
=> Warning: array_filter() expects parameter 1 to be array, object given
Как я могу отсортировать и отфильтровать этот вид объекта?
2 ответа
Ты не можешь Цель ArrayAccess
Интерфейс предназначен не только для создания оболочки ООП для массивов (хотя она часто используется как таковая), но и для предоставления доступа к коллекциям в виде массива, которые могут даже не знать все свои элементы с самого начала. Представьте себе клиента веб-службы, который вызывает удаленную процедуру в offsetGet()
а также offsetSet()
, Вы можете получить доступ к произвольным элементам, но вы не можете получить доступ ко всей коллекции - это не является частью ArrayAccess
интерфейс.
Если объект также реализует Traversable
(с помощью Iterator
или же IteratorAggregate
) по крайней мере из него можно построить массив (iterator_to_array
делает работу). Но вы все равно должны конвертировать его так, нативные функции массива принимают только массивы.
Если ваш объект хранит данные внутри себя в виде массива, наиболее эффективным решением, конечно, является реализация toArray()
метод, который возвращает этот массив (и, возможно, вызывает toArray()
рекурсивно на содержащихся объектах).
Вы могли бы использовать ArrayObject
вместо ArrayAccess
, он имеет несколько функций родной сортировки:
ArrayObject::asort
ArrayObject::ksort
ArrayObject::natcasesort
ArrayObject::natsort
ArrayObject::uasort
ArrayObject::uksort