PHPackages                             solophp/job-queue - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. solophp/job-queue

ActiveLibrary[Queues &amp; Workers](/categories/queues)

solophp/job-queue
=================

A lightweight and flexible job queue library for PHP with database-backed persistence and object-oriented job handling.

v1.0.0(7mo ago)021MITPHPPHP &gt;=8.2

Since Oct 17Pushed 7mo agoCompare

[ Source](https://github.com/SoloPHP/Job-Queue)[ Packagist](https://packagist.org/packages/solophp/job-queue)[ RSS](/packages/solophp-job-queue/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

JobQueue
========

[](#jobqueue)

[![Latest Version on Packagist](https://camo.githubusercontent.com/4131405e919e6b0566b7d1714d4dbe2c10869e1daeba33151552f660581ee4e4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6c6f7068702f6a6f622d71756575652e737667)](https://packagist.org/packages/solophp/job-queue)[![License](https://camo.githubusercontent.com/916e6e659666e6a83ac91113084055f030d6dacdc9e1a063c9a81b0953146bbf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f736f6c6f7068702f6a6f622d71756575652e737667)](https://github.com/solophp/job-queue/blob/main/LICENSE)[![PHP Version](https://camo.githubusercontent.com/983c6de39da561dcc71452d54e6b16735f2dd7e3f4a76978d05f9fe989ea96a3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f736f6c6f7068702f6a6f622d71756575652e737667)](https://packagist.org/packages/solophp/job-queue)

A lightweight and flexible job queue library for PHP with database-backed persistence and object-oriented job handling. Supports scheduled execution, retries, job expiration, indexed job types, automatic deletion of completed jobs, and type-safe job classes.

🧰 Features
----------

[](#-features)

- **Type-Safe Jobs** – Object-oriented job classes with `JobInterface`
- **Job Retries** – Configurable max retry attempts before marking as failed
- **Job Expiration** – Automatic expiration via `expires_at` timestamp
- **Indexed Job Types** – Fast filtering by `type`
- **Row-Level Locking** – Prevents concurrent execution of the same job
- **Transactional Safety** – All job operations are executed within a transaction
- **Optional Process Locking** – Prevent overlapping workers using `LockGuard`
- **Optional Deletion on Success** – Set `deleteOnSuccess: true` to automatically delete jobs after success
- **Dependency Injection** – Support for PSR-11 containers and factory methods for automatic dependency injection

📦 Installation
--------------

[](#-installation)

```
composer require solophp/job-queue

# Optional logging

To enable PSR-3 logging pass any `Psr\\Log\\LoggerInterface` implementation (e.g. [SoloPHP Logger](https://github.com/SoloPHP/Logger)) to the `JobQueue` constructor:

```php
use Solo\\Logger\\Logger;

$logger = new Logger(__DIR__.'/storage/logs/queue.log');
$queue  = new JobQueue($connection, logger: $logger);
```

```

## 📋 Requirements

- **PHP**: >= 8.2
- **Extensions**:
  - `ext-json` - for JSON payload handling
  - `ext-posix` - for LockGuard process locking (optional)
- **Dependencies**:
  - `doctrine/dbal` - for database operations

This package uses Doctrine DBAL for database abstraction, providing support for multiple database platforms (MySQL, PostgreSQL, SQLite, SQL Server, Oracle, etc.) with consistent API.

## ⚙️ Setup

```php
use Solo\JobQueue\JobQueue;
use Doctrine\DBAL\DriverManager;

$connectionParams = [
    'dbname' => 'test',
    'user' => 'username',
    'password' => 'password',
    'host' => 'localhost',
    'driver' => 'pdo_mysql',
];
$connection = DriverManager::getConnection($connectionParams);
$queue = new JobQueue($connection, table: 'jobs', maxRetries: 5, deleteOnSuccess: true);
$queue->install(); // creates the jobs table if not exists

```

🚀 Usage
-------

[](#-usage)

### Create a Job Class

[](#create-a-job-class)

```
use Solo\Contracts\JobQueue\JobInterface;

class SendEmailJob implements JobInterface
{
    public function __construct(
        private string $to,
        private string $subject,
        private string $body
    ) {}

    public function handle(): void
    {
        // Send email logic here
        mail($this->to, $this->subject, $this->body);
    }
}
```

### Push Jobs to Queue

[](#push-jobs-to-queue)

```
$job = new SendEmailJob('user@example.com', 'Welcome!', 'Welcome to our service');
$jobId = $queue->push($job);

// With type for filtering
$jobId = $queue->push($job, 'email');

// Schedule for later
$scheduledJob = new SendEmailJob('user@example.com', 'Reminder', 'Don\'t forget!');
$queue->push($scheduledJob, 'email', new DateTimeImmutable('tomorrow'));
```

### Process Jobs

[](#process-jobs)

```
$queue->processJobs(10); // Process up to 10 jobs
```

🔒 Using `LockGuard` (optional)
------------------------------

[](#-using-lockguard-optional)

```
use Solo\JobQueue\LockGuard;

$lockFile = __DIR__ . '/storage/locks/my_worker.lock';
$lock = new LockGuard($lockFile);

if (!$lock->acquire()) {
    exit(0); // Another worker is already running
}

try {
    $queue->processJobs();
} finally {
    $lock->release(); // Optional, auto-released on shutdown
}
```

💉 Dependency Injection
----------------------

[](#-dependency-injection)

JobQueue supports automatic dependency injection through PSR-11 containers and factory methods. This allows jobs to access services without serializing them into the queue.

### Setup with Container

[](#setup-with-container)

Pass a PSR-11 container to the `JobQueue` constructor:

```
use Solo\JobQueue\JobQueue;
use Psr\Container\ContainerInterface;

$queue = new JobQueue(
    connection: $connection,
    table: 'jobs',
    maxRetries: 5,
    deleteOnSuccess: true,
    container: $container  // PSR-11 container
);
```

### Create Job with Factory Method

[](#create-job-with-factory-method)

Jobs that need dependencies should:

1. Store only data (not services) in constructor
2. Implement `JsonSerializable` to serialize only data
3. Provide a static `createFromContainer` factory method

```
use Solo\Contracts\JobQueue\JobInterface;
use Psr\Container\ContainerInterface;

class ProcessOrderJob implements JobInterface, \JsonSerializable
{
    private ?OrderRepository $orderRepository = null;
    private ?PaymentService $paymentService = null;

    public function __construct(
        private readonly int $orderId
    ) {
    }

    /**
     * Factory method for creating job with dependencies from container
     */
    public static function createFromContainer(ContainerInterface $container, array $data): self
    {
        $job = new self($data['orderId']);

        // Inject dependencies from container
        $job->orderRepository = $container->get(OrderRepository::class);
        $job->paymentService = $container->get(PaymentService::class);

        return $job;
    }

    /**
     * Serialize only data (not dependencies) for queue storage
     */
    public function jsonSerialize(): array
    {
        return [
            'orderId' => $this->orderId
        ];
    }

    public function handle(): void
    {
        $order = $this->orderRepository->find($this->orderId);
        $this->paymentService->process($order);
    }
}
```

### How It Works

[](#how-it-works)

1. **When pushing to queue**: Only data from `jsonSerialize()` is stored in the database
2. **When processing**: JobQueue checks if the job class has a `createFromContainer` method
3. **If found**: Uses the factory method to create the job instance with dependencies
4. **If not found**: Falls back to direct instantiation with serialized data

This approach keeps your queue storage clean while enabling full dependency injection support.

🔗 Integration with Async Event-Dispatcher
-----------------------------------------

[](#-integration-with-async-event-dispatcher)

JobQueue provides seamless integration with [SoloPHP Async Event-Dispatcher](https://github.com/SoloPHP/async-event-dispatcher) through the built-in `SoloJobQueueAdapter` and `AsyncEventJob` classes.

### Basic Setup

[](#basic-setup)

```
use Solo\AsyncEventDispatcher\{AsyncEventDispatcher, ReferenceListenerRegistry, ListenerReference};
use Solo\AsyncEventDispatcher\Adapter\SoloJobQueueAdapter;
use Solo\JobQueue\JobQueue;

// Setup JobQueue
$queue = new JobQueue($connection);
$queue->install();

// Setup AsyncEventDispatcher
$registry = new ReferenceListenerRegistry();
$registry->addReference(UserRegistered::class, new ListenerReference(SendWelcomeEmail::class, 'handle'));

$adapter = new SoloJobQueueAdapter($queue, $container);
$dispatcher = new AsyncEventDispatcher($registry, $adapter);

// Dispatch events - they'll be queued as jobs automatically
$dispatcher->dispatch(new UserRegistered('john@example.com'));

// Process async events
$queue->processJobs(10, 'async_event');
```

The `AsyncEventJob` is automatically used by the adapter to handle event deserialization and listener execution.

For complete async event processing setup, refer to the [Async Event-Dispatcher documentation](https://github.com/SoloPHP/async-event-dispatcher).

🧪 API Methods
-------------

[](#-api-methods)

MethodDescription`install()`Create the jobs table`push(JobInterface $job, ?string $type = null, ?DateTimeImmutable $scheduledAt = null, ?DateTimeImmutable $expiresAt = null)`Push job to the queue with optional type filtering`addJob(array $payload, ?DateTimeImmutable $scheduledAt = null, ?DateTimeImmutable $expiresAt = null, ?string $type = null)`Add job to the queue using raw payload data`getPendingJobs(int $limit = 10, ?string $onlyType = null)`Retrieve ready-to-run jobs, optionally filtered by type`markCompleted(int $jobId)`Mark job as completed`markFailed(int $jobId, string $error = '')`Mark job as failed with error message`processJobs(int $limit = 10, ?string $onlyType = null)`Process pending jobs📄 License
---------

[](#-license)

This project is open-sourced under the [MIT license](./LICENSE).

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance65

Regular maintenance activity

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

212d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2f29817cec408d033cd4441c8f760e3ae40248dc0f66856a09080d282aee6959?d=identicon)[Vitaliy Olos](/maintainers/Vitaliy%20Olos)

---

Top Contributors

[![SoloPHP](https://avatars.githubusercontent.com/u/175482616?v=4)](https://github.com/SoloPHP "SoloPHP (2 commits)")

---

Tags

phpasyncschedulerqueuejobs

###  Code Quality

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/solophp-job-queue/health.svg)

```
[![Health](https://phpackages.com/badges/solophp-job-queue/health.svg)](https://phpackages.com/packages/solophp-job-queue)
```

###  Alternatives

[dereuromark/cakephp-queue

The Queue plugin for CakePHP provides deferred task execution.

308850.3k14](/packages/dereuromark-cakephp-queue)[riki137/multitron

Tool for managing fast both asynchronous and multi-threaded execution of tasks. Focused on performance and pleasant CLI interface.

9016.8k](/packages/riki137-multitron)[enqueue/job-queue

Job Queue

34390.8k6](/packages/enqueue-job-queue)[orisai/scheduler

Cron job scheduler - with locks, parallelism and more

4037.1k4](/packages/orisai-scheduler)[badfarm/zanzara

Asynchronous PHP Telegram Bot Framework

2042.5k](/packages/badfarm-zanzara)[microsoft/azure-storage-queue

This project provides a set of PHP client libraries that make it easy to access Microsoft Azure Storage Queue APIs.

142.6M17](/packages/microsoft-azure-storage-queue)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
