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實例。