0

0

PHP网络请求插件Guzzle使用

Guanhui

Guanhui

发布时间:2020-05-01 09:40:57

|

6398人浏览过

|

来源于jianshu

转载

在写后台代码时,避免不了需要与其他第三方接口交互,如向服务号下发模板消息,有时可能需要下发超过 10 万条。这时不得不考虑使用异步和「多线程」的网络请求。

今天向 PHP 工程师们推荐一个 Guzzle 插件。

Guzzle

Guzzle 是一个 PHP 的 HTTP 客户端,用来轻而易举地发送请求,并集成到我们的 WEB 服务上。

接口简单:构建查询语句、POST 请求、分流上传下载大文件、使用 HTTP cookies、上传 JSON 数据等等。

立即学习PHP免费学习笔记(深入)”;

发送同步或异步的请求均使用相同的接口。

使用 PSR-7 接口来请求、响应、分流,允许你使用其他兼容的 PSR-7 类库与 Guzzle 共同开发。

抽象了底层的 HTTP 传输,允许你改变环境以及其他的代码,如:对 cURL与 PHP 的流或 socket 并非重度依赖,非阻塞事件循环。

中间件系统允许你创建构成客户端行为。

安装 Guzzle

本文结合 Laravel 项目介绍 Guzzle 基本使用,所以使用 composer 来安装 Guzzle 再适合不过了,而且 Guzzle 官网也推荐使用 composer 来安装。

composer require guzzlehttp/guzzle:~6.0
// 或者
php composer.phar require guzzlehttp/guzzle:~6.0

发送简单的 POST 请求

访问第三方接口,基本上都是 POST 请求为主。如你想做一个简单的智能聊天工具,这时候可以借助图灵机器人 API,发送一个 POST 请求获取自动回答内容,直接上代码:

 '*****',
            'userid' => 'yemeishu'
        ];
        $params['info'] = $request->input('info', '你好吗');
        $client = new Client();
        $options = json_encode($params, JSON_UNESCAPED_UNICODE);
        $data = [
            'body' => $options,
            'headers' => ['content-type' => 'application/json']
        ];
        // 发送 post 请求
        $response = $client->post('http://www.tuling123.com/openapi/api', $data);
        $callback = json_decode($response->getBody()->getContents());
        return $this->output_json('200', '测试图灵机器人返回结果', $callback);
    }
}

Guzzle client->post 函数还是很简单的,只需要访问的接口,和请求的参数,参数中主要包含:body、headers、query等,具体可参考

http://guzzle-cn.readthedocs.io/zh_CN/latest/quickstart.html#id8

测试下:

6302-8a23f04d4eb24a12.jpg

6302-2f9f5585e3f021f6.jpg

Magic CMS 网站管理系统2.2.1.alpha 政企版
Magic CMS 网站管理系统2.2.1.alpha 政企版

Magic CMS网站管理系统(政企版)采用PHP+Mysql架构,再原CMS系统的基础上精简出适合企业政府客户使用版本,继承了原系统的快捷,高效,灵活,实用的特点,保留了核心功能,系统支持自定义模版(极易整合dede模板)、支持扩展插件,自定义模型等功能,保留了文章模型,视频模型,图集模型,产品模型,能够胜任企业多种建站需求。BUG修复:1.修改了程序安装时部分数据无法正常导入的错误2.修改了程

下载
注:图灵机器人还是很智能的,根据相同的 userid 能够识别上下文,做到智能聊天的。

发送异步的 POST 请求

在 PHP 开发中主要是「面向过程」式的开发方式,但请求第三方接口时,有时候并不需要等待第三方接口返回结果才继续执行。如用户购买成功时,我们需要向短信接口,发送一个 post 请求,由短信平台发送一条短信给用户,告知用户支付成功了,因为这类「提醒消息」属于「额外的附加功能」,并不需要在用户支付时「知道」有没有发送提醒成功。

这时候可以使用 Guzzle 的异步请求功能,直接看代码:

public function sms(Request $request) {
    $code = $request->input('code');
    $client = new Client();
    $sid = '9815b4a2bb6d5******8bdb1828644f2';
    $time = '20171029173312';
    $token = 'af8728c8bc*******12019c680df4b11c';

    $sig =  strtoupper(md5($sid.$token.$time));

    $auth = trim(base64_encode($sid . ":" . $time));

    $params = ['templateSMS' => [
            'appId' => '12b43**********0091c73c0ab',
            'param' => "coding01,$code,30",
            'templateId' => '3***3',
            'to' => '17689974321'
        ]
    ];
    $options = json_encode($params, JSON_UNESCAPED_UNICODE);
    $data = [
        'query' => [
            'sig' => $sig
        ],
        'body' => $options,
        'headers' => [
            'content-type' => 'application/json',
            'Authorization' => $auth
        ]
    ];

    // 发送 post 请求
    $promise = $client->requestAsync('POST', 'https://api.ucpaas.com/2014-06-30/Accounts/9815b4a2bb6d5******8bdb1828644f2/Messages/templateSMS', $data);

    $promise->then(
        function (ResponseInterface $res) {
            Log::info('---');
            Log::info($res->getStatusCode() . "\n");
            Log::info($res->getBody()->getContents() . "\n");
        },
        function (RequestException $e) {
            Log::info('-__-');
            Log::info($e->getMessage() . "\n");
        }
    );
    $promise->wait();

    return $this->output_json('200', '测试短信 api', []);
}

先返回接口数据:

6302-95ec6d7a688f1072.jpg

然后再输出 Log:

[2017-10-29 09:53:14] local.INFO: ---  
[2017-10-29 09:53:14] local.INFO: 200
  
[2017-10-29 09:53:14] local.INFO: {"resp":{"respCode":"000000","templateSMS":{"createDate":"20171029175314","smsId":"24a93f323c9*****8608568"}}}

最后收到短信信息:

微信截图_20200501093336.png

发送多线程异步 POST 请求

「发送多线程异步 POST 请求」在很多场合中使用到的,如:双十一快到了,可以做一些回馈老用户的活动,这是就需要批量的向老用户推送一条模板消息,告诉用户参与哪些活动的。这时候就需要用到多线程异步请求微信公众号接口。

直接上代码:

public function send($templateid, $openid, $url, $data) {
        $client = $this->bnotice->getHttp()->getClient();

        $requests = function ($open_ids) use ($templateid, $url, $data) {
            foreach($open_ids as $v){
                try {
                    yield $this->bnotice
                        ->template($templateid)
                        ->to($v)
                        ->url($url)
                        ->data($data)
                        ->request();
                } catch(Exception $e) {
                    Log::error('sendtemplate:'.$e->getMessage());
                }
            }
        };

        $pool = new Pool($client, $requests($openid), [
            'concurrency' => 16,
            'fulfilled' => function ($response, $index) {
            },
            'rejected' => function ($reason, $index) {
            },
        ]);

        $promise = $pool->promise();

        $promise->wait();
    }

其中 request 方法:

public function request($data = [])
    {
        $params = array_merge([
            'touser' => '',
            'template_id' => '',
            'url' => '',
            'topcolor' => '',
            'miniprogram' => [],
            'data' => [],
        ], $data);
        
        $required = ['touser', 'template_id'];

        foreach ($params as $key => $value) {
            if (in_array($key, $required, true) && empty($value) && empty($this->message[$key])) {
                throw new InvalidArgumentException("Attribute '$key' can not be empty!");
            }

            $params[$key] = empty($value) ? $this->message[$key] : $value;
        }

        $params['data'] = $this->formatData($params['data']);

        $this->message = $this->messageBackup;

        $options = json_encode ( $params,  JSON_UNESCAPED_UNICODE);
        $data = [
            'query' => [
                'access_token' => $this->getAccessToken()->getToken()
            ],
            'body' => $options,
            'headers' => ['content-type' => 'application/json']
        ];
        return function() use ($data) {
            return $this->getHttp()->getClient()->requestAsync('POST', $this::API_SEND_NOTICE, $data);
        };
    }

Guzzle 多线程异步请求原型函数,使用 GuzzleHttp\Pool 对象

use GuzzleHttp\Pool;use GuzzleHttp\Client;use GuzzleHttp\Psr7\Request;$client = new Client();$requests = function ($total) {
    $uri = 'http://127.0.0.1:8126/guzzle-server/perf';
    for ($i = 0; $i < $total; $i++) {
        yield new Request('GET', $uri);
    }};$pool = new Pool($client, $requests(100), [
    'concurrency' => 5,
    'fulfilled' => function ($response, $index) {
        // this is delivered each successful response
    },
    'rejected' => function ($reason, $index) {
        // this is delivered each failed request
    },]);// Initiate the transfers and create a promise$promise = $pool->promise();// Force the pool of requests to complete.$promise->wait();

总结

有了 Guzzle,极大方便了我们并发异步请求第三方接口。如果时间允许,我们可以看看 Guzzle 源代码,看看是如何实现的。

推荐教程:《PHP教程

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

37

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

37

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

9

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.6万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号