ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hifone Repository 模式实战:Criteria 如何优雅实现搜索与过滤

Hifone Repository 模式实战:Criteria 如何优雅实现搜索与过滤 Hifone Repository 模式实战Criteria 如何优雅实现搜索与过滤【免费下载链接】HifoneA free, open-source, self-hosted forum software based on the Laravel PHP Framework. QQ群656868项目地址: https://gitcode.com/gh_mirrors/hi/HifoneHifone 是一款基于 Laravel PHP Framework 构建的开源论坛软件而它的Repository 模式设计堪称教科书级的范例。本文将从零讲清楚 Hifone 中的Criteria机制它如何把搜索与过滤这类散落在控制器里的查询逻辑变成一个个可插拔、可复用、可组合的小对象让代码既优雅又好维护。即使你是刚接触 Laravel 的新手也能轻松看懂。Hifone 是什么先认识这个开源论坛 Hifone 是一个免费、开源、可自助托管的社区论坛程序。它体积轻巧、开箱即用非常适合搭建技术社区、兴趣小组或个人知识讨论区。作为一个论坛最核心的高频操作就是两件事搜索和过滤。比如首页展示最新回复还是精华帖用户搜Laravel想找到相关帖子只看某个节点版块下的内容私信列表只看自己收到的如果这些逻辑全部堆在控制器里代码很快就会变成一团乱麻。Hifone 用Repository Criteria模式漂亮地解决了这个问题。为什么论坛项目需要 Repository 模式很多新手会问直接Thread::where(...)-get()不就行了当然可以但项目变大后你会发现查询逻辑重复多个页面都要按节点过滤代码复制粘贴好几份业务与数据库耦合控制器里写满 Eloquent 细节换数据库就崩难以测试查询逻辑散落各处单元测试无从下手。Repository 模式把数据怎么取统一收口到仓库层而Criteria条件模式则更进一步把每种过滤规则封装成独立对象。两者结合查询条件可以像乐高积木一样自由拼装。Hifone 的 Repository 架构速览 Hifone 的仓库层代码集中在一个目录下结构非常清晰文件作用RepositoryInterface.php仓库接口定义统一的数据操作方法Repository.php抽象基类实现接口并内置 Criteria 机制CriteriaInterface.php条件接口规范 Criteria 的三种操作Criteria.php抽象条件基类所有条件都继承它其中最关键的是 Repository.php它用一行抽象方法abstract protected function model($modelName null);让每个具体仓库绑定自己的模型并提供了三个核心的 Criteria 操作方法pushCriteria()把条件推入队列 applyCriteria()执行队列里所有条件 ⚙️skipCriteria()临时跳过所有条件常用于某些特殊查询Criteria 是什么可插拔的查询条件 Criteria直译就是标准/条件。在 Hifone 里它就是一个实现了apply($model, Repository $repository)方法的类传入当前查询构建器返回加上过滤条件后的新构建器。基础类长这样核心就一个抽象方法abstract class Criteria { abstract public function apply($model, Repository $repository); }就这么简单你写一个类、实现apply、在构造时传入参数这个过滤条件就诞生了。下面是 Hifone 项目里现成的四个 Criteria每一个都对应一个真实业务场景。实战一用 Filter 实现多种列表排序与过滤 论坛首页最常见的需求是按不同维度展示帖子列表。Hifone 用 Filter.php 一个类就搞定了所有场景传入参数效果unanswered只看未回复的帖子reply_count 0like按点赞数排序最热门的在前excellent只看精华帖is_excellent truerecent按最新发布排序node按最近回复排序版块内常用其他/默认置顶帖优先 最近回复排序它的实现思路是在apply()里用一个switch分支把不同过滤逻辑翻译成不同的 Eloquent 查询。想新增一种过滤加一个 case 就行完全不用动控制器代码。实战二用 Search 实现关键词搜索 搜索是论坛的刚需。Hifone 把搜索也做成了一个 CriteriaSearch.php。它做的事极其简单把用户输入的关键词$q传给模型的search()作用域。具体怎么匹配标题、匹配内容全部封装在模型层。控制器只需要知道把搜索条件推给仓库即可。这种设计的妙处在于搜索逻辑可以换实现而不动调用方。今天用 MySQL LIKE明天想换成 Elasticsearch只需修改Search内部或模型作用域页面代码一行都不用改。✨实战三BelongsToNode 与 OnlyMine 的妙用 除了全局搜索Hifone 还有两个非常轻量的 CriteriaBelongsToNode.php构造时传入$nodeId在apply()里加一条where(node_id, $nodeId)实现按版块过滤OnlyMine.php构造时传入$userId调用forUser()作用域实现只看自己的数据比如私信列表。看到规律了吗每个 Criteria 都是构造时接收参数 apply 时施加条件的两段式结构。参数不同、类不同但使用方式完全一致——这就是策略模式与 Repository 结合的威力。组合拳控制器里如何优雅地叠加条件 光看单个类还不够过瘾Hifone 真正精彩的是在控制器里把它们自由组合。以 ThreadController.php 的首页为例$repository app(repository); $repository-pushCriteria(new Filter(Input::query(filter))); $repository-pushCriteria(new Search(Input::query(q))); $threads $repository-model(Thread::class)-getThreadList(15);当前列表页的过滤 用户搜索的关键词两个条件先后推入队列一次查询同时生效。而在 NodeController.php 的版块页面则组合了三个条件Search BelongsToNode Filter(node)实现在某个版块里搜索并按最近回复排序三行代码完成复杂查询。再看看 HomeController.php 的首页只推入一个Filter(excellent)展示精华帖PmController.php 则推入OnlyMine保证用户只能看到自己的私信。每个页面按需拼装互不干扰。完整执行流程从 pushCriteria 到 applyCriteria ️整个过程其实只有三步理解它你就掌握了精髓入队pushCriteria()把条件对象依次放进$criteria数组执行调用all()、find()、getThreadList()等任何查询方法时内部都会先触发applyCriteria()遍历队列依次调用每个条件的apply()把模型一层层加工出队下次请求前resetCriteria()清空队列、重建模型保证仓库对象复用时不串味。同时skipCriteria(true)可以临时跳过所有条件适合我要取全量数据的特殊场景。这套机制在 Repository.php 中实现得干净利落值得每个 Laravel 开发者反复研读。想亲手体验快速跑起来 如果你也想在本地把玩这个项目直接克隆仓库即可git clone https://gitcode.com/gh_mirrors/hi/Hifone装好依赖、配好数据库、执行迁移和种子数据一个自带优雅架构的论坛就上线了。你可以试着在 app/Repositories/Criteria/ 目录下新建自己的 Criteria比如只看一周内的热门帖体会一把加需求不改控制器的爽快感。总结从 Hifone 学到的三件事 查询即对象把过滤逻辑封装成 Criteria 类参数化、可复用、可测试组合优于堆砌多个条件用pushCriteria自由叠加控制器保持清爽解耦是王道搜索与过滤的实现细节被隔离未来替换引擎零成本。Hifone 用不到十个小文件就把Repository 模式 Criteria 模式讲得明明白白。无论你是想优化现有 Laravel 项目还是准备搭建自己的论坛这套优雅实现搜索与过滤的思路都值得直接抄作业。赶紧打开源码跟着 Criteria 目录 一行行读下去吧【免费下载链接】HifoneA free, open-source, self-hosted forum software based on the Laravel PHP Framework. QQ群656868项目地址: https://gitcode.com/gh_mirrors/hi/Hifone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表