webman本身不提供搜索过滤dsl或查询构建器,所有复杂过滤需依赖meilisearch、elasticsearch或mysql fulltext;直接php层array_filter或拼接where在高并发下必然拖垮性能。

Webman 本身不提供搜索过滤 DSL 或查询构建器,所有复杂过滤都得靠后端检索服务(如 MeiliSearch、Elasticsearch)或数据库层手写逻辑来实现;直接在 PHP 层用 array_filter() 或 WHERE 拼接多条件,高并发下必然拖垮性能。
MeiliSearch 中用 filter 参数做多字段组合过滤
MeiliSearch 的 filter 支持类似 SQL WHERE 的表达式语法,但不是 SQL——它不支持 JOIN、子查询或函数调用,只支持字段比较、布尔逻辑和基础范围操作。适合做「状态 + 时间 + 分类」这类结构化过滤。
- 必须确保字段已在索引中设置为
filterable:调用$index->updateSettings(['filterableAttributes' => ['status', 'category_id', 'created_at']]) - 时间范围要用 Unix timestamp(秒级),不能传
'2024-01-01'字符串:created_at >= 1704067200 AND created_at - 字符串字段带空格时,要用双引号包裹:
title = "PHP Webman",否则解析失败 - 多个条件用
AND/OR连接,括号仅支持一层嵌套:(status = 1 OR status = 2) AND category_id IN [3, 5]
Elasticsearch 中避免 query_string 注入风险
用户输入直接拼进 query_string 查询,等于把 DSL 控制权交给前端——q=*" OR 1=1 就能扫库。Webman 里必须做白名单+结构化解析。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 禁用
query_string,改用bool+must/must_not/should组合:['bool' => ['must' => [['match_phrase' => ['title' => $keyword]], ['term' => ['status' => $status]]]]] - 数值型字段过滤前强转:
intval($request->get('min_price')),防止传入100 OR 1=1 - 数组类参数(如多选分类)用
terms而非term,并限制最大长度:if (count($categories) > 20) { throw new InvalidArgumentException('Too many categories'); } - ES 返回的
_source字段默认全量返回,敏感字段(如 price、email)需在查询时用_source_includes显式指定
MySQL FULLTEXT 在 Webman 中的兜底方案
当没有引入外部检索服务,又必须支持模糊关键词 + 结构化过滤时,MySQL FULLTEXT 是唯一可选路径,但要注意它只对 MyISAM/InnoDB 表生效,且中文需配置 ngram parser。
- 建表时指定 parser:
CREATE TABLE articles (title TEXT, content TEXT, FULLTEXT(title, content) WITH PARSER ngram) - 查询时用
MATCH ... AGAINST('关键词' IN NATURAL LANGUAGE MODE),别用BOOLEAN MODE——后者支持+/-但易被注入 - 结构化条件必须放在
WHERE子句里,且FULLTEXT条件要放最后,否则无法走索引:WHERE status = 1 AND created_at > '2024-01-01' AND MATCH(title, content) AGAINST('php webman') - 结果排序不能依赖
ORDER BY MATCH() DESC做分页——MySQL 8.0+ 对 FULLTEXT 排序分页有严重性能退化,应先查 ID 再 JOIN 取详情
真正复杂的过滤(比如「近 7 天内发布、阅读量 Top 10%、且含至少两个指定标签」)没法靠单次查询完成,得拆成多步:先用 ES/MeiliSearch 做粗筛得 ID 列表,再用 MySQL 关联业务字段做精筛。Webman 的协程模型适合这种 pipeline 式调用,但每一步的错误边界和超时必须手动设死——没人替你 catch 超时异常或重试失败的 HTTP 请求。










