Boost PHP Performance with Swow: Install, Coroutines, and Server Examples
This guide introduces Swow—a lightweight C core and PHP‑based library for high‑performance network programming—covers its key features, step‑by‑step installation, coroutine concepts, channel communication, and provides practical HTTP and TCP server code samples for PHP developers.
What Is Swow?
Swow is a PHP extension that combines a minimal C core with mostly PHP code to enable high‑performance network programming. It offers seamless integration between PHP and the C kernel, giving developers powerful capabilities for building concurrent applications.
Key Features
Coroutine support
High performance
Fine‑grained control
Easy compatibility with existing PHP code
Installation
Require the package via Composer: composer require swow/swow Run the builder script: php vendor/bin/swow-builder Verify the installation: php --ri swow Successful output shows the extension is enabled and lists version, build date, and linked libraries.
Coroutine Basics
A coroutine (user‑space thread) is a lightweight, non‑preemptive concurrency primitive. Multiple coroutines run on a single OS thread, but only one coroutine executes at any moment. They can pause and resume by saving and restoring execution state.
Advantages of Coroutines
Lightweight: Lower creation/destruction cost and memory usage than OS threads. No explicit locks: Single‑threaded execution avoids deadlocks and race conditions. Efficient context switches: Faster than thread switches, improving performance under high concurrency. Flexible scheduling: Programmers control when coroutines run, tailoring behavior to specific workloads.
Using Swow Coroutines
Run a coroutine with Swow\Coroutine::run:
Swow\Coroutine::run(static function(): void {
echo 1;
sleep(1);
});Get the current coroutine object:
Swow\Coroutine::run(static function(): void {
var_dump(\Swow\Coroutine::getCurrent());
});Coroutine States
Swow defines three states: waiting: The coroutine is idle, either newly created or blocked on I/O. running: The coroutine is actively executing. dead: The coroutine has finished execution and its resources are released.
Example of inspecting a waiting coroutine:
$coroutine = Swow\Coroutine::run(static function(): void {
\Swow\Coroutine::yield();
});
var_dump($coroutine);Channel Communication
Channels provide a queue‑like mechanism for passing data between coroutines.
$channel = new \Swow\Channel();
Swow\Coroutine::run(static function() use ($channel): void {
$channel->push(1);
});
Swow\Coroutine::run(function() use ($channel): void {
var_dump($channel->pop());
});Channels can also be used to handle signals, such as terminating on SIGINT (Ctrl+C):
$channel = new \Swow\Channel();
\Swow\Coroutine::run(static function() use ($channel): void {
\Swow\Signal::wait(\Swow\Signal::INT);
$channel->push("Terminated by SIGINT
");
});
// Consumer coroutine
\Swow\Coroutine::run(static function() use ($channel): void {
while (true) {
sleep(1);
}
});
$timeout = 5;
try {
echo $channel->pop($timeout * 1000);
} catch (\Swow\ChannelException $e) {
echo sprintf("Timeout after %d seconds
", $timeout);
}Quick HTTP Server with Swow
$server = new \Swow\Psr7\Server\Server();
$server->bind('0.0.0.0', 9503)->listen();
while (true) {
$connection = $server->acceptConnection();
\Swow\Coroutine::run(static function() use ($connection): void {
try {
while (true) {
$request = $connection->recvHttpRequest();
if ($request->getUri()->getPath() === '/') {
$connection->respond('22222');
}
}
} catch (Throwable $e) {
// handle error
}
});
}Access http://127.0.0.1:9503 to see the response 22222.
Quick TCP Server with Swow
$server = new \Swow\Socket(\Swow\Socket::TYPE_TCP);
$server->bind('127.0.0.1', 9503)->listen();
while (true) {
$connection = $server->accept();
\Swow\Coroutine::run(static function() use ($connection): void {
$buffer = new Swow\Buffer(Swow\Buffer::COMMON_SIZE);
try {
while (true) {
$len = $connection->recv($buffer);
if ($len === 0) {
break;
}
echo "No.{$connection->getFd()} say: \"" . addcslashes($buffer->toString(), "
") . "\"
";
$connection->send($buffer);
}
} catch (Swow\SocketException $e) {
echo "No.{$connection->getFd()} goaway! {$e->getMessage()}
";
}
});
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
