prsw/ext-sqlx

Async SQL database access via Rust sqlx

Maintainers

Package info

github.com/praswicaksono/ext-sqlx

Language:Rust

Type:php-ext

Ext name:ext-sqlx

pkg:composer/prsw/ext-sqlx

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.2 2026-05-29 08:24 UTC

This package is auto-updated.

Last update: 2026-05-29 08:27:11 UTC


README

An asynchronous SQL database extension for PHP, powered by the incredible Rust sqlx library and bridged to PHP's Revolt event loop via ext-php-rs.

Enjoy non-blocking database queries in PHP using Tokio's ultra-fast multithreaded runtime.

Features

  • Truly Async: Your PHP event loop keeps ticking while heavy database queries run on Rust threads.
  • Multi-Database: Built-in support for SQLite, MySQL/MariaDB, and PostgreSQL.
  • Streaming: Stream massive query results efficiently back to PHP memory using Tokio MPSC channels.
  • Connection Pooling: Automatic, configurable connection pools under the hood.

Installation

This extension is distributed as a pre-compiled binary via PIE (PHP Installer for Extensions). You do not need Rust installed on your server to use this extension.

# Ensure you have pie installed, then run:
pie install prsw/sqlx-php

You must also require the PHP-side event loop dependencies in your project:

composer require amphp/amp revolt/event-loop

Quick Start

You must initialize the Tokio bridge and register it with Revolt before queueing your database logic.

<?php
require 'vendor/autoload.php';

use Revolt\EventLoop;
use Sqlx\Connection;

// 1. Initialize the Tokio <-> Revolt bridge
$fd = Connection::init();
$f = fopen("php://fd/" . $fd, 'r+');
stream_set_blocking($f, false);
$watcherId = EventLoop::onReadable($f, fn() => Connection::wakeup());

// 2. Queue your async application logic
EventLoop::queue(function() use ($watcherId) {
    try {
        // Connect via DSN (sqlite://, mysql://, postgres://)
        $db = new Connection("sqlite://example.sqlite", [
            "max_connections" => 5
        ]);
        
        $db->execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
        
        // Execute queries with parameterized bindings
        $db->execute("INSERT INTO users (name) VALUES (?)", ["Alice"]);
        $db->execute("INSERT INTO users (name) VALUES (?)", ["Bob"]);
        
        // Fetch all rows instantly into an array
        $rows = $db->fetchAll("SELECT * FROM users", []);
        
        // OR stream large datasets asynchronously row-by-row
        $stream = $db->fetchAllStream("SELECT * FROM users", []);
        foreach ($stream as $row) {
            echo "User: {$row['name']}\n";
        }

    } finally {
        EventLoop::unreference($watcherId);
    }
});

// 3. Start the Event Loop
EventLoop::run();

Note: For a more comprehensive example including transactions, check out example/basic_usage.php!