支持的函数
TrueAsync 将 70 多个标准 PHP 函数适配为协程内的非阻塞操作。 所有列出的函数在协程内调用时会自动变为异步。 在协程外部,它们照常工作。
DNS
| 函数 | 描述 |
|---|
gethostbyname() | 将主机名解析为 IP 地址 |
gethostbyaddr() | 将 IP 地址反向解析为主机名 |
gethostbynamel() | 获取主机名的 IP 地址列表 |
数据库
PDO MySQL
| 函数 | 描述 |
|---|
PDO::__construct() | 非阻塞连接 |
PDO::prepare() | 准备语句 |
PDO::exec() | 执行查询 |
PDOStatement::execute() | 执行预处理语句 |
PDOStatement::fetch() | 获取结果 |
PDO PgSQL
| 函数 | 描述 |
|---|
PDO::__construct() | 非阻塞连接 |
PDO::prepare() | 准备语句 |
PDO::exec() | 执行查询 |
PDOStatement::execute() | 执行预处理语句 |
PDOStatement::fetch() | 获取结果 |
PDO 连接池
通过 Async\Pool 集成实现透明的 PDO 连接池。 每个协程从池中获取自己的连接,自动管理生命周期。
MySQLi
| 函数 | 描述 |
|---|
mysqli_connect() | 非阻塞连接 |
mysqli_query() | 执行查询 |
mysqli_prepare() | 准备语句 |
mysqli_stmt_execute() | 执行预处理语句 |
mysqli_fetch_*() | 获取结果 |
PostgreSQL(原生)
| 函数 | 描述 |
|---|
pg_connect() | 非阻塞连接 |
pg_query() | 执行查询 |
pg_prepare() | 准备语句 |
pg_execute() | 执行预处理语句 |
pg_fetch_*() | 获取结果 |
每个异步上下文使用独立连接以确保安全并发。
CURL
| 函数 | 描述 |
|---|
curl_exec() | 执行请求 |
curl_multi_exec() | 执行多个请求 |
curl_multi_select() | 等待活动 |
curl_multi_getcontent() | 获取内容 |
curl_setopt() | 设置选项 |
curl_getinfo() | 获取请求信息 |
curl_error() | 获取错误 |
curl_close() | 关闭句柄 |
套接字
| 函数 | 描述 |
|---|
socket_create() | 创建套接字 |
socket_create_pair() | 创建套接字对 |
socket_connect() | 连接 |
socket_accept() | 接受连接 |
socket_read() | 读取数据 |
socket_write() | 写入数据 |
socket_send() | 发送数据 |
socket_recv() | 接收数据 |
socket_sendto() | 发送到地址 |
socket_recvfrom() | 从地址接收 |
socket_bind() | 绑定地址 |
socket_listen() | 监听 |
socket_select() | 监控套接字活动 |
文件和流 I/O
| 函数 | 描述 |
|---|
fopen() | 打开文件 |
fclose() | 关闭文件 |
fread() | 读取文件 |
fwrite() | 写入文件 |
fgets() | 读取行 |
fgetc() | 读取字符 |
fgetcsv() | 读取 CSV 行 |
fputcsv() | 写入 CSV 行 |
fseek() | 设置位置 |
ftell() | 获取位置 |
rewind() | 重置位置 |
ftruncate() | 截断文件 |
fflush() | 刷新缓冲区 |
fscanf() | 格式化读取 |
file_get_contents() | 读取整个文件 |
file_put_contents() | 写入整个文件 |
file() | 将文件读入数组 |
copy() | 复制文件 |
tmpfile() | 创建临时文件 |
readfile() | 输出文件 |
fpassthru() | 输出文件剩余部分 |
stream_get_contents() | 读取流剩余部分 |
stream_copy_to_stream() | 在流之间复制 |
flock() | 文件锁定(通过线程池) |
重要:flock() 使用线程池。flock() 函数是一个阻塞系统调用,无法通过 libuv I/O 事件实现非阻塞。 在协程内部,阻塞锁操作(LOCK_SH、LOCK_EX)被卸载到 libuv 线程池,允许其他协程在等待锁时继续执行。 非阻塞锁(LOCK_NB)和解锁(LOCK_UN)直接执行,不使用线程池。
重要:文件和管道流的超时。 PHP 原生不支持文件和管道流读写操作的超时——标准的 fread()、fwrite() 等函数可能会无限期阻塞。 TrueAsync 解决了这个问题:如果为流设置了超时(通过 stream_set_timeout()), 读取操作会同时注册一个 IO 事件和一个定时器。如果定时器在 IO 完成之前触发, 读取将被取消,协程收到返回值 -1(超时标志)。 此功能仅在协程内部有效——在协程外部,行为保持标准。
流套接字
| 函数 | 描述 |
|---|
stream_socket_client() | 创建客户端连接 |
stream_socket_server() | 创建服务器套接字 |
stream_socket_accept() | 接受连接 |
stream_select() | 监控流活动 |
stream_context_create() | 创建异步上下文 |
限制: stream_select() 在 Windows 上不支持管道流(例如来自 proc_open())。在 Linux/macOS 上通过事件循环原生工作。
进程执行
| 函数 | 描述 |
|---|
proc_open() | 打开带管道的进程 |
proc_close() | 关闭进程 |
exec() | 执行外部命令 |
shell_exec() | 执行 shell 命令 |
system() | 执行系统命令 |
passthru() | 执行并直接输出 |
重要:proc_close() 和 pclose() 会阻塞协程。 调用 proc_close() 或 pclose() 会等待子进程退出。 在协程内部,这会阻塞当前协程直到进程退出——其他协程继续运行。 通过析构函数的隐式调用也会发生同样的情况:如果持有进程资源的变量离开作用域 或被垃圾回收器销毁,析构函数会调用 pclose(),这会阻塞正在执行垃圾回收的协程。
建议:始终通过 proc_close() 显式关闭进程,而不是依赖析构函数, 以便控制哪个协程会被阻塞。
定时器和延迟
| 函数 | 描述 |
|---|
sleep() | 秒级延迟 |
usleep() | 微秒级延迟 |
time_nanosleep() | 纳秒精度延迟 |
time_sleep_until() | 等待到指定时间 |
输出缓冲
每个协程获得一个隔离的输出缓冲区。
| 函数 | 描述 |
|---|
ob_start() | 开始缓冲 |
ob_flush() | 刷新缓冲区 |
ob_clean() | 清理缓冲区 |
ob_get_contents() | 获取缓冲区内容 |
ob_end_clean() | 结束缓冲 |
尚未支持
计划实现或尚未适配的函数。
DNS
| 函数 | 描述 |
|---|
dns_check_record() / checkdnsrr() | 检查 DNS 记录 |
dns_get_mx() / getmxrr() | 获取 MX 记录 |
dns_get_record() | 获取 DNS 资源记录 |
数据库
| 扩展 | 描述 |
|---|
| PDO ODBC | ODBC 驱动 |
| PDO Oracle | Oracle 驱动 |
| PDO SQLite | SQLite 驱动 |
| PDO Firebird | Firebird 驱动 |
| MongoDB | MongoDB 客户端 |
文件操作(元数据)
| 函数 | 描述 |
|---|
opendir() / readdir() / closedir() | 目录遍历 |
unlink() / rename() | 文件删除和重命名 |
mkdir() / rmdir() | 目录创建和删除 |
stat() / lstat() | 文件信息 |
readlink() | 读取符号链接 |
注意: 本地磁盘上的文件元数据操作在微秒内完成。只有在网络文件系统(NFS)上才有异步化的意义。
接下来?