Coroutine\System
!> 此模块文件相关不再推荐使用,相关API请使用一键协程化的方式,文件相关操作对应SWOOLE_HOOK_FILE。
系统相关API
的协程封装。此模块在v4.4.6
正式版本后可用。大部分API
基于AIO
线程池实现。
!> v4.4.6
以前的版本, 请使用Co
短名或Swoole\Coroutine
调用, 如: Co::sleep
或 Swoole\Coroutine::sleep
v4.4.6
及以后版本官方推荐使用Co\System::sleep
或Swoole\Coroutine\System::sleep
此修改旨在规范命名空间, 但同时也保证向下兼容 (也就是说v4.4.6
版本以前的写法也是可以的, 无需修改)
方法
statvfs()
获取文件系统信息。
!> Swoole版本 >= v4.2.5 可用
Swoole\Coroutine\System::statvfs(string $path): array|false;
参数
string $path
- 功能:文件系统挂载的目录【如
/
,可以使用df和mount -l
命令获取】 - 默认值:无
- 其它值:无
- 功能:文件系统挂载的目录【如
使用示例
go(function() { var_dump(Swoole\Coroutine\System::statvfs('/')); }); // array(11) { // ["bsize"]=> // int(4096) // ["frsize"]=> // int(4096) // ["blocks"]=> // int(61068098) // ["bfree"]=> // int(45753580) // ["bavail"]=> // int(42645728) // ["files"]=> // int(15523840) // ["ffree"]=> // int(14909927) // ["favail"]=> // int(14909927) // ["fsid"]=> // int(1002377915335522995) // ["flag"]=> // int(4096) // ["namemax"]=> // int(255) // }
fread()
协程方式读取文件。
Swoole\Coroutine\System::fread(resource $handle, int $length = 0): string|false;
!> v4.0.4
以下版本fread
方法不支持非文件类型的stream
,如STDIN
、Socket
,请勿使用fread
操作此类资源。v4.0.4
以上版本fread
方法支持了非文件类型的stream
资源,底层会自动根据stream
类型选择使用AIO
线程池或EventLoop实现。
参数
resource $handle
- 功能:文件句柄【必须是
fopen
打开的文件类型stream
资源】 - 默认值:无
- 其它值:无
- 功能:文件句柄【必须是
int $length
- 功能:读取的长度【默认为
0
,表示读取文件的全部内容】 - 默认值:
0
- 其它值:无
- 功能:读取的长度【默认为
返回值
- 读取成功返回字符串内容,读取失败返回
false
- 读取成功返回字符串内容,读取失败返回
使用示例
$fp = fopen(__DIR__ . "/defer_client.php", "r"); go(function () use ($fp) { $r = Swoole\Coroutine\System::fread($fp); var_dump($r); });
fwrite()
协程方式向文件写入数据。
Swoole\Coroutine\System::fwrite(resource $handle, string $data, int $length = 0): int|false;
!> v4.0.4
以下版本fwrite
方法不支持非文件类型的stream
,如STDIN
、Socket
,请勿使用fwrite
操作此类资源。v4.0.4
以上版本fwrite
方法支持了非文件类型的stream
资源,底层会自动根据stream
类型选择使用AIO
线程池或EventLoop实现。
参数
resource $handle
- 功能:文件句柄【必须是
fopen
打开的文件类型stream
资源】 - 默认值:无
- 其它值:无
- 功能:文件句柄【必须是
string $data
- 功能:要写入的数据内容【可以是文本或二进制数据】
- 默认值:无
- 其它值:无
int $length
- 功能:读取的长度【默认为
0
,表示写入$data
的全部内容,$length
必须小于$data
的长度】 - 默认值:
0
- 其它值:无
- 功能:读取的长度【默认为
返回值
- 写入成功返回数据长度,读取失败返回
false
- 写入成功返回数据长度,读取失败返回
使用示例
$fp = fopen(__DIR__ . "/test.data", "a+"); go(function () use ($fp) { $r = Swoole\Coroutine\System::fwrite($fp, "hello world\n", 5); var_dump($r); });
fgets()
协程方式按行读取文件内容。
底层使用了php_stream
缓存区,默认大小为8192
字节,可使用stream_set_chunk_size
设置缓存区尺寸。
Swoole\Coroutine\System::fgets(resource $handle): string|false;
!> fgets
函数仅可用于文件类型的stream
资源,Swoole版本 >= v4.4.4
可用
参数
resource $handle
- 功能:文件句柄【必须是
fopen
打开的文件类型stream
资源】 - 默认值:无
- 其它值:无
- 功能:文件句柄【必须是
返回值
- 读取到
EOL
(\r
或\n
)将返回一行数据,包括EOL
- 未读取到
EOL
,但内容长度超过php_stream
缓存区8192
字节,将返回8192
字节的数据,不包含EOL
- 达到文件末尾
EOF
时,返回空字符串,可用feof
判断文件是否已读完 - 读取失败返回
false
,使用swoole_last_error函数获取错误码
- 读取到
使用示例
$fp = fopen(__DIR__ . "/defer_client.php", "r"); go(function () use ($fp) { $r = Swoole\Coroutine\System::fgets($fp); var_dump($r); });
readFile()
协程方式读取文件。
Swoole\Coroutine\System::readFile(string $filename): string|false;
参数
string $filename
- 功能:文件名
- 默认值:无
- 其它值:无
返回值
- 读取成功返回字符串内容,读取失败返回
false
,可使用swoole_last_error获取错误信息 readFile
方法没有尺寸限制,读取的内容会存放在内存中,因此读取超大文件时可能会占用过多内存
- 读取成功返回字符串内容,读取失败返回
使用示例
$filename = __DIR__ . "/defer_client.php"; go(function () use ($filename) { $r = Swoole\Coroutine\System::readFile($filename); var_dump($r); });
writeFile()
协程方式写入文件。
Swoole\Coroutine\System::writeFile(string $filename, string $fileContent, int $flags): bool;
参数
string $filename
- 功能:文件名【必须有可写权限,文件不存在会自动创建。打开文件失败会立即返回
false
】 - 默认值:无
- 其它值:无
- 功能:文件名【必须有可写权限,文件不存在会自动创建。打开文件失败会立即返回
string $fileContent
- 功能:写入到文件的内容【最大可写入
4M
】 - 默认值:无
- 其它值:无
- 功能:写入到文件的内容【最大可写入
int $flags
- 功能:写入的选项【默认会清空当前文件内容,可以使用
FILE_APPEND
表示追加到文件末尾】 - 默认值:无
- 其它值:无
- 功能:写入的选项【默认会清空当前文件内容,可以使用
返回值
- 写入成功返回
true
- 写入失败返回
false
- 写入成功返回
使用示例
$filename = __DIR__ . "/defer_client.php"; go(function () use ($filename) { $w = Swoole\Coroutine\System::writeFile($filename, "hello swoole!"); var_dump($w); });
sleep()
进入等待状态。
相当于PHP
的sleep
函数,不同的是Coroutine::sleep
是协程调度器实现的,底层会yield
当前协程,让出时间片,并添加一个异步定时器,当超时时间到达时重新resume
当前协程,恢复运行。
使用sleep
接口可以方便地实现超时等待功能。
Swoole\Coroutine\System::sleep(float $seconds): void;
参数
float $seconds
- 功能:睡眠的时间【必须大于
0
,最大不得超过一天时间(86400
秒)】 - 值单位:秒,最小精度为毫秒(
0.001
秒) - 默认值:无
- 其它值:无
- 功能:睡眠的时间【必须大于
使用示例
$server = new Swoole\Http\Server("127.0.0.1", 9502); $server->on('Request', function($request, $response) { //等待200ms后向浏览器发送响应 Swoole\Coroutine\System::sleep(0.2); $response->end("<h1>Hello Swoole!</h1>"); }); $server->start();
exec()
执行一条shell指令。底层自动进行协程调度。
Swoole\Coroutine\System::exec(string $cmd): array;
参数
string $cmd
- 功能:要执行的
shell
指令 - 默认值:无
- 其它值:无
- 功能:要执行的
返回值
- 执行失败返回
false
,执行成功返回数组,包含了进程退出的状态码、信号、输出内容。
array( 'code' => 0, // 进程退出的状态码 'signal' => 0, // 信号 'output' => '', // 输出内容 );
- 执行失败返回
使用示例
go(function() { $ret = Swoole\Coroutine\System::exec("md5sum ".__FILE__); });
gethostbyname()
将域名解析为IP。基于同步的线程池模拟实现,底层自动进行协程调度。
Swoole\Coroutine\System::gethostbyname(string $domain, int $family = AF_INET, float $timeout = -1): string|false
参数
string $domain
- 功能:域名
- 默认值:无
- 其它值:无
int $family
- 功能:域族【
AF_INET
表示返回IPv4
地址,使用AF_INET6
时返回IPv6
地址】 - 默认值:
AF_INET
- 其它值:
AF_INET6
- 功能:域族【
float $timeout
- 功能:超时时间
- 值单位:秒,最小精度为毫秒(
0.001
秒) - 默认值:
-1
- 其它值:无
返回值
- 成功返回域名对应的
IP
地址,失败返回false
,可使用swoole_last_error获取错误信息
array( 'code' => 0, // 进程退出的状态码 'signal' => 0, // 信号 'output' => '', // 输出内容 );
- 成功返回域名对应的
扩展
超时控制
$timeout
参数可以控制协程等待的超时时间,在规定的时间内未返回结果,协程会立即返回false
并继续向下执行。底层实现中会将该异步任务标记为cancel
,gethostbyname
还是会在AIO
线程池中继续执行。可修改
/etc/resolv.conf
设置gethostbyname
和getaddrinfo
底层C
函数的超时时间。具体请参考 设置 DNS 解析超时和重试
使用示例
go(function () { $ip = Swoole\Coroutine\System::gethostbyname("www.baidu.com", AF_INET, 0.5); echo $ip; });
getaddrinfo()
进行DNS解析,查询域名对应的IP
地址。
与gethostbyname
不同,getaddrinfo
支持更多参数设置,而且会返回多个IP
结果。
Swoole\Coroutine\System::getaddrinfo(string $domain, int $family = AF_INET, int $socktype = SOCK_STREAM, int $protocol = STREAM_IPPROTO_TCP, string $service = null, float $timeout = -1): array|false
参数
string $domain
- 功能:域名
- 默认值:无
- 其它值:无
int $family
- 功能:域族【
AF_INET
表示返回IPv4
地址,使用AF_INET6
时返回IPv6
地址】 - 默认值:无
- 其它值:无
!> 其他参数设置请参考
man getaddrinfo
文档- 功能:域族【
int $socktype
- 功能:协议类型
- 默认值:
SOCK_STREAM
- 其它值:
SOCK_DGRAM
、SOCK_RAW
int $protocol
- 功能:协议
- 默认值:
STREAM_IPPROTO_TCP
- 其它值:
STREAM_IPPROTO_UDP
、STREAM_IPPROTO_STCP
、STREAM_IPPROTO_TIPC
、0
string $service
- 功能:
- 默认值:无
- 其它值:无
float $timeout
- 功能:超时时间
- 值单位:秒,最小精度为毫秒(
0.001
秒) - 默认值:
-1
- 其它值:无
返回值
- 成功返回多个
IP
地址组成的数组,失败返回false
- 成功返回多个
使用示例
go(function () { $ips = Swoole\Coroutine\System::getaddrinfo("www.baidu.com"); var_dump($ips); });
dnsLookup()
域名地址查询。
与Coroutine\System::gethostbyname
不同,Coroutine\System::dnsLookup
是直接基于UDP
客户端网络通信实现的,而不是使用libc
提供的gethostbyname
函数。
!> Swoole版本 >= v4.4.3
可用,底层会读取/etc/resolve.conf
获取DNS
服务器地址,目前仅支持AF_INET(IPv4)
域名解析。
Swoole\Coroutine\System::dnsLookup(string $domain, float $timeout = 5): string|false
参数
string $domain
- 功能:域名
- 默认值:无
- 其它值:无
float $timeout
- 功能:超时时间
- 值单位:秒,最小精度为毫秒(
0.001
秒) - 默认值:
5
- 其它值:无
返回值
- 解析成功返回对应的IP地址
- 失败返回
false
,可以使用swoole_last_error获取错误信息
常见错误
SWOOLE_ERROR_DNSLOOKUP_RESOLVE_FAILED
:此域名无法解析,查询失败SWOOLE_ERROR_DNSLOOKUP_RESOLVE_TIMEOUT
:解析超时,DNS服务器可能存在故障,无法在规定的时间内返回结果
使用示例
go(function () { $ip = Swoole\Coroutine\System::dnsLookup("www.baidu.com"); echo $ip; });