Skip to content

Releases: swoole/swoole-src

v6.1.3

26 Nov 01:48
54792f6

Choose a tag to compare

Release Notes

🐛 Bug Fixes

HTTP/2 Server

  • Fixed Safari Compatibility Issue: Resolved a flow control compatibility issue when the HTTP/2 server sends large files to Safari browsers.
  • Fixed Data Race in Cached Date Response Header: Fixed a data race condition in the cached Date response header for the HTTP/2 server in multi-threaded mode.
  • Fixed package_max_length Configuration Not Taking Effect:
    • The server now returns a 413 Payload Too Large error if the Content-Length in the received HEADERS frame exceeds the configured value.
    • The server sends an HTTP/2 RST_STREAM frame to terminate the stream if the total length of consecutively received DATA frames exceeds the configured value.
  • Fixed Memory Out-of-Bounds in Multi-threaded Coroutine Mode: Resolved a memory out-of-bounds issue when enabling enable_reuse_port in the multi-threaded coroutine version of the HTTP/2 server.
  • Fixed TLS Variable Destruction Issue: Fixed a double free issue occurring during the destruction of TLS (Thread Local Storage) variables upon thread exit in the multi-threaded HTTP/2 server.

Redis Server

  • Fixed packet assembly anomalies in Redis\Server::format() when processing large strings.

WebSocket Server

  • Fixed Control Frame Data Contamination: Resolved an issue where automatically replied ping/pong/close control frames from the WebSocket server carried residual data from previous text or binary frames due to uncleared buffers.

Multi-threading Related

  • Fixed Data Race in swoole_get_task_tmpdir(): Resolved a data race condition when calling this function in a multi-threaded environment.
  • Fixed Memory Out-of-Bounds Access in Runtime Hooks: Fixed memory out-of-bounds access triggered when setting runtime hooks in a multi-threaded environment.
    • ⚠️ Important Change: Runtime hooks can now only be set in the main thread and must be configured before creating any child threads.

Platform Compatibility

  • Fixed FreeBSD Compilation Failure: Resolved compilation failures on FreeBSD systems.

✨ Enhancements

  • Added Android Platform Support: Improved compatibility with the Android platform; now supported in Termux environments.
  • Synchronized Updates from PHP 8.x curl Module: Adapted relevant updates from the curl extension in PHP versions 8.1, 8.2, and 8.3.

Note: This update includes several critical fixes for multi-threaded mode. Users utilizing multi-threaded mode are strongly advised to upgrade as soon as possible.

更新记录

🐛 Bug 修复

HTTP/2 服务器

  • 修复 Safari 浏览器兼容性问题:解决 HTTP/2 服务器在向 Safari 浏览器发送大文件时的流量控制兼容性问题
  • 修复 Date 响应头缓存的数据竞争:解决多线程模式下 HTTP/2 服务器的 Date 响应头缓存存在的数据竞争问题
  • 修复 package_max_length 配置未生效
    • 当接收的 Header 帧中 Content-Length 超过配置值时,服务器将返回 413 Payload Too Large 错误
    • 当连续接收的 Data 帧总长度超过配置值时,服务器将发送 HTTP/2 RST_STREAM 帧终止流
  • 修复多线程协程模式下的内存越界:解决多线程模式协程版 HTTP/2 服务器开启 enable_reuse_port 时发生的内存越界问题
  • 修复 TLS 变量销毁问题:解决多线程模式 HTTP/2 服务器在线程退出时 TLS (Thread Local Storage) 变量销毁时发生的 double free 问题

Redis 服务器

  • 修复 Redis\Server::format() 处理大字符串出现的组包异常问题

WebSocket 服务器

  • 修复控制帧数据污染问题:解决 WebSocket 服务端自动回复的 ping/pong/close 控制帧因未清空缓存,导致携带前一个文本帧或二进制帧残留数据的问题

多线程相关

  • 修复 swoole_get_task_tmpdir() 数据竞争:解决多线程环境下调用该函数时存在的数据竞争问题
  • 修复运行时钩子的内存越界访问:解决多线程环境下设置运行时钩子时触发的内存越界访问问题
    • ⚠️ 重要变更:运行时钩子现在仅允许在主线程中设置,且必须在创建任何子线程之前完成设置

平台兼容性

  • 修复 FreeBSD 编译失败:解决在 FreeBSD 系统下的编译失败问题

✨ 功能增强

  • 新增 Android 平台支持:提升在 Android 平台的兼容性,现已支持在 Termux 环境下运行
  • 同步 PHP 8.x curl 模块更新:适配 PHP 8.1、8.2 及 8.3 版本中 curl 扩展的相关更新

注意事项:本次更新包含多项多线程模式下的关键修复,建议使用多线程模式的用户尽快升级。

v6.1.2

11 Nov 14:58
fd143a8

Choose a tag to compare

  • No longer throw warnings when failing to set the socket receive/send buffer size
  • Fixed an issue in Swoole\Http\Server where the onClose callback might execute before onRequest when handling HTTP2 requests, leading to a use-after-free problem
  • Optimized the getSocket() method by duplicating the file descriptor when exporting the php sockets resource object, preventing php sockets from affecting the socket held by Swoole upon closure
  • Fixed a memory leak issue in Swoole\Async\Client
  • Fixed an issue where Swoole\Coroutine\Http\Client of IPv6 type could not use Socks5 proxy
  • Synchronized updates to adapt to relevant changes in the CURL extension in PHP 8.4
  • Added the async.file:// file protocol, which allows enabling coroutine scheduling for specific file operations even when global file coroutine support is disabled
use function Swoole\Coroutine\run;

// Disable global file coroutine support but enable coroutine operations for specific files via the `async.file://` protocol  
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL & ~SWOOLE_HOOK_FILE);

run(function() {
    $fp = fopen("async.file:///home/test", "r");
    fwrite($fp, "data");
    fclose($fp);

   $content = file_get_contents("async.file:///home/test.txt");
});

This feature is designed for scenarios where global file system coroutine HOOK is disabled, but asynchronous read/write scheduling is required for specific file operations.

简体中文

  • 设置 socket 接收/发送缓冲区尺寸失败时不再抛出警告
  • 修复 Swoole\Http\Server 处理 HTTP2 请求时,onClose 回调可能先于 onRequest 执行,导致释放后使用(use-after-free)的问题
  • 优化getSocket()方法,导出php sockets资源对象时复制文件描述符,避免php sockets 关闭时影响 Swoole 持有的socket
  • 修复 Swoole\Async\Client 内存泄漏问题
  • 修复 IPv6 类型 Swoole\Coroutine\Http\Client 无法使用 Socks5 代理的问题
  • 同步适配 PHP 8.4CURL 扩展的相关更新
  • 新增 async.file:// 文件协议,支持在未开启全局文件协程化时,对指定文件操作启用协程调度
use function Swoole\Coroutine\run;

// 禁用全局文件协程化,但可通过 `async.file://` 协议对特定文件启用协程操作
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL & ~SWOOLE_HOOK_FILE);

run(function() {
    $fp = fopen("async.file:///home/test", "r");
    fwrite($fp, "data");
    fclose($fp);

   $content = file_get_contents("async.file:///home/test.txt");
});

该特性用于在禁用全局文件系统协程 HOOK后,对部分文件操作进行异步读写调用的场景。

v6.1.1

30 Oct 14:35
9c0578b

Choose a tag to compare

  • Fixed a compilation failure caused by missing zlib dependency.
  • Optimized the resource management logic in the curl module to prevent use-after-free risks.
  • Resolved the absence of fdatasync on macOS systems.
  • Improved the log output format for coroutine deadlock detection.

简体中文

  • 修复因为缺少zlib依赖导致编译失败的问题。
  • 优化curl模块的资源管理逻辑,以规避释放后再次使用的风险。
  • 修复macos系统没有fdatasync的问题。
  • 优化协程死锁检测日志输出格式。

v6.1.0

24 Oct 12:42
0dd30a6

Choose a tag to compare

Major Changes in Swoole 6.1.0

1. Introduction of "Standard Library Extensions" - Revolutionary Syntax Enhancements
This is the most eye-catching feature at the language level in this update, allowing object-oriented operations on basic types.

  • Object-Oriented Basic Types: Methods can be called directly on variables of basic types like string, array, and stream (e.g., $text->length()->lower()), greatly improving code readability and development experience.
  • Typed Arrays: Introduced the typed_array syntax, allowing constraints on key and value types (e.g., <int, string>), with type checks performed on write operations, enhancing code robustness.

2. A Major Leap in Underlying Architecture and Stability
This version invests heavily in code quality and stability, laying a solid foundation for future development.

  • Significant Increase in Test Coverage to 86%: By systematically adding test cases, potential errors are greatly reduced, improving the overall reliability and maintainability of the project.
  • Large-Scale Code Refactoring and Static Analysis: Refactored multiple core modules like Reactor, SSL, and Socket, and used clang-tidy for code standardization, significantly improving code quality and performance.

3. Major Simplification and Unification of the Lock API
A groundbreaking refactoring of the core component for concurrent programming – the lock.

  • API Simplification: Removed methods like lockwait and trylock, retaining only three core methods – __construct, lock, and unlock – for Swoole\Coroutine\Lock, Swoole\Lock, and Swoole\Thread\Lock.
  • Unified Behavior: The new API design is closer to PHP's native flock function, reducing the learning curve, and uses standard constants like LOCK_EX | LOCK_NB to implement advanced features such as non-blocking.

4. Enhanced Coroutine Capabilities and Fine-Grained Control
More flexible coroutine operation capabilities.

  • Coroutine Cancellation Mechanism: Swoole\Coroutine::cancel() now includes a $throw_exception parameter, allowing a catchable Swoole\Coroutine\CanceledException to be thrown into the target coroutine upon cancellation, enabling safer and more controllable coroutine lifecycle management.
  • Coroutine State Isolation for Serialization Operations: Fixed the issue of global state isolation for serialize/unserialize in coroutine environments. Global variables related to serialization are now automatically saved and restored during coroutine switches, ensuring isolated serialization contexts for each coroutine.

5. Default HTTP Parser Upgrade, Websocket Feature Enhancements, and Platform Compatibility Improvements
Important improvements in performance and compatibility.

  • llHTTP Enabled by Default: Replaced the old http_parser with the more performant and modern llhttp, improving the efficiency and reliability of HTTP processing.
  • WebSocket Feature Enhancements: Both client and server now support receiving fragmented messages, actively disconnecting (disconnect), and sending Ping frames (ping), making the WebSocket protocol implementation more complete.
  • Deprecating Select, Embracing Poll: Completely deprecated the flawed select event mechanism. On platforms that do not support epoll/kqueue (like Cygwin), poll is now used by default, enabling support for a large number of concurrent connections on these platforms as well.

🎉 Standard Library Extensions

Swoole-Cli version 6.1 will add PHP standard library extension syntax, providing some additional new syntax while maintaining full compatibility with the official PHP syntax. These new extension syntaxes are all optional and do not affect existing PHP code. The standard library extension syntax will be implemented in the stdext module of ext-swoole.

  • swoole-cli users can use it directly without any additional parameters.
  • ext-swoole users need to add --enable-swoole-stdext during compilation to enable it.
  • stdext can be used in php-cli, php-fpm, cli-http-server, and swoole modes.

1. Object-Oriented Basic Types

Version 6.1 implements object-oriented encapsulation of array, string, and stream basic types, supporting method calls in an object-oriented style. Methods can be called directly on variables of these types.

The built-in methods for basic types actually still call the PHP standard library implementations. There is a one-to-one correspondence between the built-in methods and PHP's str_ or array_ series of functions. For example, $text->replace() corresponds to the str_replace function. The underlying layer only adjusts the function names, the parameter order for a few methods, and the parameter and return value types for a couple of methods. Please refer to the Swoole Documentation for details.

$text = 'Hello Swoole';
var_dump($text->length());
echo $text->lower()->replace("swoole", "php");
echo fopen("/tmp/test.log")->read(1024);

2. Typed-Array Strongly Typed Arrays

Allows restricting array types, such as Map or ArrayList, and restricting the types of key and value. Supports multi-level nested formats. A typed array is still essentially an array type; the underlying layer only performs parameter checks on write operations. A typed array can be passed as an array to other functions or class methods.

$array = typed_array('<int, string>');
$array[1000] = "hello"; // Correct
$array[2000] = 2025; // Error, throws an exception

New Features

  • llHTTP Default Parser: Starting from v6.1.0, Swoole uses the more performant llhttp instead of http_parser as the default HTTP message parser.
  • Coroutine-based File Download: Swoole\Coroutine\Http\Client now supports complete coroutine-based file download operations.
  • Asynchronous File Truncation: Added iouring ftruncate support, expanding asynchronous file operation capabilities.
  • Swoole\Coroutine::cancel() adds a $throw_exception parameter, supporting throwing an exception when canceling a coroutine.
  • Swoole\Coroutine\Http\Client and Swoole\Coroutine\Http\Server now support receiving WebSocket fragmented messages.
  • Added disconnect and ping methods for Swoole\Coroutine\Http\Client and Swoole\Coroutine\Http\Server.
  • Refactored Swoole\Coroutine\Lock, Swoole\Lock, and Swoole\Thread\Lock, retaining only the __construct, lock, and unlock methods, making usage closer to php flock.

🐛 Bug Fixes

  • Thread Mode Optimization:
    • Fixed the issue where hook_flags settings became ineffective in SWOOLE_THREAD mode.
    • Fixed the issue where the heartbeat thread held invalid pointers and accessed freed memory after worker threads restarted due to reaching the max_request limit.
    • Fixed the issue of not supporting restarting Task processes individually.
    • Fixed an issue where Swoole\Websocket\Server might still trigger the onMessage callback after a handshake failure or connection closure.
    • Fixed execution errors in Swoole\Coroutine\Http\Server caused by inconsistencies between function return value types and signatures.
    • Fixed the issue where Swoole\Coroutine\Http\Server did not support enabling HTTP/2.
    • Fixed the timeout precision conversion issue in Swoole\Lock::lockwait().
    • Fixed the issue causing ReactorEpoll::add(): failed to add event warnings when using the coroutine-based curl module, due to PHP 8 compatibility adjustments and incomplete cleanup of keepalive connections.
    • Fixed the issue where Swoole\Server::taskWaitMulti() could not be used in multi-threaded mode.
    • Fixed resource competition issues in Swoole\Server::taskCo() in multi-threaded mode.
  • Stability Improvements:
    • Fixed the issue where synchronous processes (including manager and task processes) could not normally use process::signal().
    • Corrected the resource cleanup mechanism when worker processes exit abnormally.
    • Resolved compilation failure issues on the Cygwin platform.
    • Fixed the issue where curl with keepalive enabled could not reuse sockets.
    • Improved the log component to resolve data consistency issues in multi-threaded mode.
    • Fixed the compilation failure of the io_uring futex feature on ubuntu24.04.
    • Fixed the compilation failure on older Linux systems due to struct order assignment.
    • Fixed the uninitialized id property issue for directly instantiated Swoole\Process objects.
    • Fixed the missing --enable-zstd option in composer.json when compiling swoole with PIE.
    • Fixed the issue where worker processes could not send signals to the manager process due to insufficient permissions after specifying a user group.
  • Compatibility Improvements:
    • Fixed compatibility issues with php_swoole_register_shutdown_function under PHP 8.5.
    • Corrected the handling of null parameters in Swoole\Table::get().
  • Protocol Handling:
    • Optimized the handling mechanism for duplicate fields in HTTP request and response headers to ensure correct merging.
    • Fixed the issue where processing a client Accept-Encoding: zlib request header would trigger an unknown compression method warning when the system lacked zlib.

❌️ Deprecations

  • No longer supports the select event mechanism. select only supports event monitoring for up to 1024 file descriptors and has serious flaws. On platforms that do not support epoll/kqueue, poll will be used as the event polling mechanism, allowing the Cygwin platform to also support a large number of concurrent connections.
  • In the Swoole\Server::stop() method, the second parameter $waitEvent has been deprecated; please use the reload_async parameter instead.

🛠️ Architectural Optimizations

Version 6.1...

Read more

v6.1.0-rc2

13 Oct 13:35
08a9f2f

Choose a tag to compare

v6.1.0-rc2 Pre-release
Pre-release

✨ New Features

  • Added the $throw_exception parameter to Swoole\Coroutine::cancel(), enabling exceptions to be thrown when canceling a coroutine.
  • Swoole\Coroutine\Http\Client and Swoole\Coroutine\Http\Server now support receiving WebSocket fragmented messages.
  • Added disconnect and ping methods to Swoole\Coroutine\Http\Client and Swoole\Coroutine\Http\Server.
  • Refactored Swoole\Coroutine\Lock, Swoole\Lock, and Swoole\Thread\Lock, retaining only the __construct, lock, and unlock methods, making usage more aligned with php flock.

🐛 Bug Fixes

  • Fixed an issue where Swoole\Websocket\Server might still trigger the onMessage callback after a handshake failure or connection closure.
  • Fixed execution errors in Swoole\Coroutine\Http\Server caused by mismatched return types and function signatures.
  • Fixed the issue where Swoole\Coroutine\Http\Server did not support enabling HTTP/2.
  • Fixed the timeout precision conversion issue in Swoole\Lock::lockwait().
  • Fixed the ReactorEpoll::add(): failed to add event warning when using the coroutine-based curl module, caused by PHP 8 compatibility adjustments and incomplete cleanup of keepalive connections.

🛠️ Internal Optimizations

  • Upgraded the Swoole library version.
  • Disabled the -Wdate-time warning to resolve compilation errors when using Zig/Clang.
  • Removed PHP 8.0 related compatibility code.
  • Added the SWOOLE_ODBC_LIBS variable in config.m4.
  • Ensured that timespec.tv_nsec values are less than 1,000,000,000 to comply with POSIX standards.

⚠️ Notes

  • This version is an RC (Release Candidate) and should only be used in testing environments. Do not deploy it in production.
  • Starting from Swoole 6.1, Swoole\Coroutine\Http\Client and Swoole\Coroutine\Http\Server will automatically handle WebSocket control frames unless open_websocket_ping_frame, open_websocket_pong_frame, or open_websocket_close_frame are explicitly set.
  • Swoole\Coroutine::cancel() cannot cancel file coroutine operations. Forcibly canceling may cause segmentation faults.
  • If --enable-iouring is enabled, a warning will be thrown if the kernel version or liburing version does not meet the requirements.
  • The Swoole\Websocket\Server::push method will not automatically close the connection after sending a close frame. To close the connection, use the Swoole\Websocket\Server::disconnect() method.
  • When processing control frames, the Swoole protocol actively sets the FIN flag to 1 and ensures compression is not enabled (i.e., the RSV1 bit is 0). User settings for this will be ignored.
  • When handling compression and sending of consecutive frames, Swoole delegates the responsibility of compression and data chunking to the application layer. Users must manually implement the relevant logic. Refer to the example below for details.

💡 API Changes

New Lock API

Function Prototypes

namespace Swoole\Coroutine {
    class Lock {
        public function __construct(bool $shared = false) {}
        public function lock(int $operation = LOCK_EX): bool {}
        public function unlock(): bool {}
    }
}

namespace Swoole {
    class Lock {
        public function __construct(int $type = SWOOLE_MUTEX) {}
        public function lock(int $operation = LOCK_EX, float $timeout = -1): bool {}
        public function unlock(): bool {}
    }
}

namespace Swoole\Thread {
    class Lock {
        public function __construct(int $type = SWOOLE_MUTEX) {}
        public function lock(int $operation = LOCK_EX, float $timeout = -1): bool {}
        public function unlock(): bool {}
    }
}

Usage Example

$lock = new Swoole\Lock;
$lock->lock(LOCK_EX | LOCK_NB, 0.5);
$lock->unlock();

Canceling Coroutines

Co\run(function () {
    $cid = Co\go(function () {
        try {
            while (true) {
                System::sleep(0.1);
                echo "co 2 running\n";
            }
            var_dump('end');
        } catch (Swoole\Coroutine\CanceledException $e) {
            var_dump('cancelled');
        }
    });

    System::sleep(0.3);
    Co::cancel($cid, true);

    System::sleep(0.2);
    echo "co 1 end\n";
});

WebSocket Compression and Sending Consecutive Frames

Asynchronous Server

use Swoole\WebSocket\Server;
use Swoole\WebSocket\Frame;

$server = Server('127.0.0.1', 9502);
$server->set(['websocket_compression' => true]);
$server->on('message', function (Server $server, Frame $frame) {
    $data1 = bin2hex(random_bytes(10 * 1024));
    $data2 = bin2hex(random_bytes(20 * 2048));
    $data3 = bin2hex(random_bytes(40 * 4096));
    $context = deflate_init(ZLIB_ENCODING_RAW); // Stream compression
    $server->push($frame->fd, deflate_add($context, $data1, ZLIB_NO_FLUSH), SWOOLE_WEBSOCKET_OPCODE_TEXT, SWOOLE_WEBSOCKET_FLAG_COMPRESS | SWOOLE_WEBSOCKET_FLAG_RSV1);
    $server->push($frame->fd, deflate_add($context, $data2, ZLIB_NO_FLUSH), SWOOLE_WEBSOCKET_OPCODE_CONTINUATION, 0);
    $server->push($frame->fd, deflate_add($context, $data3, ZLIB_FINISH), SWOOLE_WEBSOCKET_OPCODE_CONTINUATION, SWOOLE_WEBSOCKET_FLAG_FIN);
});
$server->start();

Coroutine Server

use function Swoole\Coroutine\run;
use Swoole\Coroutine\Http\Server;

run(function() {
    $server = new Server("127.0.0.1", 9502);
    $server->set(['websocket_compression' => true]);
    $server->handle('/', function ($request, $response) use ($data1, $data2, $data3) {
        $response->upgrade();
        $data1 = bin2hex(random_bytes(10 * 1024));
        $data2 = bin2hex(random_bytes(20 * 2048));
        $data3 = bin2hex(random_bytes(40 * 4096));
        $context = deflate_init(ZLIB_ENCODING_RAW);
        $response->push(deflate_add($context, $data1, ZLIB_NO_FLUSH), SWOOLE_WEBSOCKET_OPCODE_TEXT, SWOOLE_WEBSOCKET_FLAG_COMPRESS | SWOOLE_WEBSOCKET_FLAG_RSV1);
        $response->push(deflate_add($context, $data2, ZLIB_NO_FLUSH), SWOOLE_WEBSOCKET_OPCODE_CONTINUATION, 0);
        $response->push(deflate_add($context, $data3, ZLIB_FINISH), SWOOLE_WEBSOCKET_OPCODE_CONTINUATION, SWOOLE_WEBSOCKET_FLAG_FIN);
    });
});

Coroutine Client

use function Swoole\Coroutine\run;
use Swoole\Coroutine\Http\Client;

run(function() {
    $client = new Client('127.0.0.1', 9502);
    $client->set(['websocket_compression' => true]);
    $ret = $client->upgrade('/');
    $context = deflate_init(ZLIB_ENCODING_RAW);
    $client->push(deflate_add($context, $data1, ZLIB_NO_FLUSH), SWOOLE_WEBSOCKET_OPCODE_TEXT, SWOOLE_WEBSOCKET_FLAG_COMPRESS | SWOOLE_WEBSOCKET_FLAG_RSV1);
    $client->push(deflate_add($context, $data2, ZLIB_NO_FLUSH), SWOOLE_WEBSOCKET_OPCODE_CONTINUATION, 0);
    $client->push(deflate_add($context, $data3, ZLIB_FINISH), SWOOLE_WEBSOCKET_OPCODE_CONTINUATION, SWOOLE_WEBSOCKET_FLAG_FIN);
});

✨ 新功能

  • Swoole\Coroutine::cancel() 新增 $throw_exception 参数,支持在取消协程时抛出异常。
  • Swoole\Coroutine\Http\ClientSwoole\Coroutine\Http\Server 现已支持接收 WebSocket 分块消息。
  • Swoole\Coroutine\Http\ClientSwoole\Coroutine\Http\Server 新增 disconnectping 方法。
  • 重构Swoole\Coroutine\LockSwoole\Lock和,Swoole\Thread\Lock,只保留__constructlockunlock方法,使用上更加贴近php flock

🐛 问题修复

  • 修复 Swoole\Websocket\Server 在握手失败或连接关闭后,仍可能触发 onMessage 回调的问题。
  • 修复 Swoole\Coroutine\Http\Server 因函数返回值类型与签名不一致导致的执行错误。
  • 修复 Swoole\Coroutine\Http\Server 不支持启用 HTTP/2 的问题。
  • 修复 Swoole\Lock::lockwait() 超时时间精度转换问题。
  • 修复因PHP 8兼容性调整及keepalive连接清理不彻底,导致使用协程化 curl 模块时出现 ReactorEpoll::add(): failed to add event 警告的问题。

🛠️ 内部优化

  • 升级 Swoole library 版本。
  • 禁用 -Wdate-time 警告,解决使用 Zig/Clang 编译时的错误。
  • 移除 PHP 8.0 相关兼容代码。
  • config.m4 中新增 SWOOLE_ODBC_LIBS 变量。
  • 确保 timespec.tv_nsec 取值小于 1,000,000,000,以符合 POSIX 标准规范。

⚠️ 注意事项

  • 本版本为 RC(候选发布)版本,请仅在测试环境中使用,请勿在生产环境部署。
  • 自 Swoole 6.1 起,Swoole\Coroutine\Http\ClientSwoole\Coroutine\Http\Server 将自动处理 WebSocket 控制帧,除非显式设置 open_websocket_ping_frameopen_websocket_pong_frameopen_websocket_close_frame
  • Swoole\Coroutine::cancel() 无法取消文件协程化操作,强行取消可能导致段错误。
  • 若启用 --enable-iouring,在检测到内核版本或 liburing 版本不满足要求时,将抛出警告信息。
  • Swoole\Websocket\Server::push 方法在发送关闭帧后不会自动关闭连接,如需关闭连接,请使用 Swoole\Websocket\Server::disconnect() 方法。
  • Swoole协议在处理控制帧时,会主动设置 FIN 标志位为 1,并确保不启用压缩(即 RSV1 位为 0),用户对此的设置将被忽略。
  • 当处理连续帧的压缩和发送时,Swoole将压缩与数据分块的职责移交至应用层,用户需手动实现相关逻辑。具体请看最下面的例子。

💡 API 变更

新的锁 API

函数原型

namespace Swoole\Coroutine {
    class Lock {
        public function __construct(bool $shared = false) {}
        public function lock(int $operation = LOCK_EX): bool {}
        public function unlock(): bool {}
    }
}

namespace Swoole {
    class Lock {
        public function __construct(int $type = SWOOLE_MUTEX) {}
        public function lock(int $operation = LOCK_EX, float $timeout = -1): bool {}
        public function unlock(): bool {}
    }
}

namespace Swoole\Thread {
    class Lock {
        public function __construct(int $type = SWOOLE_MUTEX) {}
        public function lock(int $operation = LOCK_EX, float $timeout = -1): bool {}
        public function unlock(): bool {}
    }
}

使用示例

$lock = new Swoole\Lock;
$lock->lock(LOCK_EX | LOCK_NB, 0.5);
$lock->unlock();

取消协程

Co\run(function () {
    $cid = Co\go(function () {
        try {
            while (true) {
                System::sleep(0.1);
                echo "co 2 running\n";
            }
            var_dump('end');
        } catch (Swoole\Coroutine\CanceledException $e) {
            var_dump('cancelled');
        }
    });

    System::sleep(0.3);
    Co::cancel($cid, true);

    System::sleep(0.2);
    echo "co 1 end\n";
});

WebSocket 压缩和发送连续帧

异步服务端

``...

Read more

v6.1.0-rc1

30 Aug 03:24
a23fb06

Choose a tag to compare

v6.1.0-rc1 Pre-release
Pre-release

Standard Library Extension

In version 6.1, Swoole-Cli will introduce extended syntax for the PHP standard library, providing additional new syntax while maintaining full compatibility with the official PHP syntax. These new extended syntax features are entirely optional and do not affect existing PHP code. The standard library extension syntax will be implemented in the stdext module of ext-swoole.

  • swoole-cli users can use it directly without any additional parameters.
  • ext-swoole users need to add --enable-swoole-stdext during compilation to enable it.
  • stdext can be used in php-cli, php-fpm, cli-http-server, and swoole modes.

1. Object-Oriented Basic Types

Version 6.1 implements object-oriented encapsulation of basic types such as array, string, and stream, supporting method calls in an object-oriented style. Built-in methods can be directly called on variables of these types.

The built-in methods for basic types still utilize the PHP standard library. These methods correspond one-to-one with PHP's str_ or array_ series functions. For example, $text->replace() corresponds to the str_replace function. The underlying implementation only adjusts function names, slightly modifies the parameter order for a few methods, and adjusts parameter and return value types for several others. For details, please refer to the Swoole Documentation.

$text = 'Hello Swoole';
var_dump($text->length());
echo $text->lower()->replace("swoole", "php");
echo fopen("/tmp/test.log")->read(1024);

2. Typed-Array

Typed arrays can enforce type constraints, such as Map or ArrayList, and restrict the types of keys and values. Multi-level nested formats are supported. Typed arrays are still essentially array types, with parameter checks performed only during write operations. Typed arrays can be passed as array to other functions or class methods.

$array = typed_array('<int, string>');
$array[1000] = "hello"; // Correct
$array[2000] = 2025; // Error, throws an exception

New Features

  • Default llHTTP Parser: Starting from v6.1.0, Swoole uses the higher-performance llhttp as the default HTTP message parser, replacing http_parser.
  • Coroutine-Based File Download: Swoole\Coroutine\Http\Client now supports full coroutine-based file download operations.
  • Asynchronous File Truncation: Added support for iouring ftruncate, expanding asynchronous file operation capabilities.

🐛 Bug Fixes

  • Thread Mode Optimization:
    • Fixed the issue where hook_flags settings were ineffective in SWOOLE_THREAD mode.
    • Fixed the issue where heartbeat threads held invalid pointers and accessed freed memory after worker threads restarted due to reaching the max_request limit.
    • Fixed the issue where Task processes could not be restarted individually.
  • Stability Improvements:
    • Fixed the issue where synchronous processes (including manager and task processes) could not use process::signal() properly.
    • Corrected the resource cleanup mechanism when worker processes exit abnormally.
    • Resolved compilation failures on the Cygwin platform.
    • Fixed the issue where curl could not reuse sockets when keepalive was enabled.
    • Improved the logging component to address data consistency issues in multi-threaded mode.
    • Fixed compilation failures of the futex feature in io_uring on ubuntu24.04.
    • Fixed compilation failures caused by struct sequential assignment on older Linux systems.
    • Fixed the issue where the id property of directly instantiated Swoole\Process objects was uninitialized.
    • Fixed the missing --enable-zstd option in composer.json when compiling Swoole with PIE.
  • Compatibility Improvements:
    • Fixed compatibility issues with php_swoole_register_shutdown_function on PHP 8.5.
    • Corrected the handling of null parameters in Swoole\Table::get().
  • Protocol Handling:
    • Optimized the handling of duplicate fields in HTTP request and response headers to ensure proper merging.
    • Fixed the issue where a warning about an unknown compression method was triggered when processing client Accept-Encoding: zlib headers without zlib installed.

Deprecations

  • Support for the select event mechanism has been removed. select only supports event monitoring for up to 1024 handles and has significant limitations. On platforms that do not support epoll/kqueue, poll will be used as the event polling mechanism, enabling support for high concurrency even on the Cygwin platform.
  • The second parameter $waitEvent in Swoole\Server::stop() has been deprecated. Please use the reload_async parameter instead.

🛠️ Architectural Optimizations

Version 6.1 adds extensive unit tests for core modules, increasing test coverage to 86%. By systematically supplementing test cases and refactoring underlying code logic, combined with full static code analysis using the clang-tidy toolchain, automated code formatting and redundancy cleanup have been achieved, significantly improving code readability and maintainability.

  • Optimized the underlying SSL module.
  • Optimized the underlying Socket module.
  • Refactored the underlying synchronous signal module.
  • Refactored the underlying reactor and string modules.
  • Refactored the underlying dynamic log file reloading mechanism based on SIGRTMIN signals.
  • Optimized the underlying static file server by removing C-style code and unifying it into C++-style code.
  • Optimized thread initialization logic to improve multi-threaded performance. Memory for independent management structures is now managed separately, eliminating the need for locks during thread creation and exit.
  • Removed the socket_dontwait option from the underlying async module, as it is deprecated.
  • Improved test coverage for WebSocket mask handling.
  • Optimized the sendfile functionality to avoid setting the tcp_cork option for files smaller than 64KB.
  • Added unit tests for aarch64 and macOS environments.
  • Optimized underlying client network address resolution and settings.
  • Added ssl_cafile/ssl_capath configuration items for the Server module.
  • Added the print_backtrace_on_error configuration, which prints C function stack traces when location errors occur.
  • Added the Address Sanitizer debugging tool.
  • Added Cygwin testing, significantly improving compatibility and stability on the Cygwin platform.
  • On macOS systems, the kqueue event mechanism does not support cross-process pipe event monitoring, making it impossible to use SWOOLE_PROCESS mode and Task processes. Therefore, the system defaults to using poll as the underlying event mechanism. To enable kqueue, manually activate it using Swoole\Server::set(['enable_kqueue' => true]) and swoole_async_set(['enable_kqueue' => true]).

⚠️ Note

  • This version is an RC (Release Candidate) and not an official release. It is recommended for use only in testing environments and should not be used in production.

🙏 Thank You

Sincere thanks to @matyhtf @jingjingxyk @sy-records @KIMDONGYEON00 @ServBayDev @NathanFreeman and all contributors for their professional efforts. Swoole is stronger because of you! Wishing all open-source community partners good health, success in all endeavors, and smooth work.

标准库扩展

6.1 版本 Swoole-Cli 将增加 PHP 标准库扩展语法,在保持对 PHP 官方语法完整兼容的同时,提供一些额外的新语法。这些新的扩展语法均是可选的,不影响现有的PHP代码。标准库扩展语法将在ext-swoolestdext模块中实现。

  • swoole-cli 用户,可直接使用,无需设置任何额外的参数
  • ext-swoole 的用户,需在编译时添加--enable-swoole-stdext来启用
  • stdextphp-cliphp-fpmcli-http-serverswoole 模式均可使用

1. 基础类型对象化

6.1 版本实现了array/string/stream基础类型的对象化封装,支持面向对象风格的方法调用,可直接对这些类型的变量调用内置方法。

基础类型的内置方法实际上仍然是调用PHP标准库实现的,内置方法与PHPstr_array_系列函数是一一对应关系,例如$text->replace()对应的函数是str_replace。底层仅调整了函数名称,少量方法调整了参数顺序,还有几个方法调整了参数和返回值类型,详情请查看 Swoole 文档

$text = 'Hello Swoole';
var_dump($text->length());
echo $text->lower()->replace("swoole", "php");
echo fopen("/tmp/test.log")->read(1024);

2. Typed-Array 强类型数组

可限制数组类型,如:MapArrayList,以及限制keyvalue的类型。支持多层嵌套格式。typed array实际上依然是array类型,底层仅在写入时进行参数检查。typed array可作为array传递给其他函数或类方法。

$array = typed_array('<int, string>');
$array[1000] = "hello"// 正确
$array[2000] = 2025// 错误,抛出异常

新特性

  • llHTTP 默认解析器:自 v6.1.0 起,Swoole 采用性能更优的 llhttp 替代 http_parser 作为默认 HTTP 报文解析器。
  • 协程化文件下载Swoole\Coroutine\Http\Client 现支持完整的协程化文件下载操作。
  • 异步文件截断:新增 iouring ftruncate 支持,扩展异步文件操作能力。

🐛 Bug 修复

  • 线程模式优化
    • 修复 SWOOLE_THREAD 模式下 hook_flags 设置失效问题。
    • 修复因工作线程达到max_request限制重启后,导致心跳线程持有失效指针并访问已释放内存的问题。
    • 修复不支持单独重启Task进程的问题。
  • 稳定性提升
    • 修复同步进程(含 manager 进程和 task 进程)无法正常使用process::signal()的问题。
    • 修正工作进程异常退出时的资源清理机制。
    • 解决 Cygwin 平台编译失败问题。
    • 修复curl开启keepalive无法复用socket的问题。
    • 改进日志组件以解决多线程模式下的数据一致性问题。
    • 修复io_uringfutex特性在ubuntu24.04编译失败的问题。
    • 修复结构体顺序赋值在低版本的linux系统会编译失败的问题。
    • 修复直接实例化的Swoole\Process对象其id属性未初始化的问题。
  • 修复使用PIE编译swoole时,composer.json文件缺少--enable-zstd的选项的问题。
  • 兼容性改进
    • 修复 PHP 8.5 下 php_swoole_register_shutdown_function 兼容性问题。
    • 修正 Swoole\Table::get() 对 null 参数的处理。
  • 协议处理
    • 优化HTTP请求头与响应头中重复字段的处理机制,确保其正确合并。
    • 修复当系统没有zlib时,处理客户端Accept-Encoding: zlib请求头会触发未知压缩方法警告的问题。

废弃

  • 不再支持select事件机制,select仅支持1024个句柄的事件监听,存在严重缺陷,在不支持epoll/kqueue的平台将使用poll作为事件轮训机制,这使得Cygwin平台下也可以支持大量并发。
  • Swoole\Server::stop()方法中,第二个参数$waitEvent已被废弃,请使用reload_async参数。

🛠️ 架构优化

6.1版本增加了大量核心模块的单元测试,测试覆盖率提升至**8...

Read more

v5.1.8

02 Aug 04:58
3074add

Choose a tag to compare

🐛 Bug Fixes

  • Fixed compatibility issues when thread context is enabled with older GCC versions compiling Swoole.
  • Fixed CPU affinity support detection failure in newer GCC versions due to missing _GNU_SOURCE macro definition.
  • Fixed the issue where synchronous processes (including manager and task processes) couldn't properly use process::signal().
  • Fixed missing serverLastStreamId property in HTTP2 coroutine client.
  • Fixed the "unknown compression method" warning when system lacks zlib support but client requests zlib in Accept-Encoding header.
  • Fixed missing id property in Swoole\Process class.

😊 Thank You

Heartfelt thanks to all contributors @NathanFreeman @xuanyanwow @deminy for your professional dedication. Swoole grows stronger because of you! Wishing our open-source community members good health, success in all endeavors, and smooth work.

🐛 Bug 修复

  • 修复 thread context 开启时与低版本 GCC 编译 Swoole 的兼容性问题。
  • 修复高版本 GCC 编译时因缺少 _GNU_SOURCE 宏定义导致的 CPU 亲和支持检测失效问题。
  • 修复同步进程(含 manager 进程和 task 进程)无法正常使用 process::signal() 的问题。
  • 修复 HTTP2 协程客户端缺少 serverLastStreamId 属性的问题。
  • 修复系统无 zlib 支持时,客户端请求 Accept-Encoding 含 zlib 会触发未知压缩方法警告的问题。
  • 修复 Swoole\Process 类缺少 id 属性的问题。

😊 致谢

诚挚感谢 @NathanFreeman @xuanyanwow @deminy 所有贡献者的专业付出,Swoole 因你们而更强大!愿开源社区伙伴身体健康,万事如意,工作顺利。

v6.0.2

22 Mar 06:45
d5cd793

Choose a tag to compare

✨ New Features:

  • Added Swoole\Thread::yield(), Swoole\Thread::activeCount(), and Swoole\Thread::isAlive() methods. @matyhtf

🐛 Bug Fixes:

  • Fixed an issue where using single-thread mode and setting heartbeat in SWOOLE_THREAD mode would cause exceptions. @matyhtf
  • Fixed a segmentation fault issue after enabling swoole.enable_fiber_mock. @NathanFreeman
  • Fixed an integer overflow issue in the Redis server. @yannaingtun

📢 Note:

  • The Redis server currently only supports the RESP2 protocol. When formatting strings that do not comply with this protocol, an exception will be thrown instead of logging. @matyhtf

😊 Thank you:

  • Thank you for your contributions to Swoole v6.0.2. Wishing everyone good health, success, and smooth work.

✨ 新特性:

  • 增加Swoole\Thread::yield()Swoole\Thread::activeCount()Swoole\Thread::isAlive()方法。 @matyhtf

🐛 Bug修复:

  • 修复在SWOOLE_THREAD模式下,使用单线程模式和设置心跳会引发异常的问题。 @matyhtf
  • 修复开启swoole.enable_fiber_mock后的段错误问题。 @NathanFreeman
  • 修复Redis服务端的整型溢出问题。 @yannaingtun

📢 注意:

  • Redis服务端目前将仅支持RESP2协议,当格式化不符合该协议的字符串时,将抛出异常而不是记录日志。 @matyhtf

😊 致谢:

  • 感谢你们为Swoole v6.0.2做出的贡献,祝愿大家身体健康,万事如意,工作顺利。

v5.1.7

16 Feb 03:54
6bd13e4

Choose a tag to compare

🐛 Bug Fixes:

  • Fixed an issue where PostgreSQL would revert to synchronous mode under coroutine when receiving large amounts of data. @NathanFreeman
  • Fixed an issue where dynamically creating properties in Swoole\Http2\Request would throw an exception. @xuanyanwow @guandeng
  • Fixed a memory error caused by fatal errors occurring in one-click coroutine. @matyhtf

😊 Thank you:

  • Thank you for your contributions to Swoole v5.1.7. Wishing everyone good health, success in all endeavors, and smooth sailing in your work.

🐛 Bug修复:

  • 修复Postgresql在协程化下在接收大量数据会退化成同步模式下的问题。 @NathanFreeman
  • 修复Swoole\Http2\Request动态创建类的属性抛出异常的问题。 @xuanyanwow @guandeng
  • 修复一键协程化中发生的致命错误会导致内存错误的问题。 @matyhtf

😊 致谢:

  • 感谢你们为Swoole v5.1.7做出的贡献,祝愿大家身体健康,万事如意,工作顺利。

v6.0.1

14 Feb 12:19

Choose a tag to compare

🐛 Bug Fixes:

  • Fixed an issue in SWOOLE_THREAD mode where the process could not exit properly due to not removing the listening event. @NathanFreeman
  • Fixed an issue where large file uploads failed when the single_thread configuration was enabled. @matyhtf
  • Fixed an issue where compilation could not find the specific file path if the same variable was already defined in config.m4. @matyhtf
  • Fixed an issue in Swoole\Process\Pool where processes could not exit properly upon timeout. @matyhtf
  • Fixed an issue in SWOOLE_THREAD mode where calling putenv caused the program to crash. @matyhtf
  • Fixed an issue in SWOOLE_THREAD mode where event callback functions could not be set for independent ports. @matyhtf
  • Fixed an issue in SWOOLE_THREAD mode where runtime parameters could not be retrieved in events such as onWorkerStart. @matyhtf
  • Fixed an issue where Postgresql would degrade to synchronous mode when receiving large amounts of data under coroutine. @NathanFreeman
  • Optimized the parameter judgment logic of swoole_substr_json_decode/swoole_substr_unserialize functions. @Appla
  • Fixed an issue with CPU affinity settings in config.m4. @remicollet
  • Fixed an issue in SWOOLE_THREAD mode where the heartbeat detection did not function properly. @matyhtf

📢 Note:

  • In the Http service, if the process restarts, the underlying layer will send a 500 Internal Server to requests waiting in the queue, close the connection, and discard these requests after sending. @NathanFreeman
  • Since the runtime configuration relied upon by the stream factory and stream ops in the PHP underlying is not thread-safe, in multi-thread mode, only the main thread is allowed to modify these runtime configurations before creating child threads. @matyhtf
  • Upgrade nghttp2 to the latest version. @NathanFreeman

😊 Thank you:

  • Thank you for your contribution to Swoole v6.0.1. Wish you good health, all the best, and smooth work.

🐛 Bug修复:

  • 修复SWOOLE_THREAD模式下,因为没有移除监听事件导致进程无法正常退出的问题。 @NathanFreeman
  • 修复当开启single_thread配置时,无法上传大文件的问题。 @matyhtf
  • 修复如果已经定义了config.m4中相同的变量,会导致编译过程找不到具体的文件路径的问题。 @matyhtf
  • 修复Swoole\Process\Pool中进程超时无法正常退出的问题。 @matyhtf
  • 修复SWOOLE_THREAD模式下,调用putenv导致程序崩溃的问题。 @matyhtf
  • 修复SWOOLE_THREAD模式下,无法为独立的端口设置事件回调函数的问题。 @matyhtf
  • 修复SWOOLE_THREAD模式下,onWorkerStart等事件中无法获取到运行时的各项参数的问题。 @matyhtf
  • 修复Postgresql在协程化下在接收大量数据会退化成同步模式下的问题。 @NathanFreeman
  • 优化swoole_substr_json_decode/swoole_substr_unserialize函数的参数判断逻辑。 @Appla
  • 修复config.m4中的CPU亲和性设置的问题。 @remicollet
  • 修复SWOOLE_THREAD模式下,心跳检测不起作用的问题。 @matyhtf

📢 注意:

  • 在Http服务中,如果进程重启时,底层会发送500 Internal Server给队列中等待处理的请求,发送完毕就关闭连接并丢弃这些请求。 @NathanFreeman
  • 由于php底层的stream factorystream ops依赖的运行时配置不是线程安全的,因此多线程模式下只允许主线程在还没创建子线程之前修改这些运行时配置。 @matyhtf
  • 升级nghttp2到最新版本。 @NathanFreeman

😊 致谢:

  • 感谢你们为Swoole v6.0.1做出的贡献,祝愿大家身体健康,万事如意,工作顺利。