PHP 网络请求插件 Guzzle 入门(一)
Guzzle的使命就是模拟浏览器作为客户端请求获得资源,所以Guzzle的功能主要就是请求数据和获取数据。
Guzzle整个逻辑生命过程就是:建立Client客户端实例------>填写请求选项------->触发需要的请求函数------->reponse(获得返回值)。 (如果需要,可以加入异步、并发)。整个请求返回过程大致就是这样。Guzzle里还特意加入了中间件来处理我们特有的请求功能。如果需要可以在请求时转向中间件。
下面我们用代码了解一下Guzzle一般的工作工程。通过注册树的方式建立了一个类,封装了Guzzle常见的Get、Post、异步与并发。
通过这个类的实现,我们基本可以清楚了解Guzzle的使用。当然更多的功能就是看我们怎样去填充请求选项。请求选项可以参考Guzzle的中文文档,根据不同需求来扩展此类。此类来源于noodles1994的博客文章与代码:https://guzzle-cn.readthedocs.io/zh_CN/latest/index.html#。经过测试稍微修改了源代码,noodles1994对返回值都做了json解析,但是我们做测试时不一定获得的时json编码。如果我们硬解析肯定会出错。修改后以便测试使用与学习。还有一点就是在异常捕获时,我故意在一处使用Throwable异常类,看看是否会捕获到异常信息。
<?php
/*
* @ProjectName: 开软PHP实验室
* @company:河南省开软网络科技有限公司
* @Description:
* @Copyright:木兰宽松许可证第1版(2019年8月5日中国有了自己的开源许可证,为了支持与好玩咱也加上)
* @Author: 古剑楠
* @Date: 2019-10-26 13:22:15
* @Last Modified by: 古剑楠
* @Last Modified time: 2019-10-26 13:22:35
*/
namespace sdk;
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Promise;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;
//注册树模式 测试时一定要搭建好环境 见第一篇
class Guzzle
{
//注册树容器
private static $guzzle = [];
/**
* 释放资源
*/
public static function destoryAll()
{
//如果注册树容器为空
if( count(self::$guzzle) === 0 )
{
return TRUE;
}
//遍历注册树销毁
foreach (self::$guzzle as $obj)
{
$obj = null;
}
}
/**
* 实例化guzzle(单例)
* @param $base_uri
* @return bool
* */
private static function init($base_uri)
{
if(!empty($base_uri))
{
if( !isset(self::$guzzle[$base_uri]) )
{
self::$guzzle[$base_uri] = new Client([
// 基URI
'base_uri' => $base_uri,
// 请求选项
'timeout' => 10.0,
]);
return True;
}
else
{
return True;
}
}
else
{
return FALSE;
}
}
/**
* 获取guzzle实例
* @param $base_uri
* @return bool|obj
**/
private static function getGuzzle($base_uri)
{
if(Guzzle::init($base_uri) == FALSE)
{
return FALSE;
}
return self::$guzzle[$base_uri];
}
/**
* get请求
* @param string $base_uri 设置uri
* @param string $api 请求api
* @param array $headers 请求头
* @return mixed
* @Throwable
*/
public static function guzzleGet($base_uri, $api, $headers = [])
{
$guzzleGetHandel = Guzzle::getGuzzle($base_uri);
try
{
$data = [
'headers' => $headers,
];
$response = $guzzleGetHandel->get($api, $data);
$responseCode = $response->getStatusCode();
$responseBody = $response->getBody();
$responseBody = $responseBody->getContents();
//返回没有处理的数据
return $responseBody;
}
catch (RequestException $e)
{
echo $e->getMessage();
}
}
/**
* get请求(异步)
* @param string $base_uri
* @param string $api 请求api
* @param array $headers 请求头
* @return mixed
* @Throwable
*/
public static function guzzleGetAsync($base_uri, $api, $headers = [])
{
$guzzleGetHandel = Guzzle::getGuzzle($base_uri);
try
{
$data = [
'headers' => $headers,
];
$promises = [$guzzleGetHandel->getAsync($api, $data)];
$response = Promise\unwrap($promises);
//因为用到了并发的功能。给$promises传递数组就是调用并发。为了安全使用foreach便利一下。
foreach ($response as $k => $v)
{
$responseBody = $v->getBody()->getContents(); //获取server端返回值
}
return $responseBody;
}
catch (Throwable $e)
{
echo "错误";
echo $e->getMessage();
}
}
/**
* get请求(并行异步)
* @param string $base_uri 设置uri
* @param string $api 请求api
* @param array $headers 请求头
* @return mixed
* @throws \Exception
*/
public static function guzzleGetAsyncParallel($base_uri, Array $api)
{
$guzzleGetHandel = Guzzle::getGuzzle($base_uri);
try
{
$promises = [];
$info = [];
if(!empty($api))
{
foreach ($api as $value)
{
array_push($promises, $guzzleGetHandel->getAsync($value));
}
}
$response = Promise\unwrap($promises); //客户端发起请求并等待所有的请求结束再返回结果
foreach ($response as $k => $v)
{
$responseBody[] = $v->getBody()->getContents(); //获取server端返回值
}
return $responseBody;
}
catch (RequestException $e)
{
throw new \Exception($e->getMessage());
}
}
/**
* post请求
* @param string $base_uri 设置uri
* @param string $api 请求api
* @param array $post_data 请求数据
* @param array $headers 请求头
* @param string $type 请求类型 json
* @param string $cookie 请求cookies
* @return mixed
* @throws \Exception
*/
public static function guzzlePost($base_uri, $api, $post_data = [], $headers = [], $type = 'json', $cookie = '')
{
$guzzlePostHandle = Guzzle::getGuzzle($base_uri);
try
{
if($type === 'json')
{
$data = [
'headers' => $headers,
'json' => $post_data,
'cookies' => $cookie,
];
}
else
{
$data = [
'headers' => $headers,
'body' => $post_data,
'cookies' => $cookie,
];
}
$response = $guzzlePostHandle->post($api, $data);
$responseCode = $response->getStatusCode();
$responseBody = $response->getBody()->getContents();
return $responseBody;
}
catch (RequestException $e)
{
throw new \Exception($e->getMessage());
}
}
/**
* post请求(异步)
* @param string $base_uri 设置uri
* @param string $api 请求api
* @param array $post_data 请求数据
* @param array $headers 请求头
* @param string $type 请求类型 json
* @param string $cookie 请求cookies
* @return array|mixed
* @throws \Exception
*/
public static function guzzlePostAsync($base_uri, $api, $post_data = [], $headers = [], $type = 'json', $cookie = '')
{
$guzzlePostHandle = Guzzle::getGuzzle($base_uri);
$responseBody = [];
try
{
if($type === 'json')
{
$data = [
'headers' => $headers,
'json' => $post_data,
'cookies' => $cookie,
];
}else{
$data = [
'headers' => $headers,
'body' => $post_data,
'cookies' => $cookie,
];
}
$promises = [$guzzlePostHandle->postAsync($api, $data)];
$response = Promise\unwrap($promises);
foreach ($response as $k => $v)
{
$responseBody = $v->getBody()->getContents(); //获取server端返回值 如果返回数据是json需要json解码
}
return $responseBody;
}
catch (RequestException $e)
{
throw new \Exception($e->getMessage());
}
}
。。。。。。。。。。。
}
-----------------------------------Guzzle的简单使用完结---------------------------------------------------------