Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-26.2.0 | composer require openswoole/core:26.2.0
Since: OpenSwoole v26.2.0, PHP 8.3+
OpenSwoole 26.2.0 introduces a new coroutine context backend using PHP's native zend_fiber API. This replaces the traditional Boost ASM or ucontext backends and enables proper integration with Xdebug, profilers, and fiber-aware PHP extensions.
When fiber context is enabled, each coroutine runs inside a native PHP Fiber, allowing tools like Xdebug to correctly track execution across coroutine switches.
You can enable fiber context in two ways:
Via Co::set() before starting the server or coroutine scheduler:
<?php
OpenSwoole\Coroutine::set([
'use_fiber_context' => true,
]);
Via PHP INI:
openswoole.use_fiber_context=On
<?php
use OpenSwoole\Coroutine;
Coroutine::set([
'use_fiber_context' => true,
]);
co::run(function () {
go(function () {
echo "Coroutine 1 started\n";
Co::sleep(0.5);
echo "Coroutine 1 finished\n";
});
go(function () {
echo "Coroutine 2 started\n";
Co::sleep(0.3);
echo "Coroutine 2 finished\n";
});
});
With fiber context enabled, Xdebug step debugging works correctly inside coroutines. Set breakpoints in your IDE and debug coroutine code just like regular PHP code.
<?php
use OpenSwoole\Coroutine;
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;
Coroutine::set([
'use_fiber_context' => true,
]);
$server = new Server("127.0.0.1", 9501);
$server->on("request", function (Request $request, Response $response) {
// You can set breakpoints here and step through with Xdebug
$data = fetchData();
$response->end(json_encode($data));
});
function fetchData(): array
{
// Xdebug will correctly track execution across this coroutine switch
Co::sleep(0.1);
return ['status' => 'ok', 'time' => time()];
}
$server->start();
<?php
use OpenSwoole\Coroutine;
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;
Coroutine::set([
'use_fiber_context' => true,
'hook_flags' => OpenSwoole\Runtime::HOOK_ALL,
]);
$server = new Server("127.0.0.1", 9501);
$server->on("request", function (Request $request, Response $response) {
// With fiber context, coroutine context is properly maintained
$context = Co::getContext();
$context['request_id'] = uniqid();
// PDO queries work correctly with fiber context
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', '');
$stmt = $pdo->query("SELECT * FROM users LIMIT 10");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
$response->header('Content-Type', 'application/json');
$response->end(json_encode([
'request_id' => $context['request_id'],
'users' => $users,
]));
});
$server->start();