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.
composer.json now requires php: ^8.1 and the CI matrix drops 8.0. PHP 8.0 users should pin 1.26.4 (last 8.0-compatible release); the typed >= 1.24.406 line already targets 8.1+StringType (PHP reserves String), FixedString(N) with strict byte-length validation, Date, DateTime (with optional non-mutating timezone conversion), Enum8, Enum16. All implement the new StringableType interface: unlike legacy Type objects, their values are escaped by ValueFormatter, bindings, and native parametersInt8–Int256, UInt8–UInt256, Float32/Float64, Decimal32–Decimal256 via the new ScalarNumericType interface (Bool maps to the existing Boolean class). fromString() validates input — integers require ^-?\d+$, floats/decimals require is_numeric() — closing an SQL-injection vector for untrusted input, since Type values are interpolated into SQL unescapedDatabaseException::getServerVersion() and getServerStackTrace() (populate with per-query ['stacktrace' => 1]); reworked error-response parsing in Statement. The server stack trace is kept out of getMessage() — it is available only via the dedicated gettertests/Type/Ieee754MantissaTest.php, 31 cases) — significand limits and overflow collapse for Float32 (2^24), Float64 (2^53), BFloat16 (2^8, CH 24.11+); 0.1 + 0.2 != 0.3 vs exact Decimal arithmetic; inf/nan → null in JSON; scale-0 truncation toward zero; Decimal arriving as an unquoted JSON number on every supported server; the json_decode() precision trap for >16-digit decimals (exact reads need toString())clickhouse-26-9 (26.9.1.1629, port 8125), phpunit-ch269.xml, CI job PHP 8.1–8.4 × CH 26.9. Suites for 21.9 / 26.3 / 26.9 run separatelymax_execution_time is visible to getSetting() without touching global settingsREADME.md, doc/types.md, and the Pages site now link the IEEE 754 standard and the ClickHouse Float reference, with a verified 0.1 + 0.2 != 0.3 example and the exact-Decimal counterparttodo.md translated to English (#268, @sander-hash)README.md and the Pages site (docs/index.md).gitignore now covers .DS_Store, .idea/, vim swap files, and local ClickHouse data directoriesON CLUSTER) formatting reworked (#241, #263, #262) — Http::prepareWrite() no longer appends FORMAT JSON to the SQL of ON CLUSTER queries. Instead the response format is requested via the default_format=JSON query setting:
CREATE USER / GRANT / ALTER ... ON CLUSTER no longer fail with SYNTAX_ERROR from a stray FORMAT JSON (#241)CREATE / ALTER ... ON CLUSTER results are now parseable JSON again — no more Can't find meta when reading the per-host execution status (#263)ON CLUSTER substring inside INSERT data (e.g. 'REGION CLUSTER') is no longer mistaken for the keyword — \b word boundaries match the real keyword only (#262)Statement::hasErrorClickhouse() now confirms a tail-regex match with json_validate() (PHP 8.3+) before flagging an error, so valid JSON whose data legitimately contains ClickHouse exception text is not reported as a failure (@jradtilbrook)tests/ClickHouse26/OnClusterTest.php — distributed DDL regression tests (CREATE / ALTER / CREATE USER ... ON CLUSTER); skips gracefully when no Keeper/ZooKeeper backend is configuredtests/clickhouse-latest-config/keeper.xml, mounted in docker-compose.yaml and copied in CI) so the single-node default cluster can execute ON CLUSTER queriestestInsertWithOnClusterInData added to both CH 21 and CH 26 client tests (#262)FORMAT JSON in the query when inserting a record (superseded by the default_format fix)convertParamValue() now escapes \ → \\ and ' → \' for scalar String params in selectWithParams() / writeWithParams(). Previously strings like hello\ caused CANNOT_PARSE_ESCAPE_SEQUENCE in ClickHouse (@sander-hash, @tom-on-the-internet)writeWithParams with backslashCANNOT_PARSE_ESCAPE_SEQUENCEconvertParamValue() now produces ClickHouse-compatible array literals ['foo','bar'] (single quotes) instead of JSON format ["foo","bar"]. Previously any Array(String) parameter in selectWithParams() / writeWithParams() failed with a parse error (@sander-hash)' or \ are now properly escaped (e.g. "it's" → 'it\'s'), preventing query errors and array-element injectionArray(UInt32), Array(String), empty arrays, strings with single quotes, strings with backslashes, and injection attemptsbindParams() now casts integer array keys to string before passing to bindParam(string $column), restoring backward compatibility with numerically-indexed arrays. Affected downstream packages like phpclickhouse-laravel (@yehezkel-fullpath)testConnectTimeout, testStreamInsert, testStreamInsertFormatJSONEachRow marked [@group](https://github.com/group) flaky and excluded via PHPUnit config. Run separately with ./vendor/bin/phpunit --group flakytestBindParamsWithNumericKeys, testBindParamsWithMixedKeys covering #256 regressionBindings::bindParam() rejects integer keysreadWithParams() (#254) — stream query results with native ClickHouse typed parameters ({name:Type} syntax), combining server-side parameter binding with streaming output (@sander-hash)Stringable for consistency (@sander-hash)readWithParams() in native-params, streaming, and per-query-settings guidesWARNING : PHP 8.1+
ClickHouseDB\Type\Boolean class with fromString(), fromBool(), getValue(), __toString() (@sander-hash)Degeneration, IStream, Type) unchanged for backward compatibilitysecure-scan.md. All clean: no backdoors, exfiltration, or obfuscation foundValueFormatterTest (28) — SQL escaping, types, DateTimeInterface, ExpressionStrictQuoteLineTest (32) — CSV/TSV/Insert formatting, encodeStringSettingsTest (24) — get/set/is, sessions, timeouts, readonlyWriteToFileTest (15) — file validation, formats, gzipTypesTest (26+5) — UInt64, DateTime64, MapType, TupleType, Boolean and moreBindingsUnitTest (16) — compile_binds, Conditions {if}/{else}CurlerRequestResponseTest (35) — headers, auth, URL, JSON, dumpMany changes see change.log
BREAKING CHANGES
SELECT number+{num_num:UInt8} as numbe_r, {xpx1:UInt32} as xpx1,{zoza:String} as zoza FROM system.numbers LIMIT 6
Change exceptionCode in Clickhouse version 22.8.3.13 (official build) #180
Fix Docker for tests, Change the correct Docker image name #177
Some type fix
Fix types: max_execution_time & setConnectTimeOut, undo: Support floats in timeout and connect_timeout #173
add mbstring to composer require #183
fixed progressFunction #182
Add allow_plugins setting since Composer 2.2.x #178
Re upload 1.5.0 - hot fix types error
Add two new types of authentication #139 Fixed typo in streamRead exception text #140 fix the exception(multi-statement not allow) when sql end with ';' #138 Added more debug info for empty response with error #135
dropOldPartitions$client->getServerVersion()$client->ping()include.php - ClickHouseException before exceptionsinterface ClickHouseExceptionHow can I help you explore Laravel packages today?