smi2/phpclickhouse
PHP client for ClickHouse with sync and async queries, native parameter binding, bulk inserts, generators, gzip compression, cluster support, streaming, and progress callbacks. Requires PHP 8.1+, ext-curl, ext-json.
Build vs. Buy Decision:
phpClickHouse. Release 1.26.925 materially strengthens the case — the client now ships typed wrappers for strings, dates, enums, and the full numeric scalar range (Int8–Int256, UInt8–UInt256, Float32/64, Decimal32–Decimal256), plus structured server-side error metadata. That is a validation and type-mapping layer we would otherwise build and maintain ourselves.1.26.4 and freeze", which carries security-patch exposure since the injection-hardening work landed after that tag.Feature Roadmap:
{name:Type}) at the protocol level, and validated + escaped type wrappers (fromString() enforces ^-?\d+$ for integers, is_numeric() for floats/decimals; new StringableType values are escaped by ValueFormatter, bindings, and native parameters). This closes the historic SQL-injection vector where Type values were interpolated unescaped.Type objects do not get the new escaping. Any existing code interpolating Type values into SQL must be migrated to the new wrappers — treat this as a security backlog item, not a nice-to-have.Decimal32–Decimal256 with exact arithmetic is now first-class. Standardize on Decimal for money and anything auditable; Float is only appropriate for approximate metrics. Be aware of the documented json_decode() precision trap for >16-digit decimals — exact reads must go through toString().DatabaseException::getServerVersion() and getServerStackTrace() (opt in per query with ['stacktrace' => 1]) give support and on-call engineers real server context. The stack trace is deliberately excluded from getMessage(), so we must decide explicitly whether to log it — and must not surface it to end users or API responses.max_execution_time, max_block_size) for tuning without touching global server config.Use Cases:
INSERT INTO ... SELECT with structured error handling for large moves.Platform / Upgrade Decision: The PHP 8.1 requirement is a roadmap dependency. Confirm PHP 8.1–8.4 coverage across our services (the project's CI now tests exactly that range against ClickHouse 21.9 / 26.3 / 26.9) so the upgrade is a schedule item rather than a surprise.
Adopt if:
ext-curl/ext-json.StringType, FixedString(N), Date/DateTime, Enum8/16, full numeric coverage) defend at the protocol and value level.Decimal types with documented IEEE 754 caveats and exact-arithmetic guidance.Look elsewhere if:
1.26.4, but accept that the injection-hardening and type-wrapper work is unavailable.For Executives:
"phpClickHouse is a battle-tested, MIT-licensed PHP client for ClickHouse, and the new 1.26.925 release closes the gap that would have forced us to build our own type and validation layer. It now covers the complete ClickHouse scalar type set — including exact Decimal for financial reporting — with input validation and escaping that removes a known SQL-injection vector for untrusted data. Failures now carry server version and server-side stack traces, which shortens incident diagnosis. Cost: one PHP 8.1 upgrade (8.0 support was dropped) and a small migration of legacy type usage. We still build our own API layer on top, but we avoid owning and maintaining a database client."
For Engineering:
*"Upgrade to 1.26.925 (minimum PHP 8.1; last 8.0-compatible tag is 1.26.4). What you get:
StringType, FixedString(N) (strict byte-length validation), Date, DateTime (optional non-mutating timezone conversion), Enum8/Enum16, and Int8–Int256 / UInt8–UInt256 / Float32–Float64 / Decimal32–Decimal256.fromString() validates input (integers ^-?\d+$, floats/decimals is_numeric()); new StringableType values are escaped by ValueFormatter, bindings, and native parameters. Legacy Type values are still interpolated unescaped — migrate them.getServerVersion(), getServerStackTrace() via per-query ['stacktrace' => 1]; trace is kept out of getMessage() so it won't leak into logs/UI unless you opt in.0.1 + 0.2 != 0.3; Decimal for exact math; inf/nan → null in JSON; the json_decode() precision trap for >16-digit decimals — read those via toString().Trade-offs:
composer.json and CI.Recommendation: Standardize on 1.26.925 for analytics pipelines, data warehousing, high-volume ingestion, and any Decimal-bearing reporting. Schedule the PHP 8.1 upgrade first, then migrate legacy Type usage to the escaped wrappers as a security task."*
How can I help you explore Laravel packages today?