When building PHP applications, some tasks take too long to execute or donβt need an immediate response. For example:
β
Sending emails (e.g., welcome emails, password reset)
β
Generating reports (e.g., large PDF or CSV exports)
β
Processing large file uploads
β
Handling API requests asynchronously
Instead of making users wait, we can offload these tasks to a background queue system. In this guide, youβll learn how to:
β
Understand queues and background jobs
β
Use PHPβs exec()
function to run background tasks
β
Set up RabbitMQ and Redis for queue management
β
Use Laravelβs queue system for job handling
β
Build a fully functional job queue system in PHP
By the end, youβll have a high-performance job queue system ready for production! π
1οΈβ£ What Are Background Jobs and Queues?
π‘ Background jobs allow you to execute tasks asynchronously instead of processing them immediately.
Example: Without a Queue (Slow)
<?php
// Send email directly (blocking request)
mail("user@example.com", "Welcome!", "Thanks for signing up.");
echo "User registered!";
?>
π₯ Problem?
β The user waits until the email is sent.
β Slow performance if many emails are sent.
Example: With a Queue (Fast)
<?php
// Push email task to a queue (non-blocking)
file_put_contents("queue.txt", "Send email to user@example.com\n", FILE_APPEND);
echo "User registered!";
?>
π₯ Why is this better?
β
The task runs in the background.
β
The response is instant.
2οΈβ£ Running Background Jobs in PHP with exec()
If you need a simple background job system, PHPβs exec()
function can help.
1οΈβ£ Run a Background Task
exec("php send_email.php > /dev/null 2>&1 &");
π₯ What happens?
β
Runs send_email.php
in the background.
β
> /dev/null 2>&1 &
prevents blocking execution.
2οΈβ£ Example: Asynchronous Email Sending (send_email.php
)
<?php
sleep(5); // Simulate delay
mail("user@example.com", "Welcome!", "Your account is created!");
file_put_contents("logs.txt", "Email sent at " . date("H:i:s") . "\n", FILE_APPEND);
?>
π₯ Now emails send in the background without blocking users!
3οΈβ£ Setting Up a Message Queue with Redis
π‘ Redis is a fast in-memory database that can be used as a queue system.
1οΈβ£ Install Redis
For Ubuntu:
sudo apt update
sudo apt install redis-server -y
Start Redis:
sudo systemctl start redis
2οΈβ£ Install PHP Redis Extension
sudo apt install php-redis -y
3οΈβ£ Push a Job to the Queue
<?php
$redis = new Redis();
$redis->connect("127.0.0.1", 6379);
$redis->lPush("email_queue", json_encode(["to" => "user@example.com", "subject" => "Welcome!", "body" => "Thanks for signing up."]));
echo "Email job added to queue!";
?>
π₯ Whatβs happening?
β
lPush("email_queue", $data)
adds a job to Redis.
4οΈβ£ Process Jobs from the Queue (worker.php
)
<?php
$redis = new Redis();
$redis->connect("127.0.0.1", 6379);
while (true) {
$job = $redis->rPop("email_queue");
if ($job) {
$data = json_decode($job, true);
mail($data["to"], $data["subject"], $data["body"]);
echo "Email sent to " . $data["to"] . "\n";
}
sleep(1);
}
?>
π₯ Now background jobs run automatically!
4οΈβ£ Using RabbitMQ for Advanced Queues
RabbitMQ is a message broker for scaling background jobs.
1οΈβ£ Install RabbitMQ
For Ubuntu:
sudo apt update
sudo apt install rabbitmq-server -y
Start RabbitMQ:
sudo systemctl start rabbitmq-server
2οΈβ£ Install PHP AMQP Library
composer require php-amqplib/php-amqplib
3οΈβ£ Publish a Message to RabbitMQ (producer.php
)
<?php
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
require "vendor/autoload.php";
$connection = new AMQPStreamConnection("localhost", 5672, "guest", "guest");
$channel = $connection->channel();
$channel->queue_declare("email_queue", false, true, false, false);
$data = json_encode(["to" => "user@example.com", "subject" => "Welcome!", "body" => "Thanks for signing up!"]);
$msg = new AMQPMessage($data);
$channel->basic_publish($msg, "", "email_queue");
echo "Message sent to queue!";
$channel->close();
$connection->close();
?>
π₯ Whatβs happening?
β
The email job is pushed to RabbitMQ.
4οΈβ£ Process Messages (consumer.php
)
<?php
use PhpAmqpLib\Connection\AMQPStreamConnection;
require "vendor/autoload.php";
$connection = new AMQPStreamConnection("localhost", 5672, "guest", "guest");
$channel = $connection->channel();
$channel->queue_declare("email_queue", false, true, false, false);
$callback = function ($msg) {
$data = json_decode($msg->body, true);
mail($data["to"], $data["subject"], $data["body"]);
echo "Email sent to " . $data["to"] . "\n";
};
$channel->basic_consume("email_queue", "", false, true, false, false, $callback);
while ($channel->is_consuming()) {
$channel->wait();
}
?>
π₯ Now emails are processed automatically in the background!
5οΈβ£ Using Laravel Queues (Best for Large Applications)
If youβre using Laravel, queues are built-in.
1οΈβ£ Install Laravel Queue Driver
composer require predis/predis
Set queue driver in .env
:
QUEUE_CONNECTION=redis
2οΈβ£ Create a Job
php artisan make:job SendEmailJob
Modify app/Jobs/SendEmailJob.php
:
public function handle() {
mail($this->details["to"], $this->details["subject"], $this->details["body"]);
}
3οΈβ£ Dispatch a Job
use App\Jobs\SendEmailJob;
SendEmailJob::dispatch(["to" => "user@example.com", "subject" => "Welcome!", "body" => "Thanks for signing up."]);
4οΈβ£ Run the Worker
php artisan queue:work
π₯ Now Laravel handles jobs in the background! π
π Final Thoughts
Now you can handle background jobs like a pro!
β
Use PHP exec()
for quick background tasks
β
Use Redis for simple queueing
β
Use RabbitMQ for scalable message queues
β
Use Laravel queues for enterprise applications
π Next: PHP Security
Happy coding! ππ