Doctrine 2 имеет класс Doctrine \ ORM \ Tools \ Pagination \ Paginator, который можно использовать для разбивки обычных DQL-запросов.
Однако, если я передаю ему собственный запрос, я получаю эту ошибку:
Catchable fatal error: Argument 1 passed to Doctrine\ORM\Tools\Pagination\Paginator::cloneQuery() must be an instance of Doctrine\ORM\Query, instance of Doctrine\ORM\NativeQuery given
Я попытался удалить подсказку типа из класса paginator в методе cloneQuery, но это дает дополнительные ошибки, потому что другие биты класса paginator ожидают, что методы, найденные в Query, которые не входят в NativeQuery.
Есть ли простой способ разбиения на страницы собственных запросов без необходимости создания нового класса paginator или извлечения каждой строки из базы данных в массив?
Я создал свой собственный класс адаптера paginator, совместимый с Zend_Paginator.
Вероятно, он не будет наиболее гибким, поскольку он полагается на то, что рядом с началом запроса находится «ОТ» (см. Метод count ()), но это относительно быстрое и легкое исправление.
/** * Paginate native doctrine 2 queries */ class NativePaginator implements Zend_Paginator_Adapter_Interface { /** * @var Doctrine\ORM\NativeQuery */ protected $query; protected $count; /** * @param Doctrine\ORM\NativeQuery $query */ public function __construct($query) { $this->query = $query; } /** * Returns the total number of rows in the result set. * * @return integer */ public function count() { if(!$this->count) { //change to a count query by changing the bit before the FROM $sql = explode(' FROM ', $this->query->getSql()); $sql[0] = 'SELECT COUNT(*)'; $sql = implode(' FROM ', $sql); $db = $this->query->getEntityManager()->getConnection(); $this->count = (int) $db->fetchColumn($sql, $this->query->getParameters()); } return $this->count; } /** * Returns an collection of items for a page. * * @param integer $offset Page offset * @param integer $itemCountPerPage Number of items per page * @return array */ public function getItems($offset, $itemCountPerPage) { $cloneQuery = clone $this->query; $cloneQuery->setParameters($this->query->getParameters(), $this->query->getParameterTypes()); foreach($this->query->getHints() as $name => $value) { $cloneQuery->setHint($name, $value); } //add on limit and offset $sql = $cloneQuery->getSQL(); $sql .= " LIMIT $itemCountPerPage OFFSET $offset"; $cloneQuery->setSQL($sql); return $cloneQuery->getResult(); } }
Если у вас есть dbal query builder (который вы создали с помощью $ yourDbalQueryBuilder = $ connection-> createQueryBuilder ();), то вы можете использовать:
$ YourDbalQueryBuilder-> setFirstResult (0) -> setMaxResults (100000000) -> Execute () -> сверку ();