CodeIgniter4 CURLRequest類

2020-08-17 16:49 更新

CURLRequest 類是一個(gè)輕量級(jí)的基于 CURL 的 HTTP 客戶端,用于同其他網(wǎng)站和服務(wù)器進(jìn)行溝通。該類可用于獲取谷歌搜索的內(nèi)容,抓取一個(gè)網(wǎng)站頁(yè)面或一個(gè)圖片, 或者是用來(lái)同 API 進(jìn)行信息傳遞等諸多功能。

該類模仿了 Guzzle HTTP Client 庫(kù),因?yàn)樵搸?kù)被廣泛應(yīng)用于多方面。 我們盡可能地與 Guzzle 保持語(yǔ)法一致,不過(guò)如果你需要一些額外的功能的話(比如該類并未提供的功能之類的),可能需要稍微更改一下語(yǔ)法來(lái)使用 Guzzle 庫(kù)。

注解

該類需要安裝你的 PHP 版本的 cURL 庫(kù) 。該庫(kù)是一個(gè)在大多數(shù)情況下都廣泛被使用的庫(kù),但不是所有服務(wù)器都安裝了它。 因此請(qǐng)檢查你的服務(wù)器上安裝了該庫(kù)以解決依賴問(wèn)題。

加載該類庫(kù)

該類庫(kù)可以通過(guò)手動(dòng)加載或者通過(guò) 服務(wù)類 加載。

通過(guò)服務(wù)類來(lái)加載 curlrequest() 方法:

$client = \Config\Services::curlrequest();

你可以將一個(gè)默認(rèn)選項(xiàng)數(shù)組作為參數(shù)傳遞給該方法作為第一個(gè)參數(shù),用于修改 cURL 處理請(qǐng)求的方式。選項(xiàng)描述如下:

$options = [
        'base_uri' => 'http://example.com/api/v1/',
        'timeout'  => 3
];
$client = \Config\Services::curlrequest($options);

當(dāng)手動(dòng)創(chuàng)建類實(shí)例時(shí),你需要傳遞一些依賴。第一個(gè)參數(shù)是 Config\App 類的實(shí)例。第二個(gè)參數(shù)是一個(gè) URI 實(shí)例。第三個(gè)參數(shù)是一個(gè) Response 類的對(duì)象。 第四個(gè)參數(shù)是一個(gè)可選的 $options 數(shù)組:

$client = new \CodeIgniter\HTTP\CURLRequest(
        new \Config\App(),
        new \CodeIgniter\HTTP\URI(),
        new \CodeIgniter\HTTP\Response(new \Config\App()),
        $options
);

使用該類庫(kù)

處理 CURL 請(qǐng)求基本上只是創(chuàng)建一個(gè) Request 請(qǐng)求并獲取 Response 對(duì)象 的過(guò)程。這一過(guò)程就是用來(lái)處理數(shù)據(jù)交換的。 這一過(guò)程后,你可以對(duì)獲得的信息進(jìn)行完全自定義的處理.

發(fā)送請(qǐng)求

大多數(shù)交流會(huì)話是通過(guò) request() 方法進(jìn)行的,該方法觸發(fā)請(qǐng)求并返回一個(gè) Response 實(shí)例。該方法將 HTTP 動(dòng)詞, URL 信息和選項(xiàng)數(shù)組作為請(qǐng)求參數(shù)。:

$client = \Config\Services::curlrequest();


$response = $client->request('GET', 'https://api.github.com/user', [
        'auth' => ['user', 'pass']
]);

由于該響應(yīng)是 CodeIgniter\HTTP\Response 類的一個(gè)實(shí)例對(duì)象,故而可以通過(guò)調(diào)用該類的對(duì)應(yīng)方法:

echo $response->getStatusCode();
echo $response->getBody();
echo $response->getHeader('Content-Type');
$language = $response->negotiateLanguage(['en', 'fr']);

盡管 request() 方法非常靈活,你也可以使用以下的簡(jiǎn)稱方法。 這些方法將 URL 作為第一個(gè)參數(shù)并將選項(xiàng)數(shù)組作為第二個(gè)參數(shù):

* $client->get('http://example.com');
* $client->delete('http://example.com');
* $client->head('http://example.com');
* $client->options('http://example.com');
* $client->patch('http://example.com');
* $client->put('http://example.com');
* $client->post('http://example.com');

base_uri (基礎(chǔ) URI )

base_uri 可以在該類實(shí)例化時(shí)作為一個(gè)選項(xiàng)進(jìn)行設(shè)置。 該參數(shù)使得你可以設(shè)置一個(gè)基礎(chǔ) URI ,并在該實(shí)例對(duì)象進(jìn)行請(qǐng)求時(shí)使用相對(duì) URL 路徑。這一操作在和 API 通信時(shí)特別管用:

$client = \Config\Services::curlrequest([
        'base_uri' => 'https://example.com/api/v1/'
]);


// GET http:example.com/api/v1/photos
$client->get('photos');


// GET http:example.com/api/v1/photos/13
$client->delete('photos/13');

當(dāng) request() 方法或者其他簡(jiǎn)稱方法接受相對(duì) URI 作為參數(shù)時(shí),就會(huì)將 base_uri 和該相對(duì) URI 根據(jù) RFC 2986, section 2 進(jìn)行組合 以下是一些組合的例子

使用響應(yīng)

每個(gè) request() 函數(shù)調(diào)用都會(huì)返回一個(gè)包含有許多有用信息和方法的 Response 實(shí)例對(duì)象。最通用的方法使得你可以定制化地處理響應(yīng)對(duì)象本身。

你可以獲取響應(yīng)的狀態(tài)碼以及狀態(tài)原因:

$code   = $response->getStatusCode();    // 200
$reason = $response->getReason();      // OK

你可以獲取響應(yīng)頭:

// 獲取一個(gè)響應(yīng)頭的內(nèi)容
echo $response->getHeaderLine('Content-Type');


// 獲取所有響應(yīng)頭
foreach ($response->getHeaders() as $name => $value)
{
        echo $name .': '. $response->getHeaderLine($name) ."\n";
}

響應(yīng)體可以通過(guò) getBody() 方法來(lái)獲取:

$body = $response->getBody();

響應(yīng)體是遠(yuǎn)端服務(wù)器提供的原生響應(yīng)內(nèi)容。如果內(nèi)容類型需要格式化的話,你需要保證在代碼中這樣處理:

if (strpos($response->getHeader('content-type'), 'application/json') !== false)
{
        $body = json_decode($body);
}

請(qǐng)求選項(xiàng)

本節(jié)描述了在構(gòu)造函數(shù), request() 方法以及所有簡(jiǎn)稱方法中可以傳遞的所有可用選項(xiàng)。

allow_redirects (運(yùn)行重定向)

默認(rèn)情況下, CURL 會(huì)遵循遠(yuǎn)端服務(wù)器返回的所有的 “Location:” 響應(yīng)頭規(guī)則。 allow_redirects 選項(xiàng)使得你可以修改這一執(zhí)行過(guò)程。

如果該值被設(shè)為 false ,就不會(huì)執(zhí)行任何的重定向規(guī)則。

$client-&request(‘GET’, ‘http://example.com’, [‘a(chǎn)llow_redirects’ =& false]);

設(shè)為 true 時(shí)就會(huì)執(zhí)行請(qǐng)求的默認(rèn)設(shè)置:

$client->request('GET', 'http://example.com', ['allow_redirects' => true]);


// 設(shè)置以下默認(rèn)選項(xiàng):
'max'       => 5, // 終止前最多的重定向次數(shù)
'strict'    => true, // 在重定向過(guò)程中確保發(fā)送的 POST 請(qǐng)求始終保持為 POST (譯注:某些服務(wù)器會(huì)在重定向時(shí)修改請(qǐng)求方法,例如 304 重定向時(shí)修改請(qǐng)求方式為 GET)
'protocols' => ['http', 'https'] // 限制重定向使用一個(gè)或多個(gè)協(xié)議

你可以為 allow_redirects 選項(xiàng)傳遞一個(gè)選項(xiàng)數(shù)組用于重定向時(shí)使用新的設(shè)置,而不是默認(rèn)設(shè)置:

$client->request('GET', 'http://example.com', ['allow_redirects' => [
        'max'       => 10,
        'protocols' => ['https'] // Force HTTPS domains only.
]]);

注解

當(dāng) PHP 在 safe_mode 或者 open_basedir 選項(xiàng)開啟時(shí),不會(huì)進(jìn)行重定向。

auth (認(rèn)證)

使得你可以為 HTTP BasicDigest 和認(rèn)證過(guò)程提供細(xì)節(jié)信息。 你的腳本文件需要執(zhí)行額外操作以支持診斷認(rèn)證——只需要在訪問(wèn)時(shí)傳遞用戶名和密碼。第三個(gè)參數(shù)是認(rèn)證的類型,可以是 basic 或者 digest:

$client->request('GET', 'http://example.com', ['auth' => ['username', 'password', 'digest']]);

body (請(qǐng)求體)

對(duì)于支持請(qǐng)求體的方法,例如 PUT 或者是 POST 來(lái)說(shuō),有兩種方法來(lái)設(shè)置請(qǐng)求體。 第一種是使用 setBody() 方法:

$client->setBody($body)
       ->request('put', 'http://example.com');

第二種方法是通過(guò)傳遞一個(gè) body 選項(xiàng)。該方式是為了與 Guzzle 兼容起見的,并提供了和上述方式一樣的功能。該值必須是一個(gè)字符串:

$client->request('put', 'http://example.com', ['body' => $body]);

cert (證書)

指定一個(gè) PEM 格式的客戶端證書的位置,通過(guò)為 cert 選項(xiàng)來(lái)傳遞絕對(duì)路徑的方式來(lái)實(shí)現(xiàn)。 如果需要密碼的話,為該選項(xiàng)數(shù)組的第一個(gè)元素的值為路徑,第二個(gè)元素的值設(shè)為密碼:

$client->request('get', '/', ['cert' => ['/path/getServer.pem', 'password']);

connect_timeout (連接超時(shí))

默認(rèn)情況下, CodeIgniter 并未對(duì) cURL 嘗試連接一個(gè)網(wǎng)站的時(shí)間進(jìn)行限制。 如果你需要修改這個(gè)值,可以通過(guò)為 connect_timeout 選項(xiàng)提供時(shí)間秒數(shù)值的方式來(lái)進(jìn)行。傳值為0時(shí),無(wú)限等待:

$response->request('GET', 'http://example.com', ['connect_timeout' => 0]);

cookie

該選項(xiàng)指定了 CURL 用于存取 cookie 值的文件名。這一過(guò)程通過(guò)使用 CURL_COOKIEJAR 和 CURL_COOKIEFILE 選項(xiàng)來(lái)實(shí)現(xiàn)。 例如:

$response->request('GET', 'http://example.com', ['cookie' => WRITEPATH . 'CookieSaver.txt']);

debug (調(diào)試bug)

當(dāng) debug 被傳遞并設(shè)為 true 時(shí),就會(huì)啟動(dòng)額外的調(diào)試模式并在腳本執(zhí)行時(shí)輸出標(biāo)準(zhǔn)錯(cuò)誤流信息( STDERR )。 該操作是通過(guò)傳遞 CURLOPT_VERBOSE 并返回輸出來(lái)實(shí)現(xiàn)的。 因此當(dāng)你需要利用 spark serve 運(yùn)行一個(gè)內(nèi)置服務(wù)器時(shí),將會(huì)看到命令行中的輸出內(nèi)容。否則輸出就會(huì)被寫入到服務(wù)器的錯(cuò)誤日志中:

$response->request('GET', 'http://example.com', ['debug' => true]);

可以通過(guò)將文件名作為參數(shù)傳入的方式,將輸出寫入到文件中:

$response->request('GET', 'http://example.com', ['debug' => '/usr/local/curl_log.txt']);

delay (延時(shí))

使得你可以在發(fā)送請(qǐng)求前延遲指定的毫秒時(shí)間:

// 延時(shí)2秒
$response->request('GET', 'http://example.com', ['delay' => 2000]);

form_params (表單參數(shù))

你可以通過(guò)為 form_params 選項(xiàng)傳遞關(guān)聯(lián)數(shù)組的方式,在一個(gè) application/x-www-form-urlencoded POST 請(qǐng)求里發(fā)送表單數(shù)據(jù)。 該操作會(huì)將 Content-Type 請(qǐng)求頭強(qiáng)制設(shè)為 application/x-www-form-urlencoded

$client->request('POST', '/post', [
        'form_params' => [
                'foo' => 'bar',
                'baz' => ['hi', 'there']
        ]
]);

注解

form_params 不能和 multipart 選項(xiàng)一起使用。你可以非此即彼地使用這兩個(gè)選項(xiàng)。form_params 用于 application/x-www-form-urlencoded 請(qǐng)求,而 multipart 用于 multipart/form-data 請(qǐng)求。

headers (請(qǐng)求頭)

盡管你可以通過(guò) setHeader() 方法來(lái)傳遞任何請(qǐng)求頭,你也可以通過(guò)為選項(xiàng)傳遞關(guān)聯(lián)數(shù)組作為參數(shù)的方式來(lái)實(shí)現(xiàn)自定義請(qǐng)求頭。 該關(guān)聯(lián)數(shù)組中每個(gè)鍵都是請(qǐng)求頭的名字,而值就是一個(gè)字符串或者是一個(gè)字符串?dāng)?shù)組,包括著請(qǐng)求頭字段的值:

$client->request('get', '/', [
        'headers' => [
                'User-Agent' => 'testing/1.0',
                'Accept'     => 'application/json',
                'X-Foo'      => ['Bar', 'Baz']
        ]
]);

如果請(qǐng)求頭在構(gòu)造函數(shù)中被傳入時(shí),就會(huì)被設(shè)為默認(rèn)選項(xiàng)。而默認(rèn)選項(xiàng)會(huì)被后續(xù)設(shè)置的選項(xiàng)或者 setHeader() 的調(diào)用所覆蓋。

http_errors (http錯(cuò)誤)

默認(rèn)情況下,CURLRequest 類會(huì)在 HTTP 狀態(tài)碼大于等于400時(shí)結(jié)束請(qǐng)求并報(bào)錯(cuò)。 你可以通過(guò)將 http_errors 選項(xiàng)設(shè)為 false 的方式來(lái)返回內(nèi)容:

$client->request('GET', '/status/500');
// 自動(dòng)失敗報(bào)錯(cuò)


$res = $client->request('GET', '/status/500', ['http_errors' => false]);
echo $res->getStatusCode();
// 500

json

json 選項(xiàng)用于上傳 JSON 編碼的數(shù)據(jù)作為請(qǐng)求體。同時(shí)會(huì)在請(qǐng)求頭上加入 Content-Type 為 application/json 。 并覆蓋先前設(shè)置的 Content-Type 請(qǐng)求頭。傳遞給該選項(xiàng)的參數(shù)可以是任何 json_encode() 函數(shù)所接受的參數(shù):

$response = $client->request('PUT', '/put', ['json' => ['foo' => 'bar']]);

注解

該選項(xiàng)不允許對(duì) json_encode() 和 Content-Type 請(qǐng)求頭進(jìn)行自定義地修改。如果你需要這一功能, 就需要手動(dòng)編碼數(shù)據(jù)并將其傳遞給 CURLRequest 類的 setBody() 方法,并通過(guò) setHeader() 方法來(lái)設(shè)置 Content-Header 請(qǐng)求頭。

multipar

如果你想通過(guò) POST 請(qǐng)求來(lái)發(fā)送文件或者其他數(shù)據(jù)時(shí),可以使用 multipart 選項(xiàng)和 CURLFile 類 。 該選項(xiàng)的值應(yīng)當(dāng)是一個(gè)需要關(guān)聯(lián)數(shù)組,包含有需要發(fā)送的數(shù)據(jù)。為了安全起見,上傳文件時(shí)在前綴上加上 @ 的遺留方法已被禁止。你所需要發(fā)送的文件應(yīng)當(dāng)以 CURLFile 類的實(shí)例的方式傳遞:

$post_data = [
        'foo'      => 'bar',
        'userfile' => new \CURLFile('/path/to/file.txt')
];

注解

multipart 不能和 form_params 選項(xiàng)一起使用。你可以非此即彼地使用這兩個(gè)選項(xiàng)。 form_params 用于 application/x-www-form-urlencoded 請(qǐng)求,而 multipart 用于 multipart/form-data 請(qǐng)求。

query (查詢語(yǔ)句)

你可以通過(guò)為 query 選項(xiàng)傳遞一個(gè)關(guān)聯(lián)數(shù)組的方式來(lái)發(fā)送查詢字符串信息:

// 發(fā)送一個(gè) GET 請(qǐng)求來(lái)獲取 /get?foo=bar 的結(jié)果
$client->request('GET', '/get', ['query' => ['foo' => 'bar']]);

timeout(超時(shí))

默認(rèn)情況下, cURL 函數(shù)可以執(zhí)行任意長(zhǎng)的時(shí)間,不受時(shí)間限制。你可以通過(guò) timeout 選項(xiàng)來(lái)修改這一過(guò)程。選項(xiàng)值是你需要這個(gè)函數(shù)運(yùn)行的時(shí)間。使用0來(lái)無(wú)限等待:

$response->request('GET', 'http://example.com', ['timeout' => 5]);

verify(鑒權(quán))

該選項(xiàng)描述了 SSL 驗(yàn)證鑒權(quán)行為。 如果 verify 選項(xiàng)被設(shè)為 true ,就開始 SSL 鑒權(quán)操作并使用系統(tǒng)提供默認(rèn)的 CA 包文件。如果設(shè)為 false ,就會(huì)禁用鑒權(quán)操作(這一行為不安全,并可能導(dǎo)致中間人攻擊?。?。 你可以將該參數(shù)設(shè)為一個(gè) CA 包文件所在的路徑,從而進(jìn)行自定義的鑒權(quán)操作。該選項(xiàng)默認(rèn)值為 true

// 使用系統(tǒng)的 CA 包文件(默認(rèn)設(shè)置)
$client->request('GET', '/', ['verify' => true]);


// 使用硬盤上的一個(gè)自定義的 SSL 鑒權(quán)文件
$client->request('GET', '/', ['verify' => '/path/to/cert.pem']);


// 完全禁用鑒權(quán)(不安全?。?$client->request('GET', '/', ['verify' => false]);

version(版本)

你可以通過(guò)為版本參數(shù)傳遞一個(gè)字符串或者浮點(diǎn)數(shù)(特別是1.0,或1.1,尚未支持2.0)的方式來(lái)設(shè)置協(xié)議版本:

// 強(qiáng)制使用 HTTP/1.0
$client->request('GET', '/', ['version' => 1.0]);
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)