zenstruck/porpaginas

此包已被放弃,不再维护。作者建议使用zenstruck/collection包。

一个库,用于泛型解决DAO/repository抽象的多个分页问题。

v2.0.0 2018-02-08 13:23 UTC

This package is auto-updated.

Last update: 2021-04-28 23:03:49 UTC


README

Build Status Scrutinizer Code Quality Code Coverage StyleCI Latest Stable Version License

注意:此库是基于beberlei/porpaginas的分支。

此库解决了Repository类API中出现的一些问题。

  • 您需要不同的方法来处理可分页和不可分页的查找方法。
  • 您需要公开底层数据源并从您的仓库返回查询对象。
  • 分页器的序列化应易于在REST API中实现。

Pagerfanta和KnpLabs Pager都无法解决这个问题,并且它们的API在这方面真的很成问题。您需要从您的仓库返回查询对象或适配器,以使其工作,然后在控制器端使用API将它们转换为分页结果集。

Porpaginas通过引入分页结果的合理抽象来解决此问题。对于渲染目的,您可以与Pagerfanta或KnpLabs Pager集成,此库并不涉及重实现分页的视图部分。

此库的核心是接口Result

namespace Zenstruck\Porpaginas;

interface Result extends \Countable, \IteratorAggregate, \JsonSerializable
{
    public function take(int $offset, int $limit): Page;

    /**
     * Return the number of all results in the paginatable.
     */
    public function count(): int;

    /**
     * Return an iterator over all results of the paginatable.
     */
    public function getIterator(): \Iterator;
}

此API提供了两种遍历可分页结果的方法,要么是完整结果,要么是使用take()的结果的分页窗口。一个缺点是查询始终在Result内部惰性执行,而不是直接在仓库中执行。

Result::take()返回的Page接口看起来像这样

namespace Zenstruck\Porpaginas;

interface Page extends \Countable, \IteratorAggregate, \JsonSerializable
{
    /**
     * Return the number of results on the currrent page.
     */
    public function count(): int;

    /**
     * Return the number of ALL results in the paginatable..
     */
    public function totalCount(): int;

    /**
     * Return an iterator over selected windows of results of the paginatable.
     */
    public function getIterator(): \Iterator;
}

支持的后端

  • 数组
  • Doctrine ORM
  • Doctrine DBAL

示例

以下示例使用Doctrine ORM

use Zenstruck\Porpaginas\Result;

class UserRepository extends EntityRepository
{
    public function findAllUsers(): Result
    {
        $qb = $this->createQueryBuilder('u')->orderBy('u.username');

        return new ORMQueryResult($qb);
    }
}

class UserController
{
    /**
     * @var UserRepository
     */
    private $userRepository;

    public function listAction(Request $request)
    {
        $result = $this->userRepository->findAllUsers();
        // no filtering by page, iterate full result

        return array('users' => $result);
    }

    public function porpaginasListAction(Request $request)
    {
        $result = $this->userRepository->findAllUsers();

        $paginator = $result->take(($request->get('page', 1)-1) * 20, 20);

        return array('users' => $paginator);
    }
}

此库还附带一个分页辅助工具。使用Pager,上述控制器的porpaginasListAction()可以重写如下

use Zenstruck\Porpaginas\Pager;

class UserController
{
    /**
     * @var UserRepository
     */
    private $userRepository;

    public function porpaginasListAction(Request $request)
    {
        $result = $this->userRepository->findAllUsers();

        return array('users' => $result->paginate($request->get('page', 1)));
    }
}