Magento 模型筛选很神奇,新clone出来的对象增加筛选条件对之前的筛选有影响,我不理解!

这是一段神奇的代码,怎么理解 ? 大佬请教?

功能

查询status=1商品的同时,返回符合这个筛选条件的is_hot=1 热门的商品数量

现象

通过clone以后进行筛选获取is_hot的数量,但是会影响到具体分页的数据获取,比如status = 1的有3条记录, 同时满足is_hot的有2条记录,下面这样写, 最终获取的data是2条记录。 当把
$hotNum = $otherProducts->addAttributeToFilter('is_hot', 1)->count(); 这一句放到最后, 查询结果是正确的3条记录。

                $products = (new Gw_Catalog_Model_Resource_Product_Collection())
                    ->addAttributeToSelect('*')
                    ->addAttributeToFilter('status', 1);

                $otherProducts = clone $products;
                $hotNum = $otherProducts->addAttributeToFilter('is_hot', 1)->count();
                $products = $products->setPageSize(20)
                    ->setCurPage(1);
                foreach ($products as $product) {
                    $data[] = $product->getSku();
                }
思考

类比laravel, 中间clone的新对象builder增加where,对原有的builder查询没有任何影响;

        $query = Product::query()->where('status', 1);
        $newQuery = clone $query;
        $newQuery = $newQuery->where('is_hot', 1);
        $data = $query->get()->toArray();

正常来讲, addAttribute筛选返回的类似 queryBulider的对象,最终在获取数据的时候把queryBulider存储的属性变成sql查询。 clone后是一个新的builder。在增加筛选属性,应该不会影响之前的builder,自然也不会影响查询出来的结果数据,但最终结果增加的筛选条件页生效了

重新复制一份模型筛选代码正常实现功能, 但是显得臃肿,有啥好的方法实现

相关

laravel的query增加条件需要 = 接收吗 ?

PHP是世界上最好的编程语言,它能快速的进行技术变现,让代码多一份价值。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2

这个要看clone的类对克隆的魔术方法是怎么样设置的。如果是克隆的方法返回的就是类的this,那就跟你测试的一样,没毛病

2年前 评论
PHP之父一只码 (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!