- Yii2 How-To Guides
-
Basics
- How to Create a Dependent Dropdown in Yii2?
- How to Generate a PDF in Yii2 Using Mpdf
-
Swoole+YII2
- How to Run Yii2 with Swoole HTTP Server for Realtime Asynchronous Task Processing
-
Advanced
- How to Use CTE in Yii2 GridView: ArrayDataProvider vs. SQL View Approaches
- How to Add a New Application in Yii2 Basic Template (Without Switching to the Advanced Template)
How to Run Yii2 with Swoole HTTP Server for Realtime Asynchronous Task Processing
Add to BookmarkIn this tutorial, you'll learn how to implement real-time asynchronous task processing in a Yii2 application using PHP Swoole as a microservice. This architecture lets you offload time-consuming tasks (like sending emails or generating reports) to a separate process, without waiting for them to complete in your web request.
This is not about running Yii2 on Swoole. Instead, we embed a Swoole HTTP server alongside our Yii2 project, acting as a background worker that receives and processes tasks sent from Yii2 controllers.
Benefits of This Architecture
- No more waiting for long tasks to complete during user requests.
- Real-time background processing without relying on
cron
. - Event-driven and fast thanks to Swoole.
- Clean and extendable codebase using handlers and task routing.
Project Structure
yii2-app/
├── swoole/
│ ├── runserver.php
│ ├── TaskHandlerInterface.php
│ ├── TaskRouter.php
│ ├── task-log.txt
│ └── handlers/
│ ├── SendEmailTask.php
│ └── GenerateReportTask.php
├── controllers/
│ └── SiteController.php
├── web/
│ └── index.php
...
Step 1: Setup the Swoole HTTP Server
File: swoole/runserver.php
<?php
declare(strict_types=1);
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/../config/console.php';
$application = new yii\console\Application($config);
$server = new \Swoole\Http\Server("127.0.0.1", 9501);
$server->on("start", function (\Swoole\Http\Server $server) {
echo "Swoole task server started at http://127.0.0.1:9501\n";
});
$server->on("request", function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
$data = json_decode($request->rawContent(), true);
if (!$data || !isset($data['task'])) {
$response->status(400);
$response->end(json_encode(['error' => 'No task']));
return;
}
// Immediately respond before processing
$response->end(json_encode(['status' => 'Task queued']));
// Run task in coroutine asynchronously
go(function () use ($data) {
$payload = $data['payload'] ?? [];
\app\swoole\TaskRouter::dispatch($data['task'], $payload);
});
});
$server->start();
Step 2: Task Routing and Interface
File: swoole/TaskHandlerInterface.php
<?php
namespace app\swoole;
interface TaskHandlerInterface
{
public function handle(array $payload): void;
}
File: swoole/TaskRouter.php
<?php
namespace app\swoole;
class TaskRouter
{
public static function dispatch(string $taskName, array $payload): bool
{
$class = '\\app\\swoole\\handlers\\' . ucfirst($taskName) . 'Task';
file_put_contents(__DIR__ . '/task-log.txt', "Trying to dispatch: $class\n", FILE_APPEND);
if (!class_exists($class)) {
file_put_contents(__DIR__ . '/task-log.txt', "Class not found: $class\n", FILE_APPEND);
return false;
}
$handler = new $class();
if (!$handler instanceof TaskHandlerInterface) {
file_put_contents(__DIR__ . '/task-log.txt', "Handler does not implement TaskHandlerInterface: $class\n", FILE_APPEND);
return false;
}
$handler->handle($payload);
return true;
}
}
Step 3: Define Task Handlers
File: swoole/handlers/SendEmailTask.php
<?php
namespace app\swoole\handlers;
use app\swoole\TaskHandlerInterface;
class SendEmailTask implements TaskHandlerInterface
{
public function handle(array $payload): void
{
// Simulate sending an email
$to = $payload['to'] ?? 'unknown';
$subject = $payload['subject'] ?? '(no subject)';
$users = json_encode([]);
$i = 1;
while ($i <= 100) {
\Swoole\Coroutine::sleep(1);
$i++;
file_put_contents(__DIR__ . '/../task-log.txt', "$i\n", FILE_APPEND);
}
file_put_contents(__DIR__ . '/../task-log.txt', "Email Send , [EMAIL] To: $to, Subject: $subject and total users id $users\n", FILE_APPEND);
}
}
File: swoole/handlers/GenerateReportTask.php
<?php
namespace app\swoole\handlers;
use app\swoole\TaskHandlerInterface;
class GenerateReportTask implements TaskHandlerInterface
{
public function handle(array $payload): void
{
// Generate Report
file_put_contents(__DIR__ . '/../task-log.txt', "Report Generated for : " . json_encode($payload) . "\n", FILE_APPEND);
}
}
Step 4: Send Tasks from Yii2
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
class SiteController extends Controller
{
public function actionCheck()
{
$client = new \yii\httpclient\Client([
'baseUrl' => 'http://127.0.0.1:9501',
]);
$response = $client->createRequest()
->setMethod('POST')
->setUrl('/')
->setFormat(\yii\httpclient\Client::FORMAT_JSON)
->setData([
'task' => 'SendEmail',
'payload' => [
'to' => 'user@example.com',
'subject' => 'Welcome from Yii2',
],
])
->send();
if ($response->isOk) {
echo 'Task sent successfully: ' . $response->content;
}
$response = $client->createRequest()
->setMethod('POST')
->setUrl('/')
->setFormat(\yii\httpclient\Client::FORMAT_JSON)
->setData([
'task' => 'GenerateReport',
'payload' => [
'report_date' => date('Y-m-d'),
'report_title' => 'UP State Report',
],
])
->send();
if ($response->isOk) {
echo 'Task sent successfully: ' . $response->content;
exit;
}
return 'Error: ' . $response->statusCode;
}
}
Step 5: Run the Swoole Server
Run the following in a separate terminal:
php swoole/runserver.php
You’re Done!
Now when you visit http://localhost:8080/site/check
, Yii2 sends two background tasks to the Swoole server. Swoole handles them immediately, logs the results, and your controller returns without delay.
You’ve just upgraded your Yii2 app to support real-time microservice task delegation with PHP Swoole — no cron jobs, no blocking.
- You can add more task types by creating new classes in
handlers/
. - Consider moving to Redis or queues later for larger scale.
- Use this architecture to process webhooks, notifications, or database syncs instantly.
Prepare for Interview
- JavaScript Interview Questions for 0–1 Year Experience
- JavaScript Interview Questions For Fresher
- SQL Interview Questions for 5+ Years Experience
- SQL Interview Questions for 2–5 Years Experience
- SQL Interview Questions for 1–2 Years Experience
- SQL Interview Questions for 0–1 Year Experience
- SQL Interview Questions for Freshers
- Design Patterns in Python
- Dynamic Programming and Recursion in Python
- Trees and Graphs in Python
- Linked Lists, Stacks, and Queues in Python
- Sorting and Searching in Python
- Debugging in Python
- Unit Testing in Python
- Asynchronous Programming in PYthon
Random Blogs
- AI & Space Exploration – AI’s Role in Deep Space Missions and Planetary Research
- What Is SEO and Why Is It Important?
- Internet of Things (IoT) & AI – Smart Devices and AI Working Together
- Python Challenging Programming Exercises Part 3
- The Ultimate Guide to Data Science: Everything You Need to Know
- Government Datasets from 50 Countries for Machine Learning Training
- Understanding OLTP vs OLAP Databases: How SQL Handles Query Optimization
- 15 Amazing Keyword Research Tools You Should Explore
- Python Challenging Programming Exercises Part 2
- Where to Find Free Datasets for Your Next Machine Learning & Data Science Project
- Create Virtual Host for Nginx on Ubuntu (For Yii2 Basic & Advanced Templates)
- 10 Awesome Data Science Blogs To Check Out
- Ideas for Content of Every niche on Reader’s Demand during COVID-19
- Google’s Core Update in May 2020: What You Need to Know
- Store Data Into CSV File Using Python Tkinter GUI Library
Datasets for Machine Learning
- Amazon Product Reviews Dataset
- Ozone Level Detection Dataset
- Bank Transaction Fraud Detection
- YouTube Trending Video Dataset (updated daily)
- Covid-19 Case Surveillance Public Use Dataset
- US Election 2020
- Forest Fires Dataset
- Mobile Robots Dataset
- Safety Helmet Detection
- All Space Missions from 1957
- OSIC Pulmonary Fibrosis Progression Dataset
- Wine Quality Dataset
- Google Audio Dataset
- Iris flower dataset
- Artificial Characters Dataset