应直接使用 smi2/phpclickhouse,它是当前唯一在 php 8.4 下稳定运行、持续维护且适配 clickhouse v23+ 的纯 php 客户端,不依赖 pdo 或 c 扩展,避免编译失败、ssl 不兼容及内存溢出等问题。

直接用 smi2/phpclickhouse,别碰其他驱动 —— 它是当前唯一在 PHP 8.4 下稳定运行、持续维护、且适配 ClickHouse v23+ 的纯 PHP 客户端。
为什么不是 pdo_clickhouse 或 clickhouse.so?
PHP 8.4 已移除对旧式资源类型(resource)的兼容支持,而多数已停更的 C 扩展(如 clickhouse.so)和 pdo_clickhouse 依赖该机制,编译失败或运行时 segfault 是常态。官方从 ClickHouse v22 起就明确不推荐非 HTTP 协议直连 PHP,TCP 端口(9000)只留给 clickhouse-client 或 Golang/Java 客户端用。
smi2/phpclickhouse 的安装与最小连接配置
执行这条命令即可:
composer require smi2/phpclickhouse:^1.5
注意:^1.5 兼容 PHP 8.4 且无需额外扩展;若你项目已启用 OpenSSL 3.0+ 并需 TLS 1.3,可升到 ^2.0,但必须确认 ClickHouse 服务端启用了 HTTPS 且证书有效。
初始化时务必注意这四点:
-
port必须是字符串,比如'8123',写成整数8123会静默失败(底层用http_build_query拼 URL,整数转为空) -
host写 IP 或域名,不要带http://前缀 -
https字段要显式设为true,否则即使 URL 是 https 也会走 http -
database不是连接时切换的库,而是后续所有select()、insert()默认作用的数据库,不设会报Database not specified
最小可用示例:
require 'vendor/autoload.php'; use ClickHouseDB\Client; <p>$client = new Client([ 'host' => '192.168.1.10', 'port' => '8123', 'username' => 'default', 'password' => '', 'database' => 'analytics', 'https' => false, // 若服务端没开 HTTPS,必须设 false 'timeout' => 45, // 大查询或首次建表可能卡住,建议 ≥30 秒 ]);</p>
查大结果集时 PHP 内存爆掉怎么办?
别用 $client->select('SELECT * FROM huge_table') —— 这个方法会把整个响应体读进内存,百万行以上基本 OOM。
正确做法是绕过高层封装,调用底层流式接口:
- 设置
stream=1和max_block_size=65536(默认 1024 太小) - 禁用
CURLOPT_RETURNTRANSFER,改用CURLOPT_WRITEFUNCTION回调逐块处理 - 响应格式选
JSONEachRow,每行一个 JSON 对象,但注意每行前后可能有空白,得trim()后再json_decode() - 务必加
output_format_json_quote_64bit_integers=0,否则UInt64字段会被包成字符串,PHP 自动转 float 导致精度丢失
关键参数拼在 query string 里,例如:
SELECT * FROM events FORMAT JSONEachRow -- 实际请求 URL 类似: -- http://192.168.1.10:8123/?database=analytics&query=SELECT%20*%20FROM%20events%20FORMAT%20JSONEachRow&stream=1&max_block_size=65536&output_format_json_quote_64bit_integers=0
分页查不出数据?大概率是 ORDER BY 字段没索引
ClickHouse 的分页不能靠 LIMIT offset, size,大数据量下性能断崖下跌。真正能用的只有三种方式:
- 基于排序字段的
WHERE + LIMIT:比如WHERE event_time > '2026-07-14 00:00:00' ORDER BY event_time LIMIT 1000,前提是event_time是建表时ORDER BY的一部分,或有跳数索引 - 物化视图预聚合:把高频分页逻辑提前固化到视图里,查视图时只扫小结果集
- 客户端游标 token:首次查完记下最后一条的
id(必须唯一且单调递增),下次传WHERE id > ? ORDER BY id LIMIT 1000
最容易被忽略的一点:ClickHouse 的 ORDER BY 是建表时定义的排序键,不是查询时能动态加的索引 —— 如果建表语句里没包含你要分页的字段,那它就真没索引。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











