{"id":13467416,"url":"https://github.com/smi2/phpClickHouse","last_synced_at":"2025-03-26T02:31:22.144Z","repository":{"id":39421380,"uuid":"63620693","full_name":"smi2/phpClickHouse","owner":"smi2","description":"php ClickHouse wrapper","archived":false,"fork":false,"pushed_at":"2024-08-05T15:54:30.000Z","size":784,"stargazers_count":747,"open_issues_count":27,"forks_count":138,"subscribers_count":27,"default_branch":"master","last_synced_at":"2024-10-29T15:48:56.863Z","etag":null,"topics":["clickhouse","php","php-clickhouse","php-clickhouse-wrapper"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smi2.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-18T16:51:04.000Z","updated_at":"2024-10-29T11:26:16.000Z","dependencies_parsed_at":"2023-01-30T03:30:39.606Z","dependency_job_id":"b5cce1e7-015e-405c-8192-ed5580768c60","html_url":"https://github.com/smi2/phpClickHouse","commit_stats":{"total_commits":536,"total_committers":61,"mean_commits":8.78688524590164,"dds":0.2854477611940298,"last_synced_commit":"ba32b01c0520cba8881c5015c6ab7f9809ff68fd"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smi2%2FphpClickHouse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smi2%2FphpClickHouse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smi2%2FphpClickHouse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smi2%2FphpClickHouse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smi2","download_url":"https://codeload.github.com/smi2/phpClickHouse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245568568,"owners_count":20636803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clickhouse","php","php-clickhouse","php-clickhouse-wrapper"],"created_at":"2024-07-31T15:00:56.123Z","updated_at":"2025-03-26T02:31:22.137Z","avatar_url":"https://github.com/smi2.png","language":"PHP","readme":"PHP ClickHouse wrapper\n======================\n\n[![Downloads](https://poser.pugx.org/smi2/phpClickHouse/d/total.svg)](https://packagist.org/packages/smi2/phpClickHouse)\n[![Packagist](https://poser.pugx.org/smi2/phpClickHouse/v/stable.svg)](https://packagist.org/packages/smi2/phpClickHouse)\n[![Licence](https://poser.pugx.org/smi2/phpClickHouse/license.svg)](https://packagist.org/packages/smi2/phpClickHouse)\n\n## Features\n\n- No dependency, only Curl (support php `\u003e=7.1` )\n- Select parallel queries (asynchronous)\n- Asynchronous bulk inserts from CSV file\n- Http compression (Gzip), for bulk inserts\n- Find active host, check cluster\n- Select WHERE IN ( _local csv file_ )\n- SQL conditions \u0026 template\n- tablesSize \u0026 databaseSize\n- listPartitions\n- truncateTable in cluster\n- Insert array as column\n- Get master node replica in cluster\n- Get tableSize in all nodes\n- Async get ClickHouse progress function\n- streamRead/Write \u0026 Closure functions\n\n[Russian articles habr.com 1](https://habrahabr.ru/company/smi2/blog/317682/) [on habr.com 2](https://habr.com/company/smi2/blog/314558/)\n\n## Install composer\n\n```\ncomposer require smi2/phpclickhouse\n```\n\n\nIn php\n```php\n\n// vendor autoload \n$db = new ClickHouseDB\\Client(['config_array']);\n\nif (!$db-\u003eping()) echo 'Error connect';\n```\n\nLast stable version for \n* php 5.6 \u003c= `1.1.2`\n* php 7.2 \u003c= `1.3.10`\n* php 7.3 \u003e= `1.4.x ... 1.5.X` \n* php 8.4 \u003e= `1.6.0`\n\n\n[Packagist](https://packagist.org/packages/smi2/phpclickhouse)\n\n## Start\n\nConnect and select database:\n```php\n$config = [\n    'host' =\u003e '192.168.1.1',\n    'port' =\u003e '8123',\n    'username' =\u003e 'default',\n    'password' =\u003e '',\n    'https' =\u003e true\n];\n$db = new ClickHouseDB\\Client($config);\n$db-\u003edatabase('default');\n$db-\u003esetTimeout(1.5);      // 1 second , support only Int value\n$db-\u003esetTimeout(10);       // 10 seconds\n$db-\u003esetConnectTimeOut(5); // 5 seconds\n$db-\u003eping(true); // if can`t connect throw exception  \n```\n\nShow tables:\n```php\nprint_r($db-\u003eshowTables());\n```\n\nCreate table:\n```php\n$db-\u003ewrite('\n    CREATE TABLE IF NOT EXISTS summing_url_views (\n        event_date Date DEFAULT toDate(event_time),\n        event_time DateTime,\n        site_id Int32,\n        site_key String,\n        views Int32,\n        v_00 Int32,\n        v_55 Int32\n    )\n    ENGINE = SummingMergeTree(event_date, (site_id, site_key, event_time, event_date), 8192)\n');\n```\nShow create table:\n```php\necho $db-\u003eshowCreateTable('summing_url_views');\n```\nInsert data:\n```php\n$stat = $db-\u003einsert('summing_url_views',\n    [\n        [time(), 'HASH1', 2345, 22, 20, 2],\n        [time(), 'HASH2', 2345, 12, 9,  3],\n        [time(), 'HASH3', 5345, 33, 33, 0],\n        [time(), 'HASH3', 5345, 55, 0, 55],\n    ],\n    ['event_time', 'site_key', 'site_id', 'views', 'v_00', 'v_55']\n);\n```\n\nIf you need to insert UInt64 value, you can wrap the value in `ClickHouseDB\\Type\\UInt64` DTO.\n\n```php\n$statement = $db-\u003einsert('table_name',\n    [\n        [time(), UInt64::fromString('18446744073709551615')],\n    ],\n    ['event_time', 'uint64_type_column']\n);\nUInt64::fromString('18446744073709551615')\n```\n\nSelect:\n```php\n$statement = $db-\u003eselect('SELECT * FROM summing_url_views LIMIT 2');\n```\n\nWork with Statement:\n```php\n// Count select rows\n$statement-\u003ecount();\n\n// Count all rows\n$statement-\u003ecountAll();\n\n// fetch one row\n$statement-\u003efetchOne();\n\n// get extremes min\nprint_r($statement-\u003eextremesMin());\n\n// totals row\nprint_r($statement-\u003etotals());\n\n// result all\nprint_r($statement-\u003erows());\n\n// totalTimeRequest\nprint_r($statement-\u003etotalTimeRequest());\n\n// raw answer JsonDecode array, for economy memory\nprint_r($statement-\u003erawData());\n\n// raw curl_info answer\nprint_r($statement-\u003eresponseInfo());\n\n// human size info\nprint_r($statement-\u003einfo());\n\n// if clickhouse-server version \u003e= 54011\n$db-\u003esettings()-\u003eset('output_format_write_statistics',true);\nprint_r($statement-\u003estatistics());\n\n\n// Statement Iterator\n$state=$this-\u003eclient-\u003eselect('SELECT (number+1) as nnums FROM system.numbers LIMIT 5');\nforeach ($state as $key=\u003e$value) {\n    echo $value['nnums'];\n}\n\n```\n\nSelect result as tree:\n```php\n$statement = $db-\u003eselect('\n    SELECT event_date, site_key, sum(views), avg(views)\n    FROM summing_url_views\n    WHERE site_id \u003c 3333\n    GROUP BY event_date, url_hash\n    WITH TOTALS\n');\n\nprint_r($statement-\u003erowsAsTree('event_date.site_key'));\n\n/*\n(\n    [2016-07-18] =\u003e Array\n        (\n            [HASH2] =\u003e Array\n                (\n                    [event_date] =\u003e 2016-07-18\n                    [url_hash] =\u003e HASH2\n                    [sum(views)] =\u003e 12\n                    [avg(views)] =\u003e 12\n                )\n            [HASH1] =\u003e Array\n                (\n                    [event_date] =\u003e 2016-07-18\n                    [url_hash] =\u003e HASH1\n                    [sum(views)] =\u003e 22\n                    [avg(views)] =\u003e 22\n                )\n        )\n)\n*/\n```\n\nDrop table:\n\n```php\n$db-\u003ewrite('DROP TABLE IF EXISTS summing_url_views');\n```\n\n\n\nFeatures\n--------\n### Select parallel queries (asynchronous)\n```php\n$state1 = $db-\u003eselectAsync('SELECT 1 as ping');\n$state2 = $db-\u003eselectAsync('SELECT 2 as ping');\n\n// run\n$db-\u003eexecuteAsync();\n\n// result\nprint_r($state1-\u003erows());\nprint_r($state2-\u003efetchOne('ping'));\n```\n\n### Parallelizing massive inserts from CSV file\n```php\n$file_data_names = [\n    '/tmp/clickHouseDB_test.1.data',\n    '/tmp/clickHouseDB_test.2.data',\n    '/tmp/clickHouseDB_test.3.data',\n    '/tmp/clickHouseDB_test.4.data',\n    '/tmp/clickHouseDB_test.5.data',\n];\n\n// insert all files\n$stat = $db-\u003einsertBatchFiles(\n    'summing_url_views',\n    $file_data_names,\n    ['event_time', 'site_key', 'site_id', 'views', 'v_00', 'v_55']\n);\n```\n### Parallelizing errors\n\nselectAsync without executeAsync\n\n```php\n$select = $db-\u003eselectAsync('SELECT * FROM summing_url_views LIMIT 1');\n$insert = $db-\u003einsertBatchFiles('summing_url_views', ['/tmp/clickHouseDB_test.1.data'], ['event_time']);\n// 'Exception' with message 'Queue must be empty, before insertBatch, need executeAsync'\n```\nsee example/exam5_error_async.php\n\n### Gzip \u0026 enable_http_compression\n\nOn fly read CSV file and compress zlib.deflate.\n\n```php\n$db-\u003esettings()-\u003emax_execution_time(200);\n$db-\u003eenableHttpCompression(true);\n\n$result_insert = $db-\u003einsertBatchFiles('summing_url_views', $file_data_names, [...]);\n\n\nforeach ($result_insert as $fileName =\u003e $state) {\n    echo $fileName . ' =\u003e ' . json_encode($state-\u003einfo_upload()) . PHP_EOL;\n}\n```\n\nsee speed test `example/exam08_http_gzip_batch_insert.php`\n\n### Max execution time\n\n```php\n$db-\u003esettings()-\u003emax_execution_time(200); // second\n```\n\n\n\n\n### Connection without port \n\n```php \n$config['host']='blabla.com';\n$config['port']=0;\n// getUri() === 'http://blabla.com'\n\n\n$config['host']='blabla.com/urls';\n$config['port']=8765;\n// getUri() === 'http://blabla.com/urls'\n\n$config['host']='blabla.com:2224';\n$config['port']=1234;\n// getUri() === 'http://blabla.com:2224'\n\n\n\n\n\n``` \n\n\n### tablesSize \u0026 databaseSize\n\nResult in _human size_\n\n```php\nprint_r($db-\u003edatabaseSize());\nprint_r($db-\u003etablesSize());\nprint_r($db-\u003etableSize('summing_partions_views'));\n```\n\n### Partitions\n\n```php\n$count_result = 2;\nprint_r($db-\u003epartitions('summing_partions_views', $count_result));\n```\n\n### Select WHERE IN ( _local csv file_ )\n\n```php\n$file_name_data1 = '/tmp/temp_csv.txt'; // two column file [int,string]\n$whereIn = new \\ClickHouseDB\\Query\\WhereInFile();\n$whereIn-\u003eattachFile($file_name_data1, 'namex', ['site_id' =\u003e 'Int32', 'site_hash' =\u003e 'String'], \\ClickHouseDB\\Query\\WhereInFile::FORMAT_CSV);\n$result = $db-\u003eselect($sql, [], $whereIn);\n\n// see example/exam7_where_in.php\n```\n\n\n### Bindings\n\nBindings:\n\n```php\n$date1 = new DateTime(\"now\"); // DateTimeInterface\n\n$Bindings = [\n  'select_date' =\u003e ['2000-10-10', '2000-10-11', '2000-10-12'],\n  'datetime'=\u003e$date,\n  'limit' =\u003e 5,\n  'from_table' =\u003e 'table'\n];\n\n$statement = $db-\u003eselectAsync(\"SELECT FROM {from_table} WHERE datetime=:datetime limit {limit}\", $Bindings);\n\n// Double bind in {KEY}\n$keys=[\n            'A'=\u003e'{B}',\n            'B'=\u003e':C',\n            'C'=\u003e123,\n            'Z'=\u003e[':C',':B',':C']\n        ];\n$this-\u003eclient-\u003eselectAsync('{A} :Z', $keys)-\u003esql() // ==   \"123 ':C',':B',':C' FORMAT JSON\",\n\n\n```\n\n\n#### Simple sql conditions \u0026 template\n\nConditions is deprecated, if need use:\n`$db-\u003eenableQueryConditions();`\n\nExample with QueryConditions:\n\n```php\n\n$db-\u003eenableQueryConditions();\n\n$input_params = [\n  'select_date' =\u003e ['2000-10-10', '2000-10-11', '2000-10-12'],\n  'limit' =\u003e 5,\n  'from_table' =\u003e 'table'\n];\n\n$select = '\n    SELECT * FROM {from_table}\n    WHERE\n    {if select_date}\n        event_date IN (:select_date)\n    {else}\n        event_date=today()\n    {/if}\n    {if limit}\n    LIMIT {limit}\n    {/if}\n';\n\n$statement = $db-\u003eselectAsync($select, $input_params);\necho $statement-\u003esql();\n\n/*\nSELECT * FROM table\nWHERE\nevent_date IN ('2000-10-10','2000-10-11','2000-10-12')\nLIMIT 5\nFORMAT JSON\n*/\n\n$input_params['select_date'] = false;\n$statement = $db-\u003eselectAsync($select, $input_params);\necho $statement-\u003esql();\n\n/*\nSELECT * FROM table\nWHERE\nevent_date=today()\nLIMIT 5\nFORMAT JSON\n*/\n\n$state1 = $db-\u003eselectAsync(\n    'SELECT 1 as {key} WHERE {key} = :value',\n    ['key' =\u003e 'ping', 'value' =\u003e 1]\n);\n\n// SELECT 1 as ping WHERE ping = \"1\"\n```\n\nExample custom query Degeneration in `exam16_custom_degeneration.php`\n\n```\nSELECT {ifint VAR} result_if_intval_NON_ZERO{/if}\nSELECT {ifint VAR} result_if_intval_NON_ZERO {else} BLA BLA{/if}\n```\n\n### Settings\n\n3 way set any settings\n```php\n// in array config\n$config = [\n    'host' =\u003e 'x',\n    'port' =\u003e '8123',\n    'username' =\u003e 'x',\n    'password' =\u003e 'x',\n    'settings' =\u003e ['max_execution_time' =\u003e 100]\n];\n$db = new ClickHouseDB\\Client($config);\n\n// settings via constructor\n$config = [\n    'host' =\u003e 'x',\n    'port' =\u003e '8123',\n    'username' =\u003e 'x',\n    'password' =\u003e 'x'\n];\n$db = new ClickHouseDB\\Client($config, ['max_execution_time' =\u003e 100]);\n\n// set method\n$config = [\n    'host' =\u003e 'x',\n    'port' =\u003e '8123',\n    'username' =\u003e 'x',\n    'password' =\u003e 'x'\n];\n$db = new ClickHouseDB\\Client($config);\n$db-\u003esettings()-\u003eset('max_execution_time', 100);\n\n// apply array method\n$db-\u003esettings()-\u003eapply([\n    'max_execution_time' =\u003e 100,\n    'max_block_size' =\u003e 12345\n]);\n\n// check\nif ($db-\u003esettings()-\u003egetSetting('max_execution_time') !== 100) {\n    throw new Exception('Bad work settings');\n}\n\n// see example/exam10_settings.php\n```\n### Use session_id with ClickHouse\n\n\n`useSession()` - make new session_id or use exists `useSession(value)`\n\n\n```php\n\n// enable session_id\n$db-\u003euseSession();\n$sesion_AA=$db-\u003egetSession(); // return session_id\n\n$db-\u003ewrite(' CREATE TEMPORARY TABLE IF NOT EXISTS temp_session_test (number UInt64)');\n$db-\u003ewrite(' INSERT INTO temp_session_test SELECT number*1234 FROM system.numbers LIMIT 30');\n\n// reconnect to continue with other session\n$db-\u003euseSession($sesion_AA);\n```\n\n### Array as column\n\n```php\n$db-\u003ewrite('\n    CREATE TABLE IF NOT EXISTS arrays_test_string (\n        s_key String,\n        s_arr Array(String)\n    )\n    ENGINE = Memory\n');\n\n$db-\u003einsert('arrays_test_string',\n    [\n        ['HASH1', [\"a\", \"dddd\", \"xxx\"]],\n        ['HASH1', [\"b'\\tx\"]],\n    ],\n    ['s_key', 's_arr']\n);\n\n// see example/exam12_array.php\n```\n\nClass for FormatLine array\n\n```php\nvar_dump(\n    ClickHouseDB\\Quote\\FormatLine::CSV(\n        ['HASH1', [\"a\", \"dddd\", \"xxx\"]]\n    )\n);\n\nvar_dump(\n    ClickHouseDB\\Quote\\FormatLine::TSV(\n        ['HASH1', [\"a\", \"dddd\", \"xxx\"]]\n    )\n);\n\n// example write to file\n$row=['event_time'=\u003edate('Y-m-d H:i:s'),'arr1'=\u003e[1,2,3],'arrs'=\u003e[\"A\",\"B\\nD\\nC\"]];\nfile_put_contents($fileName,ClickHouseDB\\Quote\\FormatLine::TSV($row).\"\\n\",FILE_APPEND);\n```\n\n### HTTPS\n\n```php\n$db = new ClickHouseDB\\Client($config);\n$db-\u003esettings()-\u003ehttps();\n```\n\n\n\n### getServer System.Settings \u0026 Uptime\n\n```php\nprint_r($db-\u003egetServerUptime());\n\nprint_r($db-\u003egetServerSystemSettings());\n\nprint_r($db-\u003egetServerSystemSettings('merge_tree_min_rows_for_concurrent_read'));\n\n```\n\n### ReadOnly ClickHouse user\n\n```php\n$config = [\n    'host' =\u003e '192.168.1.20',\n    'port' =\u003e '8123',\n    'username' =\u003e 'ro',\n    'password' =\u003e 'ro',\n    'readonly' =\u003e true\n];\n```\n\n\n### Direct write to file\n\nSend result from clickhouse, without parse json.\n\n```php\n$WriteToFile=new ClickHouseDB\\WriteToFile('/tmp/_1_select.csv');\n$db-\u003eselect('select * from summing_url_views',[],null,$WriteToFile);\n// or\n$db-\u003eselectAsync('select * from summing_url_views limit 4',[],null,new ClickHouseDB\\WriteToFile('/tmp/_3_select.tab',true,'TabSeparatedWithNames'));\n$db-\u003eselectAsync('select * from summing_url_views limit 4',[],null,new ClickHouseDB\\WriteToFile('/tmp/_4_select.tab',true,'TabSeparated'));\n$statement=$db-\u003eselectAsync('select * from summing_url_views limit 54',[],null,new ClickHouseDB\\WriteToFile('/tmp/_5_select.csv',true,ClickHouseDB\\WriteToFile::FORMAT_CSV));\n```\n\n## Stream\n\nstreamWrite() : Closure stream write\n\n```php\n\n$streamWrite=new ClickHouseDB\\Transport\\StreamWrite($stream);\n\n$client-\u003estreamWrite(\n        $streamWrite,                                   // StreamWrite Class\n        'INSERT INTO {table_name} FORMAT JSONEachRow',  // SQL Query\n        ['table_name'=\u003e'_phpCh_SteamTest']              // Binds\n    );\n```\n\n\n### streamWrite \u0026 custom Closure \u0026 Deflate\n\n```php\n\n$stream = fopen('php://memory','r+');\n\nfor($f=0;$f\u003c23;$f++) {  // Make json data in stream\n        fwrite($stream, json_encode(['a'=\u003e$f]).PHP_EOL );\n}\n\nrewind($stream); // rewind stream\n\n\n$streamWrite=new ClickHouseDB\\Transport\\StreamWrite($stream);\n$streamWrite-\u003eapplyGzip();   // Add Gzip zlib.deflate in stream\n\n$callable = function ($ch, $fd, $length) use ($stream) {\n    return ($line = fread($stream, $length)) ? $line : '';\n};\n// Apply closure\n$streamWrite-\u003eclosure($callable);\n// Run Query\n$r=$client-\u003estreamWrite($streamWrite,'INSERT INTO {table_name} FORMAT JSONEachRow', ['table_name'=\u003e'_phpCh_SteamTest']);\n// Result\nprint_r($r-\u003einfo_upload());\n\n```\n\n\n### streamRead\n\nstreamRead is like `WriteToFile`\n\n\n```php\n$stream = fopen('php://memory','r+');\n$streamRead=new ClickHouseDB\\Transport\\StreamRead($stream);\n\n$r=$client-\u003estreamRead($streamRead,'SELECT sin(number) as sin,cos(number) as cos FROM {table_name} LIMIT 4 FORMAT JSONEachRow', ['table_name'=\u003e'system.numbers']);\nrewind($stream);\nwhile (($buffer = fgets($stream, 4096)) !== false) {\n    echo \"\u003e\u003e\u003e \".$buffer;\n}\nfclose($stream); // Need Close Stream\n\n\n\n// Send to closure\n\n$stream = fopen('php://memory','r+');\n$streamRead=new ClickHouseDB\\Transport\\StreamRead($stream);\n$callable = function ($ch, $string) use ($stream) {\n    // some magic for _BLOCK_ data\n    fwrite($stream, str_ireplace('\"sin\"','\"max\"',$string));\n    return strlen($string);\n};\n\n$streamRead-\u003eclosure($callable);\n\n$r=$client-\u003estreamRead($streamRead,'SELECT sin(number) as sin,cos(number) as cos FROM {table_name} LIMIT 44 FORMAT JSONEachRow', ['table_name'=\u003e'system.numbers']);\n\n```\n\n\n### insert Assoc Bulk\n\n```php\n $oneRow = [\n            'one' =\u003e 1,\n            'two' =\u003e 2,\n            'thr' =\u003e 3,\n            ];\n            $failRow = [\n                'two' =\u003e 2,\n                'one' =\u003e 1,\n                'thr' =\u003e 3,\n            ];\n\n$db-\u003einsertAssocBulk([$oneRow, $oneRow, $failRow])\n```\n### Auth methods\n\n```\n   AUTH_METHOD_HEADER       = 1;\n   AUTH_METHOD_QUERY_STRING = 2;\n   AUTH_METHOD_BASIC_AUTH   = 3;\n```\n\nIn config set `auth_method`\n\n```php\n$config=[\n    'host'=\u003e'host.com',\n    //...\n    'auth_method'=\u003e1,\n];\n\n```\n\n\n### progressFunction\n\n```php\n// Apply function\n\n$db-\u003eprogressFunction(function ($data) {\n    echo \"CALL FUNCTION:\".json_encode($data).\"\\n\";\n});\n$st=$db-\u003eselect('SELECT number,sleep(0.2) FROM system.numbers limit 5');\n\n\n// Print\n// ...\n// CALL FUNCTION:{\"read_rows\":\"2\",\"read_bytes\":\"16\",\"total_rows\":\"0\"}\n// CALL FUNCTION:{\"read_rows\":\"3\",\"read_bytes\":\"24\",\"total_rows\":\"0\"}\n// ...\n\n```\n\n### ssl CA\n```php\n$config = [\n    'host' =\u003e 'cluster.clickhouse.dns.com', // any node name in cluster\n    'port' =\u003e '8123',\n    'sslCA' =\u003e '...', \n];\n```\n\n\n### Cluster\n\n```php\n\n$config = [\n    'host' =\u003e 'cluster.clickhouse.dns.com', // any node name in cluster\n    'port' =\u003e '8123',\n    'username' =\u003e 'default', // all node have one login+password\n    'password' =\u003e ''\n];\n\n\n// client connect first node, by DNS, read list IP, then connect to ALL nodes for check is !OK!\n\n\n$cl = new ClickHouseDB\\Cluster($config);\n$cl-\u003esetScanTimeOut(2.5); // 2500 ms, max time connect per one node\n\n// Check replica state is OK\nif (!$cl-\u003eisReplicasIsOk())\n{\n    throw new Exception('Replica state is bad , error='.$cl-\u003egetError());\n}\n\n// get array nodes, and clusers\nprint_r($cl-\u003egetNodes());\nprint_r($cl-\u003egetClusterList());\n\n\n// get node by cluster\n$name='some_cluster_name';\nprint_r($cl-\u003egetClusterNodes($name));\n\n// get counts\necho \"\u003e Count Shard   = \".$cl-\u003egetClusterCountShard($name).\"\\n\";\necho \"\u003e Count Replica = \".$cl-\u003egetClusterCountReplica($name).\"\\n\";\n\n// get nodes by table \u0026 print size per node\n$nodes=$cl-\u003egetNodesByTable('shara.adpreview_body_views_sharded');\nforeach ($nodes as $node)\n{\n    echo \"$node \u003e \\n\";\n    // select one node\n    print_r($cl-\u003eclient($node)-\u003etableSize('adpreview_body_views_sharded'));\n    print_r($cl-\u003eclient($node)-\u003eshowCreateTable('shara.adpreview_body_views'));\n}\n\n// work with one node\n\n// select by IP like \"*.248*\" = `123.123.123.248`, dilitmer `;`  , if not fount -- select first node\n$cli=$cl-\u003eclientLike($name,'.298;.964'); // first find .298 then .964 , result is ClickHouseDB\\Client\n\n$cli-\u003eping();\n\n\n\n// truncate table on cluster\n$result=$cl-\u003etruncateTable('dbNane.TableName_sharded');\n\n// get one active node ( random )\n$cl-\u003eactiveClient()-\u003esetTimeout(500);\n$cl-\u003eactiveClient()-\u003ewrite(\"DROP TABLE IF EXISTS default.asdasdasd ON CLUSTER cluster2\");\n\n\n// find `is_leader` node\n$cl-\u003egetMasterNodeForTable('dbNane.TableName_sharded');\n\n\n// errors\nvar_dump($cl-\u003egetError());\n\n\n//\n\n```\n\n### Return Extremes\n\n```php\n$db-\u003eenableExtremes(true);\n```\n\n### Enable Log Query\n\nYou can log all query in ClickHouse\n\n```php\n$db-\u003eenableLogQueries();\n$db-\u003eselect('SELECT 1 as p');\nprint_r($db-\u003eselect('SELECT * FROM system.query_log')-\u003erows());\n```\n\n### isExists\n\n```php\n$db-\u003eisExists($database,$table);\n```\n\n\n### Debug \u0026 Verbose\n\n```php\n$db-\u003everbose();\n```\n\n\nVerbose to file|steam:\n\n```php\n    // init client\n    $cli = new Client($config);\n    $cli-\u003everbose();\n    // temp stream\n    $stream = fopen('php://memory', 'r+');\n    // set stream to curl\n    $cli-\u003etransport()-\u003esetStdErrOut($stream);\n    // exec curl\n    $st=$cli-\u003eselect('SElect 1 as ppp');\n    $st-\u003erows();\n    // rewind \n    fseek($stream,0,SEEK_SET);\n    \n    // output\n    echo stream_get_contents($stream);\n```\n\n\n### Dev \u0026 PHPUnit Test\n\n\n* Don't forget to run composer install. It should setup PSR-4 autoloading.\n* Then you can simply run vendor/bin/phpunit and it should output the following\n\n\n```bash\ncp phpunit.xml.dist phpunit.xml\nmcedit phpunit.xml\n```\n\nEdit in phpunit.xml constants:\n```xml\n\u003cphp\u003e\n    \u003cenv name=\"CLICKHOUSE_HOST\" value=\"127.0.0.1\" /\u003e\n    \u003cenv name=\"CLICKHOUSE_PORT\" value=\"8123\" /\u003e\n    \u003cenv name=\"CLICKHOUSE_USER\" value=\"default\" /\u003e\n    \u003cenv name=\"CLICKHOUSE_DATABASE\" value=\"phpChTestDefault\" /\u003e\n    \u003cenv name=\"CLICKHOUSE_PASSWORD\" value=\"\" /\u003e\n    \u003cenv name=\"CLICKHOUSE_TMPPATH\" value=\"/tmp\" /\u003e\n\u003c/php\u003e\n```\nRun docker ClickHouse server  \n```\ncd ./tests\ndocker-compose up\n```\n\nRun test\n```bash\n\n./vendor/bin/phpunit\n\n./vendor/bin/phpunit --group ClientTest\n\n./vendor/bin/phpunit --group ClientTest --filter testInsertNestedArray\n\n./vendor/bin/phpunit --group ConditionsTest\n\n\n```\n\n\nRun PHPStan\n\n```\n# Main\n./vendor/bin/phpstan analyse src tests --level 7\n# SRC only\n./vendor/bin/phpstan analyse src --level 7\n\n\n\n# Examples\n./vendor/bin/phpstan analyse example -a ./example/Helper.php\n\n\n\n```\n\nLicense\n-------\n\nMIT\n\nChangeLog\n---------\n\nSee [changeLog.md](CHANGELOG.md)\n","funding_links":[],"categories":["PHP","目录","非关系型数据库( NoSQL )","类库","Language bindings"],"sub_categories":["NoSQL","数据库","PHP"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmi2%2FphpClickHouse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmi2%2FphpClickHouse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmi2%2FphpClickHouse/lists"}