PHP 网络请求插件 Guzzle(一)
Guzzle插件是何方神圣
Guzzle在英文中的读音是: 英 [ˈgʌzl] 。意识是:狂吃暴饮,大吃大喝;
Guzzle是一个利用PHP实现发送HTTP 请求,方便和web service集成的PHP 客户端模拟组件。一句话,它就像一个PHP写的浏览器。当你的服务端程序需要作为客户端来访问其他的service服务时,这就是你所需要的。当然如果你想使用PHP做一个爬虫项目也是最棒的选择。
Guzzle是一个PHP的HTTP客户端,用来轻而易举地发送请求,并集成到我们的WEB服务上。Guzzle有许多特点,这里引用官方文档:
- 接口简单:构建查询语句、POST请求、分流上传下载大文件、使用HTTP cookies、上传JSON数据等等。
- 发送同步或异步的请求均使用相同的接口。
- 使用PSR-7接口来请求、响应、分流,允许你使用其他兼容的PSR-7类库与Guzzle共同开发。
- 抽象了底层的HTTP传输,允许你改变环境以及其他的代码,如:对cURL与PHP的流或socket并非重度依赖,非阻塞事件循环。
- 中间件系统允许你创建构成客户端行为。
Guzzle插件安装
Guzzle需要的环境支持:
- >=PHP 5.5.0
- 使用PHP的流,
allow_url_fopen
必须在php.ini中启用。[如果使用集成环境:比如PHPStudy已经默认开启。] - 要使用cURL,你必须已经有版本cURL >= 7.19.4,并且编译了OpenSSL 与 zlib。[如果使用集成环境:比如PHPStudy已经默认开启。使用Guzzle不是必须的!]
开始安装:
推荐使用 Composer 安装Guzzle。【Composer是PHP的依赖管理工具,允许你在项目中声明依赖关系,并安装这些依赖。如果你还不熟悉Composer,赶紧恶补一下吧。现代PHP编程已经是必须的技能】。使用命令行工具直接打命令自动下载安装吧【假如你的操作系统是linux的话,真是一个命令搞定,喝杯咖啡去吧,国外镜像真的用不起:太慢了。当然也可以修改镜像地址为中国的镜像服务器:https://www.phpcomposer.com/。】:
如果是windows系统,直接去Composer中国镜像网站:https://www.phpcomposer.com 下载安装包自动安装吧。总之都是非常简单的事情!
好了,我们已经准备好了,开始安装Guzzle吧。这时候无论是哪种操作系统。我们直接使用命令行工具进入项目目录,贴安装命令,一切就搞定了。
#使用compose将Guzzle作为依赖添加到项目:
php composer.phar require guzzlehttp/guzzle:~6.0
快速入门
创建客户端
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'http://httpbin.org',
// You can set any number of default request options.
'timeout' => 2.0,
]);
Client对象可以接收一个包含参数的数组:base_uri
(string|UriInterface) base_uri用来合并到相关URI,可以是一个字符串或者UriInterface的实例,当提供了相关uri,将合并到基URI,遵循的规则请参考 RFC 3986, section 2 章节。
// 使用基uri创建客户端
$client = new GuzzleHttp\Client(['base_uri' => 'https://foo.com/api/']);
// 向https://foo.com/api/test发送请求
$response = $client->request('GET', 'test');
// 向https://foo.com/root发送请求
$response = $client->request('GET', '/root');
不想阅读RFC 3986?这里有一些关于 base_uri
与其他URI处理器的快速例子:
base_uri | URI | Result |
---|---|---|
http://foo.com |
/bar |
http://foo.com/bar |
http://foo.com/foo |
/bar |
http://foo.com/bar |
http://foo.com/foo |
bar |
http://foo.com/bar |
http://foo.com/foo/ |
bar |
http://foo.com/foo/bar |
http://foo.com |
http://baz.com |
http://baz.com |
http://foo.com/?bar |
bar |
http://foo.com/bar |
handler
传输HTTP请求的(回调)函数。 该函数被调用的时候包含 Psr7\Http\Message\RequestInterface
以及参数数组,必须返回 GuzzleHttp\Promise\PromiseInterface
,成功时满足 Psr7\Http\Message\ResponseInterface
。 handler
是一个构造方法,不能在请求参数里被重写。
(混合) 构造方法中传入的其他所有参数用来当作每次请求的默认参数。
注意:
在我们开始编写测试代码之前,我们需要做点配置,以便我们可以的访问ssl网站:https://。
否则我们的测试代码只能访问http://这样的网站。
在没有配置根证书服务文件之前,如果我们尝试编写Guzzle代码访问ssl网站。系统会抛出访问异常代码:
GuzzleHttp\Exception\RequestException:
cURL error 60: SSL certificate
problem: unable to get local issuer certificate
(see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
系统异常想告诉我们他找不到根证书服务文件,也就是cacert.pem。那这个文件是干什么的呢。这要我们了解一下open ssl的访问过程。首先各个浏览器厂商在开发时已经把各个CA厂商的公钥信息集成到了浏览器内。当我们使用浏览器访问https的网站时,浏览器根据已集成的CA厂商信息,直接去认证访问。
而我们使用的Guzzle客户端,因为还没有集成CA厂商信息文件。这时如果想访问https网站,我们就得想办法弄到各个CA证书厂商的信息,然后合成为.pem文件。这对于一般的开发者是相当繁琐的事。好在已经有人帮我们做了这些事。就是通过从Mozilla提取的CA证书,我们直接下载下来用便是。下载网址是:https://curl.haxx.se/docs/caextract.html。
我们把下载下来的cacert.pem放入我们的服务器环境目录里。当然你可以任意放置,只要做好php.ini的配置文件和访问权限就好。比如我用的事phpstudy集成环境,PHP版本为PHP7.3.4nts_p。按照习惯我就把cacert.pem放进:D:\phpstudy_pro\Extensions\php\php7.3.4nts_p\extras\ssl目录。接下来就开始配置php.ini文件。
在PHP.ini的php.ini Options下面插入下面语句:
;;;;;;;;;;;;;;;;;;;;
; php.ini Options ;
;;;;;;;;;;;;;;;;;;;;
; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
;user_ini.filename = ".user.ini"
//根证书服务文件
curl.cainfo = "D:\phpstudy_pro\Extensions\php\php7.3.4nts_p\extras\ssl\cacert.pem"
OK!我们重启Apache服务器。然后重新访问我们的测试程序,已经开始正常工作了。
Guzzle测试代码:
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
require 'vendor/autoload.php';
try
{
//使用Guzzle试验一 2019/10/21
$http = new Client();
$request = new Request('GET', 'https://blog.csdn.net/weixin_40583088');
$response = $http->send($request, ['timeout' => 2]);
var_dump($request);
}
catch(throwable $e)
{
echo $e;
}
返回的部分结果是:
object(GuzzleHttp\Psr7\Request)#15 (7) {
["method":"GuzzleHttp\Psr7\Request":private]=> string(3) "GET"
["requestTarget":"GuzzleHttp\Psr7\Request":private]=> NULL
......
接下来我们开始尝试编写代码:
还记得上面的client类么,我们开始实例化一个新client对象。
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
require 'vendor/autoload.php';
try
{
//使用Guzzle试验一 2019/10/21
$http = new Client();
}
catch(throwable $e)
{
echo $e;
}
我们并不打算在初始化时给他传参数。我们通过Client的request方法给他传我们需要的任务值。request方法是查询字符串参数方法。代码如下:
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
require 'vendor/autoload.php';
try
{
//使用Guzzle试验一 2019/10/21
$http = new Client();
$response = $http->request('GET', 'http://www.baidu.com', [
"timeout" => 3000
]);
echo "<H1>返回状态代码:".$response->getStatusCode(). "</H1>\n";
echo $response->getBody();
}
catch(throwable $e)
{
echo $e;
}
这时我们的运行结果应该是这样的:
本节我们安装并创建了Guzzle的客户端实例:Client实例。