toknot / php-epoll
PHP 对 Linux epoll C API 的绑定。
Requires
- php: >=7.4.0
- ext-ffi: *
- toknot/ffi-extend: >=0.1.5
This package is auto-updated.
Last update: 2024-09-13 01:53:11 UTC
README
PHP 对 Linux epoll API 的绑定。
要求
- PHP >= 7.4
- PHP FFI 扩展可用
- Linux > 2.6
- toknot/ffi-extend>=0.1
安装
使用 composer install
composer require toknot/php-epoll
包含 composer 自动加载文件: ./vendor/autoload.php
参考
-
Epoll::__construct() -
Epoll::create(int $flags)打开 epoll 文件描述符
-
Epoll::ctl(int $op, int $fd, EpollEvent $events): intepoll 文件描述符的控制接口
-
Epoll::wait(EpollEvent $event, int $maxevents, int $timeout, $sigmask = null): int在 epoll 文件描述符上等待 I/O 事件
-
Epoll::getFdno(resource $file, int $type): int从 PHP 资源文件描述符获取 ID
-
Epoll::lastErrno(): int获取最后错误代码
-
Epoll::lastError(): string获取最后错误消息
-
Epoll::ffi(): FFI -
Epoll::initEvents($num): EpollEvent -
EpollEvent::__construct(Epoll $epoll,$num) -
EpollEvent::setEvent($event, $idx)设置 Epoll 事件
-
EpollEvent::setData($data, $idx)设置用户数据变量
-
EpollEvent::getEvents($idx): FFI\CData
简单示例
PHP 资源到文件描述符
$epoll = new Epoll(); $fp = fopen(__FILE__, 'rb'); $fdno = $epoll->getFdno($fp, Epoll::RES_TYPE_FILE); $fdfp = fopen("php://fd/$fdno", 'rb'); echo fread($fdfp, 1024);
来自 man epoll 的 epoll 示例
const MAX_EVENTS = 10; const EXIT_FAILURE = 1; $epoll = new Epoll(); $ev = $epoll->initEvents(MAX_EVENTS); $events = $epoll->initEvents(); $stream = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr); $listen_sock = $epoll->getFdno($stream, Epoll::RES_TYPE_NET); function perror($str) { fprintf(STDERR, $str); } $epollfd = $epoll->create(0); $ev->setEvent(Epoll::EPOLLIN); $ev->setData(['fd' => $listen_sock]); if ($epoll->ctl(Epoll::EPOLL_CTL_ADD, $listen_sock, $ev) == -1) { perror("epoll_ctl: listen_sock"); exit(EXIT_FAILURE); } for (;;) { $nfds = $epoll->wait($events, MAX_EVENTS, -1); if ($nfds == -1) { perror("epoll_wait"); exit(EXIT_FAILURE); } for ($n = 0; $n < $nfds; ++$n) { if ($events[$n]->data->fd == $listen_sock) { $conn_sock = stream_socket_accept($stream); if (!$conn_sock) { perror("accept"); exit(EXIT_FAILURE); } stream_set_blocking($conn_sock, false); $ev->setEvent(Epoll::EPOLLIN | Epoll::EPOLLET); $connFdno = $epoll->getFdno($conn_sock, Epoll::RES_TYPE_NET); $ev->setData(['fd' => $connFdno]); if ($epoll->ctl(Epoll::EPOLL_CTL_ADD, $connFdno, $ev) == -1) { perror("epoll_ctl: conn_sock"); exit(EXIT_FAILURE); } } else { do_use_fd($events[$n]->data->fd); } } }