kalider / php-simple-queue
There is no license information available for the latest version (1.0.0) of this package.
php simple queue with small footprint
1.0.0
2026-08-28 03:13 UTC
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.19 || ^3.0
- monolog/monolog: ^1.26
- phpunit/phpunit: ^6.5
README
A lightweight, modular queue library for PHP 7.0+ implementing the Adapter Pattern and Factory Pattern. Supports MySQL (PDO) and Redis (phpredis), featuring exponential backoff, procedural job execution, and PSR-3 logging (Monolog).
๐๏ธ Architecture & Design Patterns
- Adapter Pattern:
PhpSimpleQueue\Queue: The client interface/wrapper implementingQueueInterface.PhpSimpleQueue\Adapters\QueueAdapterInterface: The common contract for queue drivers.PhpSimpleQueue\Adapters\MysqlAdapter: MySQL storage adapter using PDO with atomic locking tokens.PhpSimpleQueue\Adapters\RedisAdapter: Redis storage adapter usingphprediswith atomic Lua scripts.
- Factory Pattern:
PhpSimpleQueue\Factories\ConnectionFactory: Assembles and returns database/cache connection instances (PDOorRedis).PhpSimpleQueue\Factories\QueueFactory: Instantiates configuredQueueinstances with the corresponding adapter and connection.
๐ Features
- PHP 7.0+ Compatible: Works on PHP 7.0 through PHP 8.x.
-
Dual Storage Adapters:
-
MySQL (PDO): Safe concurrency using atomic lock tokens (
reserved_by&reserved_at). -
Redis (
phpredis): Atomic pop using Lua scripts and Sorted Sets (ZSET) for delayed processing.
-
MySQL (PDO): Safe concurrency using atomic lock tokens (
- Delayed Jobs: Built-in support for delaying job execution by $N$ seconds.
-
Exponential Backoff: Automatic retry with exponential delay (
pow(2, attempts) * 10seconds) up to a max attempt threshold (default: 5). -
Dead Letter / Failed Queue: Permanently failed jobs are moved to
failed_jobstable (MySQL) orjobs:failedlist (Redis). -
Procedural Job Dispatching: Execute global functions or callables via
call_user_func_array(). - PSR-3 Logging: Fully compatible with PSR-3 loggers like Monolog.
- Code Style (PHP-CS-Fixer): Pre-configured PSR-12 / PSR-2 code formatting and checking.
๐ฆ Installation
Install via Composer:
composer require kalider/php-simple-queue
๐๏ธ Database Setup (MySQL)
If using the MySQL adapter, create the jobs and failed_jobs tables:
CREATE TABLE IF NOT EXISTS `jobs` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `payload` LONGTEXT NOT NULL, `available_at` INT UNSIGNED NOT NULL, `created_at` INT UNSIGNED NOT NULL, `reserved_at` INT UNSIGNED NULL DEFAULT NULL, `reserved_by` VARCHAR(255) NULL DEFAULT NULL, INDEX `idx_queue_reservation` (`reserved_at`, `available_at`), INDEX `idx_reserved_by` (`reserved_by`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `failed_jobs` ( `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `payload` LONGTEXT NOT NULL, `failed_at` INT UNSIGNED NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
๐ ๏ธ Usage
1. Define Your Job Function
function send_welcome_email(array $data) { echo "Sending email to {$data['name']} ({$data['email']})...\n"; }
2. Creating Queue via QueueFactory
A. MySQL Queue (via Config Array)
<?php require_once __DIR__ . '/vendor/autoload.php'; use PhpSimpleQueue\Factories\QueueFactory; $queue = QueueFactory::create([ 'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => 3306, 'database' => 'your_database', 'username' => 'root', 'password' => 'secret', 'table' => 'jobs', // optional, default: 'jobs' 'failed_table' => 'failed_jobs', // optional, default: 'failed_jobs' ]); // Push immediate job $queue->push('send_welcome_email', ['email' => 'john@example.com', 'name' => 'John Doe']); // Push delayed job (delay 60 seconds) $queue->push('send_welcome_email', ['email' => 'jane@example.com', 'name' => 'Jane Doe'], 60);
B. MySQL Queue (with Existing PDO Instance)
$pdo = new PDO('mysql:host=127.0.0.1;dbname=your_database', 'root', 'secret'); $queue = QueueFactory::create([ 'pdo' => $pdo, // or 'connection' => $pdo ]);
C. Redis Queue (via Config Array)
$queue = QueueFactory::create([ 'driver' => 'redis', 'host' => '127.0.0.1', 'port' => 6379, 'password' => null, // optional 'database' => 0, // optional 'queue' => 'default', // optional, default: 'jobs' ]); $queue->push('send_welcome_email', ['email' => 'john@example.com', 'name' => 'John Doe']);
D. Redis Queue (with Existing Redis Instance)
$redis = new Redis(); $redis->connect('127.0.0.1', 6379); $queue = QueueFactory::create([ 'redis' => $redis, // or 'connection' => $redis ]);
3. Manual Adapter Instantiation (Adapter Pattern)
You can also instantiate adapters directly without the factory:
use PhpSimpleQueue\Adapters\MysqlAdapter; use PhpSimpleQueue\Queue; $adapter = new MysqlAdapter($pdo, 'jobs', 'failed_jobs'); $queue = new Queue($adapter);
4. Running the Worker (with Monolog)
Create a daemon worker script (e.g., worker.php):
<?php require_once __DIR__ . '/vendor/autoload.php'; use PhpSimpleQueue\Factories\QueueFactory; use PhpSimpleQueue\Worker; use Monolog\Logger; use Monolog\Handler\StreamHandler; // 1. Setup PSR-3 Logger (Monolog) $logger = new Logger('queue_worker'); $logger->pushHandler(new StreamHandler(__DIR__ . '/worker.log', Logger::INFO)); $logger->pushHandler(new StreamHandler('php://stdout', Logger::INFO)); // 2. Setup Queue via Factory $queue = QueueFactory::create([ 'driver' => 'mysql', 'host' => '127.0.0.1', 'database' => 'your_database', 'username' => 'root', 'password' => 'secret', ]); // 3. Start Worker Daemon $worker = new Worker($queue, $logger, 3); // sleep 3 seconds when queue is empty $worker->daemon();
Run the worker:
php worker.php
๐ Failure & Retry Mechanism
- When an unhandled exception or error occurs:
- An
ERRORentry is logged with the error message and job ID. - The attempt count is incremented (
attempts + 1). - If attempts < 5, re-queued with exponential backoff: $$\text{Delay} = 2^{\text{attempts}} \times 10\text{ seconds}$$
- If attempts $\ge 5$, the job is permanently marked as failed and moved to
failed_jobstable (MySQL) orjobs:failedlist (Redis).
- An
๐งน Code Style & Linting (PHP-CS-Fixer)
Projek ini dilengkapi konfigurasi PHP-CS-Fixer dengan standar PSR-12 / PSR-2.
Periksa format kode tanpa mengubah file (dry-run & diff):
composer cs:check
Perbaiki format kode secara otomatis:
composer cs:fix
๐งช Running Tests
./vendor/bin/phpunit # or composer test
๐ License
MIT License.