PHP 7.4 项目需用 elasticsearch/elasticsearch:^7.17;PHP 8.0+ 且已有 Guzzle 6 时应先卸载再安装;连接失败多因未配置 basic_auth 或 SSL 验证;bulk 操作需手动检查 items 状态;match_phrase 查不到结果常因字段类型或 analyzer 配置不当。

怎么装 elasticsearch-php 客户端才不会和 Composer 冲突
新版 elasticsearch/elasticsearch(v8.x)默认要求 PHP 8.1+,且强制依赖 guzzlehttp/guzzle 7.5+ 和 psr/http-client。如果你项目还在用 PHP 7.4 或 Guzzle 6,直接 composer require elasticsearch/elasticsearch 会报依赖冲突。
- PHP 7.4 项目:只能用
elasticsearch/elasticsearch:^7.17,它兼容 Guzzle 6 和 PSR-18 基础实现 - PHP 8.0+ 但已有 Guzzle 6:先执行
composer remove guzzlehttp/guzzle,再装客户端,让 Composer 自动拉取兼容版本 - 别碰
dev-master或未打 tag 的分支——连官方都不保证接口稳定
连接 ES 时为什么一直抛 ConnectionFailedException
不是密码错,也不是地址写反,大概率是客户端默认没开 HTTP 认证或 SSL 验证,而你的 ES 集群启用了安全模块(如 Elastic Stack Security 或 OpenSearch)。v8 客户端默认关闭 basic_auth,也不校验证书。
- ES 启用了 HTTPS + 用户名密码?必须显式传
basic_auth参数:$client = ClientBuilder::create() ->setHosts(['https://localhost:9200']) ->setBasicAuthentication('elastic', 'changeme') ->build(); - 自签名证书?加
->setSSLVerification(false),但仅限开发环境——生产禁用 - 用的是 OpenSearch?确保 host 地址末尾不带
/,否则会拼出https://host//_search导致 400
bulk 插入数据时部分失败,index 操作返回 400 却没报错
因为 bulk 是“尽力而为”操作,默认不会中断整个请求。客户端把响应体解析成数组后,每个子操作的 status 字段得你自己检查,Client::bulk() 成功只代表 HTTP 请求发出去了,不代表每条都写进去了。
- 务必检查响应里的
items数组:$response = $client->bulk($params); foreach ($response['items'] as $item) {if (isset($item['index']['status']) && $item['index']['status'] >= 400) {error_log('Bulk item failed:' . $item['index']['error']['reason']); } } - 别在
bulk里混用不同 index 的文档——v7+ 要求显式指定_index,否则可能路由到错误索引 - 单次 bulk 超过 10MB 或 1000 条?ES 可能直接 close 连接,建议控制在 5–10MB / 次
为什么 match_phrase 查询总查不出结果
不是 DSL 写错,而是你建索引时没配好 analyzer。ES 默认对 text 字段用 standard 分词器,但 match_phrase 依赖 term 级别的位置信息,如果字段 mapping 是 keyword 类型,或者用了 whitespace 这种不记录 position 的分词器,就必然匹配失败。
立即学习 “PHP 免费学习笔记(深入)”;
- 确认字段类型:
GET /my_index/_mapping # 看 target_field 的 type 是否为 text,且 analyzer 不是 keyword - 测试分词输出:
GET /my_index/_analyze {"field": "title", "text": "quick brown fox"}—— 必须看到
"position"字段才有 phrase 匹配基础 - 别在查询里硬写
"analyzer": "keyword",那是给match用的,match_phrase不支持运行时指定 analyzer
Elasticsearch 的坑多数不在 PHP 客户端本身,而在服务端配置、DSL 语义和网络中间层。最常被跳过的其实是 _cat/indices 和 _cat/shards 这两个诊断命令——查不到数据时,先看索引是否存在、shard 是否全 green,比反复改 PHP 代码快得多。