您的当前位置:首页>全部文章>文章详情

【PHP】PHP8.1新特性大讲解之Fibers with a grain of salt

CrazyPanda发表于:2024-01-04 23:30:09浏览:292次TAG:


Fibers with a grain of salt

所以我打算写一篇关于在PHP 8.1 中使用Fibers纤维的深入博客文章。我们将从一个基本示例开始,从头开始解释它们。这个想法是发送异步 HTTP 请求并使用纤程并行处理它们。

但是和他们一起玩,我了解到RFC并不是在开玩笑,当它说“不应直接在应用程序级代码中使用 Fiber API。Fibers 提供了一个基本的、低级的流控制 API 来创建更高然后在应用程序代码中使用的级抽象”。

因此,与其走这条路并使事情变得过于复杂,我们将讨论什么是纤程概念,为什么它们在应用程序代码中几乎不可用,以及您到底如何使用异步 PHP。

首先,一点点理论。

假设您要发送三个 HTTP 请求并处理它们的组合结果。这样做的同步方式是发送第一个,等待响应,然后发送第二个,等待,等等。

让我们用尽可能简单的图表来表示这样的程序流程。你需要从上到下阅读这张图表,时间越往下越走。每种颜色代表一个 HTTP 请求。每个请求的彩色部分代表实际运行的 PHP 代码,您服务器上的 CPU 正在执行工作,透明块代表等待时间:请求需要通过网络发送,其他服务器需要处理并发送回. 只有当响应到达时,我们才能再次工作。

1.png


这是一个同步执行流程:发送、等待、处理、重复。

在并行处理的世界中,我们发送请求但不等待。然后我们发送下一个请求,然后是另一个。只有然后我们等待所有请求。在等待的同时,我们会定期检查我们的一个请求是否已经完成。如果是这种情况,我们可以立即处理。

1.png

您可以看到这种方法如何减少执行时间,因为我们更优化地使用了等待时间。

Fibers 是 PHP 8.1 中的一种新机制,可让您更有效地管理这些并行执行路径。使用生成器和 已经可以实现yield,但是纤维是一个显着的改进,因为它们是专门为此用例设计的。

您将为每个请求创建一个纤程,并在请求发送后暂停纤程。创建所有三个光纤后,您将遍历它们,并一一恢复它们。通过这样做,纤程检查请求是否已经完成,如果没有则再次暂停,否则它可以处理响应并最终完成。

你看,纤程是一种启动、暂停和恢复程序隔离部分执行流程的机制。Fiber 也被称为“绿色线程”:实际上存在于同一进程中的线程。这些线程不是由操作系统管理的,而是由运行时管理的——在我们的例子中是 PHP 运行时。它们是管理某些形式的并行编程的一种经济高效的方式。

但请注意,它们并没有添加任何真正的异步内容:所有纤程都位于同一个 PHP 进程中,并且一次只能运行一个纤程。这是循环它们并在等待时检查它们的主进程,该循环通常称为“事件循环”。

并行性的难点不在于你如何在纤程或生成器上循环,或者你想使用的任何机制;它是关于能够开始一个操作,将它交给一个外部服务,并且只在你想要的时候以非阻塞的方式检查结果。

看,在前面的例子中,我们假设我们可以只发送一个请求,然后在我们想要的时候检查它的响应,但这实际上并不像听起来那么容易。

没错:大多数处理 I/O 的 PHP 函数都没有内置这种非阻塞功能。事实上,只有少数函数可以做到,而且使用它们非常麻烦。

有一个套接字的例子,它可以被设置为非阻塞,像这样:

[$read, $write] = stream_socket_pair(
    STREAM_PF_UNIX,
    STREAM_SOCK_STREAM,
    STREAM_IPPROTO_IP
);
  
stream_set_blocking($read, false);
stream_set_blocking($write, false);

通过使用stream_socket_pair(),创建了两个可用于双向通信的套接字。正如您所看到的,它们可以使用stream_set_blocking().

假设我们想要实现我们的示例,发送三个请求。我们可以使用套接字来做到这一点,但我们需要在它之上自己实现 HTTP 协议。这正是nox7所做的,该用户在Reddit上分享了一个小型概念证明,以展示如何使用光纤和套接字发送 HTTP GET 请求。你真的想在你的应用程序代码中这样做吗?

至少对我来说,答案是“不”。这正是 RFC 警告的内容;我不生气。相反,我们鼓励使用现有的异步框架之一:Amp或ReactPHP。

例如,使用 ReactPHP,我们可以这样写:

$loop = React\EventLoop\Factory::create();
$browser = new Clue\React\Buzz\Browser($loop);
$promises = [
    $browser->get('https://example.com/1'),
    $browser->get('https://example.com/2'),
    $browser->get('https://example.com/3'),
];
$responses = Block\awaitAll($promises, $loop);

与手动创建套接字连接相比,这是一个更好的示例。这就是 RFC 的意思:应用程序开发人员不需要担心纤程,它是 Amp 或 ReactPHP 等框架的实现细节。

不过,这给我们带来了一个问题:与我们已经可以用发电机做的事情相比,纤维有什么好处?RFC 是这样解释的:

与无堆栈生成器不同,每个 Fiber 都有自己的调用堆栈,允许它们在深度嵌套的函数调用中暂停。声明中断点的函数(即调用 Fiber::suspend())不需要更改其返回类型,这与使用 yield 的函数必须返回 Generator 实例不同。

Fiber 可以在任何函数调用中挂起,包括那些从 PHP VM 内部调用的函数,例如提供给 array_map 的函数或迭代器对象上的 foreach 调用的方法。

很明显,纤程在语法和灵活性方面都有显着的改进。但与 Go 及其“ goroutines ”相比,它们还不算什么。

要使异步 PHP 在没有框架开销的情况下成为主流,仍然缺少许多功能,而 Fiber 是朝着正确方向迈出的良好一步,但我们还没有做到这一点。

所以就是这样。如果您不是 Amp、ReactPHP 或较小的异步 PHP 框架的维护者,那么实际上没有什么可说的。也许更多的框架或库将开始合并它们?

同时,还有Swoole——一个 PHP 扩展,它实际上将几个核心功能修改为非阻塞。Swoole 本身是一个中文项目,在涉及英语时通常没有很好的文档记录,但最近 Laravel宣布与它进行第一方集成。也许这是将 PHP 推向更异步模型的更好策略:可选择将 Swoole 或其他扩展与 Laravel 和 Symfony 等框架集成?


猜你喜欢

【PHP】微信支付V3生成平台证书
使用composer下载官网SDK:https://pay.weixin.qq.com/docs/merchant/sdk-tools/sdk-tool.htmlcomposer require wechatpay/wechatpay使用方式参考:https://pay.weixin.qq.com/docs/merchant/sdk-tools/quickstart-php.html然后根据命令生成平台证书,命令共需要5个内容:商户mchid,商户私钥V3 key,商户支付证
发表于:2023-12-02 浏览:619 TAG:
【PHP】PHP 字符串编码处理 (附各语言的字符集编码范围)
PHP中GBK和UTF8编码处理  一、编码范围1. GBK (GB2312/GB18030) x00-xff GBK双字节编码范围 x20-x7f ASCII xa1-xff 中文 x80-xff 中文 2. UTF-8 (Unicode)u4e00-u9fa5 (中文) x3130-x318F (韩文) xAC00-xD7A3 (韩文) u0800-u4e00 (日文) ps: 韩文是大于[u9fa5]的字符 正则例子:preg_replace("/([x80-
发表于:2023-12-13 浏览:360 TAG:
【PHP】Composer创建包,设置命名空间
在Composer创建的库中,给文件命名空间应遵循PSR-4自动加载标准。以下是简要步骤和示例:在库的根目录下创建一个名为 src 的目录,用于存放源代码。在 src 目录下创建你的库的 PHP 文件,并在文件顶部声明命名空间。在库的 composer.json 文件中指定自动加载配置。使用Composer的 dump-autoload 命令更新自动加载器。示例:假设你的库名为 example-library,你想要创建一个名为 ExampleClass 的类。步骤 1: 在 src 目录下创建
发表于:2024-08-28 浏览:366 TAG: #php #composer
【PHP】thinkphp利用缓存提高数据库查询性能
ThinkPHP是一款十分受欢迎的PHP框架,它提供了许多便捷的功能和优化的设计,使得开发者可以更高效地进行Web应用程序的开发。其中,利用缓存提高数据库查询性能是一个常见的优化手段。本文将分享一些关于如何在ThinkPHP中利用缓存提高数据库查询性能的经验。一、什么是缓存?缓存是指将经常查询的数据存储在快速访问的存储介质中,以提高数据的访问速度。在Web应用程序中,数据库是最常用的数据存储介质之一。而经常查询数据库会带来一定的性能压力。因此,利用缓存可以避免频繁地查询数据库,从而提高
发表于:2023-12-08 浏览:424 TAG:
【PHP】PHP判断PC、手机浏览器、微信浏览器、支付宝浏览器
PHP识别不同的请求,主要从请求头user_agent来区分比如PC端谷歌浏览器Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit.........Safari/537.36手机微信浏览器Mozilla/5.0 ............. MicroMessenger/8.0.42.2460(0x28002A51) WeChat/arm64 
发表于:2024-04-11 浏览:280 TAG:
【PHP】php curl怎么使用get和post方法
hp curl使用post的方法:首先启动一个curl会话;然后对认证证书来源进行检查;接着从证书中检查ssl加密算法是否存在;最后以post方式请求https协议接口即可。本文操作环境:Windows7系统、PHP7.1版,DELL G3电脑php curl怎么使用get和post方法?PHP:CURL分别以GET、POST方式请求HTTPS/http协议接口apicurl以GET方式请求https协议接口function curl_get_https($url){  &
发表于:2024-03-19 浏览:309 TAG:
【PHP】PHP获取器和修改器技巧
从入门到精通:掌握PHP中的获取器和修改器技巧在PHP编程中,获取器(Getter)和修改器(Setter)是非常重要的概念和技巧。它们被广泛应用于面向对象编程中,用于实现封装性和数据安全性。本文将介绍获取器和修改器的概念、作用以及具体的代码示例,帮助读者掌握PHP中获取器和修改器的技能,从入门到精通。一、获取器(Getter)和修改器(Setter)的基本概念和作用获取器和修改器是一对用于访问和修改对象属性的方法,主要用于保护属性的访问权限和数据的完整性。获取器用于获取对象的属性值,
发表于:2023-12-27 浏览:419 TAG:
【PHP】ES在MySQL、PHP中的使用
                                                       ES简介一个高扩展、开源的全文检索和分析引擎,它可以准实时地快速存储、搜索、分析海量的数据。全文检索是指
发表于:2024-06-15 浏览:208 TAG:
【PHP】PHP实现验证码的生成与验证
PHP是一种常用的服务器端脚本语言,不仅功能强大,而且易于学习和编写。在网站开发中,验证码的生成与验证是非常重要的安全措施。在这篇文章中,我们将介绍如何使用PHP实现验证码的生成与验证。一、什么是验证码?验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写。它是一种常见的在线验证机制,用于确保用户是真正的人而不是机器人。
发表于:2023-12-28 浏览:277 TAG:
【PHP】php正则表达式有哪些
php正则表达式有"/pattern/"、"^"、"$"、"."、"[]"、"[^]"、"[a-z]"、"[A-Z]"、"[0-9]"、"\d"、"\D"、"\w"、"\W"、"\s"、"\S&quo
发表于:2023-12-04 浏览:634 TAG: #php #网络服务器软件