Какой интерфейс SPL я должен реализовать, чтобы иметь возможность использовать функцию usort() для объекта?

У меня есть класс, который представляет объект коллекции: у него есть только один атрибут, массив. Этот класс реализует \Countable, \IteratorAggregateи самое главное для этого вопроса, \ArrayAccess,

Но при использовании:

        usort($collectionData, function($a, $b) {
            return ($a->getPosition() > $b->getPosition());
        });

Я получаю следующее ловимое исключение:

Предупреждение: usort() ожидает, что параметр 1 будет массивом, объект указан в /home/alain/workspace/(...)n.php строка 1057 (500 Internal Server Error)

Я могу обмануть, используя промежуточную переменную:

        $data = $collectionData->getData();
        usort($data, function($a, $b) {
            return ($a->getPosition() > $b->getPosition());
        });
        $collectionData->setData($data);

Но хотел знать, есть ли интерфейс SPL, который может проходить через ожидание типа параметра массива usort(),

3 ответа

Решение

Не то, что я знаю из. Никакой интерфейс не сделает ваш объект тоже array и это то, что вам нужно передать usort(), Однако вы можете инкапсулировать это поведение в своем классе, добавив usort() метод для вашего класса.

class CollectionEntity implements Countable, IteratorAggregate, ArrayAccess {

  private $data = array();

  /* other methods omitted for simplicity */

  public function usort(Closure $callback) {
    usort($this->data,$callback);
  }


}

Я действительно думаю, что единственный класс, который вы должны продлить, это ArrayIterator потому что это уже реализует

ArrayIterator реализует Iterator, Traversable, ArrayAccess, SeekableIterator, Countable, Serializable

Также он поддерживает

 public void uasort ( string $cmp_function )
 public void uksort ( string $cmp_function )

И так много других методов

Так что ваш класс так же просто, как

class CollectionEntity extends ArrayIterator {
}

затем

$collectionData->uasort(function ($a, $b) {
    return ($a->getPosition() > $b->getPosition());
});

Нет такого интерфейса, функции массива могут работать только на собственных массивах. Тем не менее, вы можете конвертировать Traversables, такие как IteratorAggregate массивы с iterator_to_array

Кстати, вот объяснение, почему особенно ArrayAccess не помогает: PHP: как я могу отсортировать и отфильтровать "массив", то есть Object, реализующий ArrayAccess?

Другие вопросы по тегам