iliaal / php_clickhouse
Native PHP extension for ClickHouse using the official ClickHouse/clickhouse-cpp client. Connects over the native TCP protocol with LZ4 / ZSTD compression and optional TLS.
Package info
github.com/iliaal/php_clickhouse
Language:C
Type:php-ext
Ext name:ext-clickhouse
pkg:composer/iliaal/php_clickhouse
Requires
- php: >=7.4
- ext-json: *
README
Native PHP extension for ClickHouse, built on the official ClickHouse/clickhouse-cpp v2.6.2 client. Speaks the native binary TCP protocol with LZ4 / ZSTD compression and optional TLS, picking up where SeasX/SeasClick left off in 2020. 30-40% faster than HTTP-based clients on heavy workloads, with modern types (Date32, Time64, Decimal128, LowCardinality, Map, JSON), multi-endpoint failover, and structured exceptions.
📖 Documentation
Full usage guide, data-type read/write reference, and configuration: iliaal.github.io/php_clickhouse
The docs site covers every supported type (what insert() accepts and what select() returns), fetch_mode flags, CSV/TSV streaming, placeholders, settings, observability, and the complete method list. This README is the quick start.
Why this fork?
SeasX/SeasClick was the canonical native PHP ClickHouse extension and stopped accepting PRs in 2020. Several follow-up PRs there have been pending for years. This fork:
- Renames the extension to
php_clickhouse(moduleclickhouse, classesClickHouse/ClickHouseException) - Upgrades the vendored client from artpaul-fork v1.x to the official ClickHouse/clickhouse-cpp v2.6.2
- Adds Date32 / Time / Time64 / DateTime64 / Int128 / UInt128 / Decimal128 / LowCardinality / Map / JSON column types, multi-endpoint failover, ZSTD compression, query_id propagation, and TLS
- Ships an updated test suite, CI, PIE-based packaging, and benchmarks
The original SeasClick and SeasClickException class names continue to work as deprecated aliases. Method signatures, return types, and class properties are declared with PHP types via a stub-driven arginfo workflow, so reflection, IDE completion, and static analyzers see the typed surface.
🚀 Install
Via PIE (the PHP Foundation's PECL successor):
pie install iliaal/php_clickhouse
With TLS support:
pie install iliaal/php_clickhouse --enable-clickhouse-openssl
Bare
php:X.Y-cliDocker images lack/usr/bin/unzip, which composer needs to extract PIE's prebuilt.sozip. Runapt-get install -y unzipbeforepie install, otherwise composer falls back to PHP's ZipArchive and PIE fails withExtensionBinaryNotFound. Host installs that already haveunzipare fine.
Building from source:
git clone https://github.com/iliaal/php_clickhouse.git cd php_clickhouse phpize ./configure # default build ./configure --enable-clickhouse-openssl # with TLS, requires OpenSSL development headers # (libssl-dev on Debian/Ubuntu, openssl-devel # on RHEL/Fedora, openssl-dev on Alpine) make && sudo make install
Add extension=clickhouse.so to your php.ini. The build needs a C++17-capable compiler (GCC 8+, Clang 7+, MSVC 2019+); LZ4, ZSTD, abseil-int128, and CityHash are vendored under lib/clickhouse-cpp/contrib/.
Platforms
| Platform | Status | Notes |
|---|---|---|
| Linux NTS | first-class | PHP 7.4 through 8.5, CI matrix |
| Linux ZTS | first-class | PHP 8.4 ZTS in CI |
| Windows (NTS, TS) | supported | PHP 8.4 x86 / x64 in CI; pre-built .dll released via PIE |
| macOS | unverified | should build (POSIX path); no CI lane |
Per-Client state lives on the zend_object itself (custom create_object / free_obj handlers), so ZTS works without locking. There is no module-global state to thread-isolate.
Test server
For development and integration tests, the simplest path is the official ClickHouse server image:
docker run -d --name clickhouse-test \
--ulimit nofile=262144:262144 \
-p 9000:9000 -p 8123:8123 -p 9440:9440 \
-e CLICKHOUSE_USER=test \
-e CLICKHOUSE_PASSWORD=test \
clickhouse/clickhouse-server:latest
Stop and clean up: docker rm -f clickhouse-test.
🛠️ Quick example
<?php $ch = new ClickHouse([ "host" => "127.0.0.1", "port" => 9000, "database" => "test", "user" => "default", "passwd" => "", "compression" => "lz4", // or "zstd" / true / false ]); $ch->execute("CREATE TABLE IF NOT EXISTS events ( id UInt32, ts DateTime64(3), tag LowCardinality(String) ) ENGINE = Memory"); $ch->insert("events", ["id", "ts", "tag"], [ [1, time(), "alpha"], [2, time(), "beta"], ]); foreach ($ch->select("SELECT id, ts, tag FROM events ORDER BY id", [], ClickHouse::DATE_AS_STRINGS) as $row) { print_r($row); }
Configuration keys, the full method list, per-type read/write rules, placeholders, settings, streaming, and observability all live in the documentation site.
📊 Benchmarks
PHP 8.4.22 / ClickHouse 26.3.9.8 / localhost loopback / Memory table (no disk).
Compared against smi2/phpClickHouse, the most popular pure-PHP HTTP client. Each cell is total wall-clock seconds for selectCount queries plus a single bulk insert of dataCount rows.
| dataCount × selectCount × limit | phpClickHouse (HTTP) | php_clickhouse (uncompressed) | php_clickhouse (LZ4) | php_clickhouse (ZSTD) |
|---|---|---|---|---|
| 10000 × 1 × 5000 | 0.112 | 0.085 | 0.074 | 0.023 |
| 10000 × 1 × 5000 | 0.104 | 0.030 | 0.024 | 0.081 |
| 10000 × 100 × 5000 | 0.298 | 0.263 | 0.209 | 0.218 |
| 10000 × 100 × 10000 | 0.303 | 0.210 | 0.265 | 0.215 |
| 1000 × 200 × 500 | 0.558 | 0.416 | 0.415 | 0.413 |
| 1000 × 200 × 1000 | 0.611 | 0.408 | 0.410 | 0.395 |
| 1000 × 500 × 500 | 1.428 | 1.063 | 0.976 | 0.982 |
| 1000 × 500 × 1000 | 1.383 | 0.959 | 1.025 | 1.030 |
| 1000 × 800 × 500 | 2.477 | 1.533 | 1.569 | 1.543 |
| 1000 × 800 × 1000 | 2.498 | 1.588 | 1.563 | 1.519 |
At high select counts the native binary protocol runs 30-40% faster than the HTTP client. On small bursts (dataCount=10000, selectCount=1), php_clickhouse with ZSTD or LZ4 is fastest. To reproduce, see bench/.
🔗 PHP Performance Toolkit
Companion native PHP extensions for high-throughput PHP workloads:
- php_excel: native Excel I/O. 7-10× faster than PhpSpreadsheet, full XLS/XLSX with formulas, conditional formatting, and rich text. Powered by LibXL.
- mdparser: native CommonMark + GFM markdown parser. 15-30× faster than pure-PHP libraries (Parsedown, cebe, michelf). Powered by cmark-gfm.
- fastchart: native chart-rendering extension. 26 chart types behind one fluent OO API, SVG-canonical with PNG/JPG/WebP output (no libgd dependency).
📚 Read more
Full background, fork rationale, and benchmark methodology in the launch post: php_clickhouse: A Native ClickHouse Client for PHP, Picking Up Where SeasClick Left Off.
License
The PHP-side wrapper is licensed under PHP-3.01.
The vendored client library at lib/clickhouse-cpp/ is ClickHouse/clickhouse-cpp, licensed under the Apache License 2.0.
The vendored compression libraries (lib/clickhouse-cpp/contrib/lz4/, contrib/zstd/, contrib/cityhash/) carry BSD-style licenses; abseil int128 (contrib/absl/) is Apache 2.0. See each subdirectory for the exact text.
Credits
php_clickhouse started as a fork of SeasX/SeasClick by SeasX Group (ahhhh.wang@gmail.com). The original PR-4 work to add fetch modes landed in 2019 and the upstream maintainer hasn't accepted external PRs since. Independent re-vendoring, port to clickhouse-cpp v2.6.2, new types, TLS, and packaging are by Ilia Alshanetsky ilia@ilia.ws.
Contributing
See CONTRIBUTING.md. Security issues: SECURITY.md.
Follow @iliaa on X • Blog • If this sped up your stack, ⭐ star it!
