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的簡單使用完結---------------------------------------------------------