Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Clickhouse Php Client Laravel Package

the-tinderbox/clickhouse-php-client

PHP 7.1+ ClickHouse HTTP client built on Guzzle. Configure single servers or clusters, pick random or specific hosts, and run queries per-cluster. Supports async SELECT and INSERT from local files via a simple Client/ServerProvider API.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
To start using `the-tinderbox/clickhouse-php-client` in Laravel, install the package via Composer:
```bash
composer require the-tinderbox/clickhouse-php-client

First Query

Initialize a single-server client in your Laravel service provider or a dedicated ClickHouse facade:

use Tinderbox\Clickhouse\Server;
use Tinderbox\Clickhouse\ServerProvider;
use Tinderbox\Clickhouse\Client;

// In a service provider or facade
$server = new Server('127.0.0.1', '8123', 'default', 'user', 'pass');
$serverProvider = (new ServerProvider())->addServer($server);
$client = new Client($serverProvider);

// Example: Fetch data from ClickHouse
$result = $client->readOne('SELECT * FROM your_table LIMIT 10');
return $result->rows; // Returns an array of rows

Laravel Integration Tip

Create a ClickHouse facade in app/Providers/AppServiceProvider.php for easy access:

use Illuminate\Support\Facades\Facade;

class ClickHouseFacade extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'clickhouse.client';
    }
}

Register the client in the same file:

public function register()
{
    $this->app->singleton('clickhouse.client', function () {
        $server = new Server(config('clickhouse.host'), config('clickhouse.port'), config('clickhouse.database'), config('clickhouse.user'), config('clickhouse.password'));
        $serverProvider = (new ServerProvider())->addServer($server);
        return new Client($serverProvider);
    });
}

Implementation Patterns

Cluster Management

For high availability, configure a cluster in your config/clickhouse.php:

return [
    'clusters' => [
        'analytics' => [
            [
                'host' => '127.0.0.1',
                'port' => '8123',
                'database' => 'analytics',
                'user' => 'user',
                'password' => 'pass',
            ],
            [
                'host' => '127.0.0.2',
                'port' => '8123',
                'database' => 'analytics',
                'user' => 'user',
                'password' => 'pass',
            ],
        ],
    ],
];

Use the cluster in your code:

$client->onCluster('analytics');
$result = $client->readOne('SELECT * FROM events');

Async Queries

Execute multiple queries asynchronously for performance:

list($events, $users) = $client->read([
    ['query' => 'SELECT * FROM events WHERE date = ?', ['2023-01-01']],
    ['query' => 'SELECT * FROM users WHERE status = ?', ['active']],
], 2); // Concurrency limit

File-Based Operations

Use local files for bulk inserts or temporary tables:

// Insert from CSV
$client->writeFiles('table', ['date', 'value'], [
    new \Tinderbox\Clickhouse\Common\File(storage_path('app/export.csv')),
]);

// Query using a temp table
$result = $client->readOne(
    'SELECT * FROM main_table WHERE id IN _temp_ids',
    new \Tinderbox\Clickhouse\TempTable('_temp_ids', storage_path('app/ids.csv'), ['id' => 'UInt64'])
);

Laravel Eloquent Integration

Extend Eloquent queries with ClickHouse:

// In a model trait or service
public function scopeInClickHouse($query, $column, $values)
{
    $client = app('clickhouse.client');
    $tempTable = new \Tinderbox\Clickhouse\TempTable('_filter', $values->path(), ['id' => 'UInt64']);
    $result = $client->readOne("SELECT * FROM {$query->getTable()} WHERE {$column} IN _filter", $tempTable);
    return $result->rows;
}

Gotchas and Tips

Debugging

  • Enable Guzzle Middleware for debugging HTTP requests:
    $client = new Client($serverProvider, [
        'http_transport_options' => [
            'middleware' => [
                new \GuzzleHttp\Middleware::tap(function ($request) {
                    LaravelLog::debug('ClickHouse Request:', ['url' => (string) $request->getUri()]);
                }),
            ],
        ],
    ]);
    

Performance Pitfalls

  • Avoid SELECT *: ClickHouse optimizes for columnar queries. Specify columns explicitly:

    // Bad
    $client->readOne('SELECT * FROM large_table');
    
    // Good
    $client->readOne('SELECT id, name FROM large_table');
    
  • Batch Async Queries: Limit concurrency ($concurrency in read()) to avoid overwhelming the server:

    $client->read($queries, 5); // Max 5 concurrent requests
    

Configuration Quirks

  • Deflate Compression: Disable if experiencing issues:

    $client = new Client($serverProvider, [
        'http_transport_options' => ['deflate' => false],
    ]);
    
  • Server Tags: Use tags to route queries to specific servers (e.g., for read/write separation):

    $server->setTag('replica');
    $client->usingServerWithTag('replica')->readOne('SELECT * FROM table');
    

Extension Points

  • Custom File Streams: Implement \Tinderbox\Clickhouse\Common\FileInterface for custom data sources (e.g., S3 files):

    class S3File implements FileInterface {
        public function getStream() { /* Return S3 stream */ }
        public function getSize() { /* Return file size */ }
    }
    
  • Query Logging: Log all queries via middleware:

    $client = new Client($serverProvider, [
        'query_logger' => function ($query, $params) {
            \Log::info('ClickHouse Query', ['query' => $query, 'params' => $params]);
        },
    ]);
    

Common Errors

Error Solution
Connection refused Verify ClickHouse HTTP port (8123 by default) and firewall rules.
Invalid query Use EXPLAIN in ClickHouse to debug syntax.
File not found Ensure paths in TempTable are absolute and accessible by the server.
Timeout Increase Guzzle timeout in http_transport_options: 'timeout' => 30.

---
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime