即将在下月底发布的 PHP 7.4
将会引入一个有趣的新功能,那就是期待已久的
FFI(外部函数接口,Foreign Function
Interface)的支持
。此功能使得开发者可以在原生 PHP 代码中调用 C
定义的函数/变量/数据结构。

PHP的高性能异步网络通信框架Swoole已发布 1.8.0
版本,此版本是一个里程碑式新版本,新增了多项新特性、多项核心功能优化以及问题修复、移除了无效的特性。更新内容如下:

FFI 与预加载功能都将是 PHP 7.4 的重要新功能,FFI 还增强了 PHP FPM
systemd 服务、用于 OpenSSL 流的 TLS 1.3 以及许多其他更改。PHP 7.4 的 FFI
甚至可与其他语言的 FFI 实现相媲美。

客户端增加原生异步MySQL客户端增加原生异步Redis客户端,基于Redis官方提供的hiredis库增加原生异步Http客户端增加原生异步WebSocket客户端支持重构底层swClient,异步TCP客户端实现放到swoole内核中增加swoole_client-reuse属性,SWOOLE_KEEP长连接模式下标识是否为复用的连接服务器端重构websocket服务器代码,底层与length_check协议复用相同的处理函数,增强稳定性增加Task进程对tick/after定时器的支持,底层基于高精度的setitimer+信号实现保存构造函数中传入的host、port参数到swoole_server对象属性增加多端口多协议的支持增加swoole_server-defer函数用于延时执行一些函数增加swoole_server-close强制切断连接的选项,设置第二个参数会true会清空发送队列并立即切断连接

使用 PHP FFI 应该可以减少为 C 库/程序接口编写新 PHP
模块的需求,因为现在可以使用外部函数接口来完成了。如果你对 PHP 7.4 FFI
的示例代码感到好奇,负责 Fedora/RedHat 的 PHP 打包程序工程师 Remi Collet
撰写了一篇新的博客文章,其中概述了一些带有示例代码的用例。

多端口多协议示例:

澳门新葡萄京所有网站 ,下面摘录一个简单的例子:

$serv = new swoole_server("0.0.0.0", 9501);$port2 = $serv-listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP);$port2-set(array( 'open_length_check' = true, 'package_length_type' = 'N', 'package_length_offset' = 0, //第N个字节是包长度的值 'package_body_offset' = 4, //第几个字节开始计算长度 'package_max_length' = 2000000, //协议最大长度));$port2-on('receive', function (swoole_server $serv, $fd, $from_id, $data) { echo "ServerPort2n";});$serv-on('connect', function ($serv, $fd, $from_id){ echo "[#".posix_getpid()."]tClient@[$fd:$from_id]: Connect.n";});$serv-on('receive', function (swoole_server $serv, $fd, $from_id, $data) { echo "[#".$serv-worker_id."]tClient[$fd]: $datan"; if ($serv-send($fd, "hellon") == false) { echo "errorn"; }});$serv-on('close', function ($serv, $fd, $from_id) { echo "[#".posix_getpid()."]tClient@[$fd:$from_id]: Close.n";});$serv-start();

Redis 客户端

其他增加swoole_table对key值的存储,foreach遍历table时可以获取到key值更改swoole_table的key对比模式,从crc32比对改为直接进行字符串对比更新utlist.h库到1.9.9版本

目前存在使用 C 或 PHP 编写的 Redis
客户端的各种实现,此示例演示了使用
FFI 来访问 hiredis 库的函数。

swoole_table保存Key值会增加内存占用,如table的size为100万,KEY值存储会增加64M内存占用

  1. 定义库,从库的头文件 hiredis/hredis.h 和 hiredis/read.h 复制/粘贴:preload-redis.h
  2. 对需要预加载的
    RemiRedis 类进行定义:preload-redis.inc
  3. 使用此类的测试脚本:redis.php

问题修复修复启用消息队列后发生double-free问题重构定时器,修复aftertick定时器偶然出现的core dump的问题定时器使用最小堆数据结构,插入/删除时间复杂度为log(N)修复swoole_process::signal在PHP7下发生core dump的问题修复swoole_async_write在PHP7下发生core dump的问题移除特性移除未支持的特性相关历史遗留代码,如heartbeat_pingdispatch_key_type等移除swoole_server-addtimerswoole_server-deltimerswoole_server-gettimer移除swoole_timer_addswoole_timer_del移除swoole_serveronTimer事件移除task_worker_max配置及相关特性代码移除swoole_server-handler方法

输出摘要

$ php74 -d ffi.preload=preload-redis.h -d opcache.preload=preload-redis.inc redis.php
...
+ RemiRedis::__construct(localhost, 6379)
+ RemiRedis::initFFI()
+ RemiRedis::del(foo)
int(1)
+ RemiRedis::get(foo)
NULL
+ RemiRedis::set(foo, 2019/10/23 12:45:03)
string(2) "OK"
+ RemiRedis::get(foo)
string(19) "2019/10/23 12:45:03"
+ RemiRedis::__destruct

如果希望了解有关 PHP 7.4 FFI
的更多信息,可以查看 PHP.net 上的文档及其基本示例。在发布
PHP 7.4 GA 前估计会经历多个 RC 版本,GA 预计将在 11 月 28 日左右发布。

(文/开源中国)