【问题标题】:CakePHP 3 - how to filter data (Collection) in combination with pagination?CakePHP 3 - 如何结合分页过滤数据(集合)?
【发布时间】:2019-10-22 20:05:04
【问题描述】:

Collection 函数(在我的例子中是“过滤器”)和 paginate() 的组合会导致错误。简化的 PHP 代码如下:

$rooms = $this->Rooms
    ->find('all')
    ->formatResults(function ($results) {
        return $results->map(function ($row) {
            //... 
            $row->free_booking=0;      
            if($someCondition) $row->free_booking=1;
            //...

            return $row;
        });        
    })
    ->filter(function ($booking, $key) {
        return $booking->free_booking == 1;
    });
$this->set('rooms',$this->paginate($rooms));

错误如下:

错误:调用未定义的方法 ArrayIterator::alias() 文件 .../public_html/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php 线路:174


如何解决这个问题?

【问题讨论】:

    标签: cakephp pagination filtering cakephp-3.x


    【解决方案1】:

    您在查询对象上调用filter(),这将导致查询被执行并转换为集合,并且不支持对集合进行分页。

    如果您使用分页,您通常应该避免在 PHP 级别操作结果(添加/删除条目),这几乎肯定会弄乱您的分页,因为 PHP 级别的记录数与计数的记录数不匹配在 SQL 级别上。

    将您的过滤逻辑移到查询中,即在 SQL 级别进行过滤。

    【讨论】:

    • 问题出在应用性能上。如果使用,应用程序非常快 $this->set('rooms',$this->paginate($rooms));如果使用 $roomSegments = $rooms->take($limit,$offset)->toArray(); 会非常慢$this->set('rooms',$roomSegments);.应用程序处理大量数据
    • @user3661042 我并不是说你不应该使用分页,我只是建议你应该在 SQL 级别而不是 PHP 级别进行过滤。
    • @user3661042 如果您添加创建$someCondition 的代码,那么也许我可以添加一个关于如何使用 SQL 执行此操作的示例。
    • 不幸的是,这不能用 SQL 完成,因为 '$someCondition' 非常复杂。 '$someCondition' 的一部分也是房价计算和预订检查。
    • @user3661042 我的意思是,SQL 通常能够执行复杂的操作,即使是非常大、复杂的查询仍然可以很快,但这当然取决于。在没有看到计算的情况下,我真的不能给你任何进一步的建议,我只能说在 PHP 级别上的过滤会破坏你的分页,因为你不知道记录的总数,因此分页计算会错了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    相关资源
    最近更新 更多