新闻详情

新闻详情

首页 / 资讯中心 / 详情

PHP使用Guzzle发起的异步请求示例详解

发布时间:2026/11/15 16:40:26来源:尧图网络
PHP使用Guzzle发起的异步请求示例详解
Guzzle中的异步请求使用Guzzle发起异步请求Guzzle是一个PHP的HTTP客户端它在发起http请求时不仅可以同步发起还可以异步发起。12345678$clientnewClient();$requestnewRequest(GET,http://www.baidu.com);$promise$client-sendAsync($request)-then(function($response) {echo$response-getBody();});// todo somethingecho1;$promise-wait();PHP发起HTTP请求的几种方式curl使用libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。stream通过流的方式获取和发送远程文件该功能需要ini配置allow_url_fopenon。关于php的流更多参考PHP流Stream的概述与使用详解在guzzle中可以兼容使用这两种的任意一种或者是用户自定义的http handler1234567891011121314151617181920functionchoose_handler(){$handler null;if(function_exists(curl_multi_exec) function_exists(curl_exec)) {$handler Proxy::wrapSync(newCurlMultiHandler(),newCurlHandler());}elseif(function_exists(curl_exec)) {$handlernewCurlHandler();}elseif(function_exists(curl_multi_exec)) {$handlernewCurlMultiHandler();}if(ini_get(allow_url_fopen)) {$handler$handler? Proxy::wrapStreaming($handler,newStreamHandler()):newStreamHandler();}elseif(!$handler) {thrownew\RuntimeException(GuzzleHttp requires cURL, the .allow_url_fopen ini setting, or a custom HTTP handler.);}return$handler;}可以看出guzzle会优先使用curl然后选择使用streamProxy::wrapStreaming($handler, new StreamHandler())是一个流包装器。12345678910publicstaticfunction wrapStreaming(callable $default,callable $streaming) {returnfunction (RequestInterface $request, array $options) use ($default, $streaming) {returnempty($options[stream])? $default($request, $options): $streaming($request, $options);};}什么是URIURI的组成URIUniform Resource Identifier统一资源标识符。scheme:[//[user:password]host[:port]][/]path[?query][#fragment]请求的组装Guzzle发起请求大致分为两个阶段第一阶段负责将需要请求的uri组装成各种内部定义的类。Client类这是一个发起客户端的调用者后续所有的调用需要基于这个负责的类实现它负责提供一个 handler ,这是一个客户端发起http请求的句柄其中Guzzle实现curl和stream调用的无感知就是在这里实现的同时开发者也可以自定义请求协议。123456789101112131415161718192021// 根据系统当前状态选择一个发起Http请求的协议的方法句柄functionchoose_handler(){$handler null;if(function_exists(curl_multi_exec) function_exists(curl_exec)) {$handler Proxy::wrapSync(newCurlMultiHandler(),newCurlHandler());}elseif(function_exists(curl_exec)) {$handlernewCurlHandler();}elseif(function_exists(curl_multi_exec)) {$handlernewCurlMultiHandler();}if(ini_get(allow_url_fopen)) {$handler$handler? Proxy::wrapStreaming($handler,newStreamHandler()):newStreamHandler();}elseif(!$handler) {thrownew\RuntimeException(GuzzleHttp requires cURL, the .allow_url_fopen ini setting, or a custom HTTP handler.);}return$handler;}Request类负责定义一个uriPromise类这个类负责承载类请求发起前的各种准备工作完成后的结果还包括两个回调请求成功回调、请求失败回调,同时请求发起中的队列延迟等处理也是在这个类里。其中组装阶段最重要的方法是私有方法private function transfer(RequestInterface $request, array $options)它负责将用户通过各种方法传入的uri和client类的各种属性组合然后使用这些属性生成一个新的类 Promise 类。请求的发起Client的各种属性组装完成后就可以使用得到的Promise类发起http请求了这里主要是通过一个 wait() 方法。同步调用与异步调用在同步方法内部的调用同步方法是在内部组装好一个Promise之后立刻发起wait()调用。12345publicfunction send(RequestInterface $request, array $options []){$options[RequestOptions::SYNCHRONOUS] true;return$this-gt;sendAsync($request, $options)-gt;wait();}wait的实现wait() 方法的实现逻辑也很简单递归调用wait()方法直到result属性不是PromiseInterface实现类或者state不是pending然后将结果逐层输出。这里说一下这个state的pending状态这是一个PromiseInterface实现类的初始化状态表示改实现类还没有完成需要继续wait。1234567891011121314151617publicfunction wait($unwrap true){$this-gt;waitIfPending();$inner $this-gt;result instanceof PromiseInterface? $this-gt;result-gt;wait($unwrap): $this-gt;result;if($unwrap) {if($this-gt;result instanceof PromiseInterface|| $this-gt;state self::FULFILLED) {return$inner;}else{// Its rejected so unwrap and throw an exception.throwexception_for($inner);}}}waitIfPending() 如果promise类还处于pending状态就执行。主要是执行改实现类的waitFn方法。最外层promise执行完成后执行queue()-run() 这个方法内部循环执行队列内方法直到队列为空。至此Guzzle就能将组装进来的多个request和各种方法执行完毕。123456789101112131415161718192021222324252627privatefunctionwaitIfPending(){if($this-state ! self::PENDING) {return;}elseif($this-waitFn) {$this-invokeWaitFn();}elseif($this-waitList) {$this-invokeWaitList();}else{// If theres not wait function, then reject the promise.$this-reject(Cannot wait on a promise that has .no internal wait function. You must provide a wait .function when constructing the promise to be able to .wait on a promise.);}queue()-run();if($this-state self::PENDING) {$this-reject(Invoking the wait callback did not resolve the promise);}}publicfunctionrun(){/** var callable $task */while($taskarray_shift($this-queue)) {$task();}}waitFn是什么回到前面提到的transfer()函数。123$handler$options[handler];// 返回一个promise类这个类有一个属性是waitFnreturnPromise\promise_for($handler($request,$options));这里我们看 $handler 是什么它是一个HandleStack类就是我们在new Client时选择的发起Http请求的协议的方法句柄实例化的类。br /之后的调用依次是 HandleStack-__invoke、RedirectMiddleware-__invoke、PrepareBodyMiddleware-__invoke。执行$fn($request, $options);方法经过前面的逐层处理此时的$fn就是HandleStack内部的Proxy包装的方法无论使用哪种协议都会在各自的实现里实例化一个拥有waitFn的Promise的实例。1234567// curl的实现$promisenewPromise([$this,execute],function()use($id) {return$this-cancel($id);});复制讲解由此可以直到waitFn方法就是各自协议的实现类的请求发起方法。then() 方法会将promise本身再封装一层promise并将原先的waitFn和then()的回调方法打包进waitFnList属性里。queue() 是的入队时机当请求执行完成后依次调用 processMessages()、promise-resolve()、settle()、FulfilledPromise-then()将请求结果插入队列。1234567891011$queue-add(staticfunction()use($p,$value,$onFulfilled) {if($p-getState() self::PENDING) {try{$p-resolve($onFulfilled($value));}catch(\Throwable$e) {$p-reject($e);}catch(\Exception$e) {$p-reject($e);}}});以上就是PHP使用Guzzle发起的异步请求示例详解的详细内容
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/15 4:54:16

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/15 2:04:12

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/14 10:11:15

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/14 17:14:38

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/14 16:35:50

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/15 4:06:36

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉