Search by

codelieutenant / scylla-driver

CodeLieutenant

ScyllaDB/Cassandra PHP driver

Package info

github.com/he4rt/scylladb-php-driver

Language:C

Type:php-ext

Ext name:ext-cassandra

pkg:composer/codelieutenant/scylla-driver

Fund package maintenance!

CodeLieutenant

DanielHe4rt

Statistics

Installs: 1 062

Dependents: 0

Suggesters: 0

Stars: 124

Open Issues: 2

v1.5.1 2026-09-05 16:45 UTC

README

ScyllaDB PHP Driver

A modern PHP extension for ScyllaDB and Apache Cassandra

Tests Build Docker Image Packagist Version License PHP ScyllaDB

Read the documentation →

A high-performance PHP extension for ScyllaDB and Apache Cassandra 3.0+, built on top of the ScyllaDB C/C++ Driver. Communicates exclusively over the native CQL binary protocol.

The extension is actively being migrated from C++ to C23 for improved performance, safety, and maintainability.

Compatibility

Component Supported versions
PHP 8.2, 8.3, 8.4, 8.5
ScyllaDB 4.4.x, 5.x, 6.x
Apache Cassandra 3.0+ (via DataStax libcassandra)
Architecture x86-64 (64-bit only)
Thread safety NTS and ZTS
Compilers GCC 13+, Clang 16+
OS Linux, macOS

Quick Start

<?php

$session = Cassandra::cluster()
    ->withContactPoints('127.0.0.1')
    ->withPort(9042)
    ->withCredentials('cassandra', 'cassandra')
    ->withTokenAwareRouting(true)
    ->build()
    ->connect('my_keyspace');

// Simple string query
$session->execute("INSERT INTO users (id, name) VALUES (uuid(), 'Alice')");

// Prepared statement with bound values
$prepared = $session->prepare('SELECT * FROM users WHERE id = ?');
$result = $session->execute($prepared, ['arguments' => [$id]]);

foreach ($result as $row) {
    printf("User: %s\n", $row['name']);
}

Async and Event Loops

executeAsync(), prepareAsync(), connectAsync() and closeAsync() return a Cassandra\Future that resolves on the driver's own IO threads. Every future exposes a completion descriptor, so a PHP event loop can await a query without blocking the thread.

$future = $session->executeAsync('SELECT * FROM users');

$read = [$future->getResource()];
$write = $except = [];
stream_select($read, $write, $except, 5);

foreach ($future->get() as $row) {
    printf("User: %s\n", $row['name']);
}

For hundreds of queries in flight, Cassandra\Async\Reactor folds every completion onto one descriptor, so the file descriptor count stays flat:

use Cassandra\Async\Reactor;

foreach ($ids as $id) {
    Reactor::add($session->executeAsync($prepared, ['arguments' => [$id]]));
}

$resource = Reactor::resource();

while (Reactor::pending() > 0) {
    $read = [$resource];
    $write = $except = [];
    stream_select($read, $write, $except, 5);

    foreach (Reactor::poll(64) as $future) {
        $rows = $future->get();
    }
}
You use Reach for
No framework, tens of futures Future::getResource() with stream_select()
Revolt, AMPHP or ReactPHP codelieutenant/scylla-driver-async-adapters
Hundreds or thousands in flight Cassandra\Async\Reactor
Swoole or OpenSwoole A build with PHP_SCYLLADB_ENABLE_SWOOLE, then plain get()
PHP 8.6 A build with PHP_SCYLLADB_ENABLE_POLL_API, then Cassandra\Async\Poll

Read asynchronous queries and event loops for the full picture.

Installation

Via PIE (recommended)

PIE is the official PHP extension installer. It handles downloading, building, and installing the extension in a single command.

Package: codelieutenant/scylla-driver

1. Install native dependencies

PIE builds the extension from source, so the C/C++ driver (and its own dependency, libuv) must be present first.

# libuv
./scripts/compile-libuv.sh --prefix ~/.local

# ScyllaDB driver (default)
./scripts/compile-cpp-driver.sh --driver scylladb --prefix ~/.local

# — or — DataStax Cassandra driver
./scripts/compile-cpp-driver.sh --driver cassandra --prefix ~/.local

Export the pkg-config path so CMake can find both libraries:

export PKG_CONFIG_PATH="$HOME/.local/lib/pkgconfig:$PKG_CONFIG_PATH"

2. Install with PIE

# ScyllaDB driver (default)
pie install codelieutenant/scylla-driver

# DataStax Cassandra driver
pie install codelieutenant/scylla-driver --enable-libcassandra

PIE places the compiled cassandra.so in your PHP extension directory and enables it automatically.

Prebuilt binaries

Each release attaches a .tar.gz for every supported combination. The archive holds cassandra.so and cassandra.ini.

Two families are published:

Family Built on Runs on
manylinux_2_28_<arch> AlmaLinux 8, glibc 2.28, OpenSSL 1.1.1 RHEL / Rocky / AlmaLinux 8, Ubuntu 18.04 and 20.04, Debian 10 and 11
ubuntu-<release> a current Ubuntu runner recent Ubuntu releases

Every release checks that the manylinux_2_28 archives ask for no symbol above glibc 2.28, GLIBCXX 3.4.25 or CXXABI 1.3.11 — the versions RHEL 8 provides.

The module also needs libssl.so.1.1 and libcrypto.so.1.1. Those are the system OpenSSL on RHEL 8, Ubuntu 20.04 and Debian 11. On a distribution that moved to OpenSSL 3 (RHEL 9+, Ubuntu 22.04+, Debian 12+), install the OpenSSL 1.1 compatibility package or build from source instead.

Every archive also needs libuv.so.1 and libgmp.so.10. The C/C++ driver itself is linked into the module, so you do not install it separately.

The file name is <family>-php<version>-<nts|ts>-<driver>.tar.gz. Match all four parts to your host:

php -i | grep -E 'PHP Version|Thread Safety|extension_dir'

Install the extension:

tar xzf manylinux_2_28_x86_64-php8.4-nts-scylladb.tar.gz
sudo cp cassandra.so "$(php-config --extension-dir)/"

Then enable it. Copy cassandra.ini into the scan directory that php --ini reports, or add extension=cassandra to your php.ini. Confirm the result:

php -m | grep cassandra

ts archives are for a ZTS PHP build. nts archives are for the default non-thread-safe build. A mismatch stops the extension from loading.

Manual build from source

Prerequisites

The extension links against the ScyllaDB C/C++ driver (or DataStax libcassandra), which in turn needs libuv. Use the provided scripts to build them from source:

# Install libuv (latest stable)
./scripts/compile-libuv.sh --prefix ~/.local

# Install the ScyllaDB C/C++ driver
./scripts/compile-cpp-driver.sh --driver scylladb --prefix ~/.local

# Build PHP with debug symbols (optional, for development)
./scripts/compile-php.sh -v 8.4 -d -o ./php

System packages (Debian/Ubuntu)

apt install -y build-essential ninja-build cmake \
    libssl-dev libgmp-dev zlib1g-dev libpcre3-dev

Building the Extension

The project uses CMake with presets for common configurations. Preset names follow the pattern <BuildType>PHP<Version><ThreadModel>, e.g. DebugPHP8.4NTS.

Configure and compile

# List all available presets
cmake --list-presets

# Configure (e.g. debug build, PHP 8.4, non-thread-safe)
cmake --preset DebugPHP8.4NTS

# Compile
cmake --build out/DebugPHP8.4NTS

Available build types

Preset prefix Description
Debug Debug symbols, no optimisations
Release Fully optimised
RelWithDebugInfo Optimised with debug info

CMake options

option(ENABLE_SANITIZERS   "Enable AddressSanitizer + UndefinedSanitizer" OFF)
option(ENABLE_AVX          "Enable AVX instruction set"                   OFF)
option(ENABLE_AVX2         "Enable AVX2 instruction set"                  OFF)
option(ENABLE_LTO          "Enable Link-Time Optimisation"                OFF)

set(CPU_TYPE "x86-64-v3" CACHE STRING
    "x86-64 micro-arch: x86-64 | x86-64-v2 | x86-64-v3 | x86-64-v4 | native")

# PHP
set(PHP_VERSION_FOR_PHP_CONFIG "8.4" CACHE STRING "PHP version")
option(PHP_DEBUG       "Debug build of PHP"    ON)
option(PHP_THREAD_SAFE "ZTS (thread-safe) PHP" OFF)

# Linking
option(PHP_SCYLLADB_STATIC  "Statically link the C/C++ driver"  OFF)
option(USE_LIBCASSANDRA     "Use DataStax libcassandra instead" OFF)

Regenerating CMake presets

After adding a new PHP version, regenerate CMakePresets.json:

php generate-presets.php

Running Tests

Start a local ScyllaDB node, then run the Pest test suite:

# 1. Start ScyllaDB via Docker Compose
./scripts/run-scylladb.sh

# 2. Build the extension
cmake --preset DebugPHP8.4NTS
cmake --build out/DebugPHP8.4NTS

# 3. Install Composer dependencies
composer install

# 4. Run tests
php ./vendor/bin/pest

Environment variables for the test suite:

Variable Default Description
SCYLLADB_HOSTS 127.0.0.1 Comma-separated list of nodes
SCYLLADB_PORT 9042 CQL native port
SCYLLADB_USERNAME cassandra Username
SCYLLADB_PASSWORD cassandra Password
SCYLLADB_KEYSPACE (empty) Default keyspace

Development Status

The extension is undergoing an incremental C++ → C23 migration. The src/Cluster/ module is the canonical reference implementation.

Module Status
Cluster Refactored (C23 reference)
RetryPolicy Partial — stubs done, handlers need C port
DateTime Partial — stubs done
SSLOptions Partial — stubs done
Database Legacy
Type Legacy
Numbers Legacy
TimestampGenerator Legacy
Exception Legacy (thin wrappers)

Contributing

  • Bug reports — please include driver version, PHP version, ScyllaDB version, dependency versions, a full stack trace, and steps to reproduce.
  • Pull requests — fork the repository and open a PR. See CONTRIBUTING.md for the full contribution guide.
  • Questions / discussions — join the ScyllaDB Developers Discord.

License

Copyright © DataStax, Inc. and contributors.

Licensed under the Apache License, Version 2.0.