easyhttp——輕量級、語義化、 對 IDE 友好的 HTTP 客戶端

gouguoyin發表於2020-03-31

EasyHttp 是一個輕量級、語義化、對IDE友好的HTTP客戶端,支援常見的HTTP請求、非同步請求和併發請求,讓你可以快速地使用 HTTP 請求與其他 Web 應用進行通訊。

EasyHttp並不強制依賴於cURL,如果沒有安裝cURL,EasyHttp會自動選擇使用PHP流處理,或者你也可以提供自己的傳送HTTP請求的處理方式。

如果您覺得EasyHttp對您有用的話,別忘了給點個贊哦^_^ !
github:github.com/gouguoyin/easyhttp
gitee:gitee.com/gouguoyin/easyhttp

安裝說明

環境依賴

  • PHP >= 5.5.0
  • 如果使用PHP流處理,allow_url_fopen 必須在php.ini中啟用。
  • 如果使用cURL處理,cURL >= 7.19.4,並且編譯了OpenSSL 與 zlib。

一鍵安裝

composer require gouguoyin/easyhttp

發起請求

同步請求

常規請求
$response = Http::get('http://httpbin.org/get');

$response = Http::get('http://httpbin.org/get?name=gouguoyin');

$response = Http::get('http://httpbin.org/get?name=gouguoyin', ['age' => 18]);

$response = Http::post('http://httpbin.org/post');

$response = Http::post('http://httpbin.org/post', ['name' => 'gouguoyun']);

$response = Http::patch(...);

$response = Http::put(...);

$response = Http::delete(...);

$response = Http::head(...);

$response = Http::options(...);
傳送 Content-Type 編碼請求
// application/x-www-form-urlencoded(預設)
$response = Http::asForm()->post(...);

// application/json
$response = Http::asJson()->post(...);
傳送 Multipart 表單請求
$response = Http::asMultipart(
    'file_input_name', file_get_contents('photo1.jpg'), 'photo2.jpg'
)->post('http://test.com/attachments');

$response = Http::asMultipart(
    'file_input_name', fopen('photo1.jpg', 'r'), 'photo2.jpg'
)->post(...);

$response = Http::attach(
    'file_input_name', file_get_contents('photo1.jpg'), 'photo2.jpg'
)->post(...);

$response = Http::attach(
    'file_input_name', fopen('photo1.jpg', 'r'), 'photo2.jpg'
)->post(...);

表單enctype屬性需要設定成 multipart/form-data

攜帶請求頭的請求
$response = Http::withHeaders([
    'x-powered-by' => 'gouguoyin'
])->post(...);
攜帶重定向的請求
// 預設
$response = Http::withRedirect(false)->post(...);

$response = Http::withRedirect([
    'max'             => 5,
    'strict'          => false,
    'referer'         => true,
    'protocols'       => ['http', 'https'],
    'track_redirects' => false
])->post(...);
攜帶認證的請求
// Basic認證
$response = Http::withBasicAuth('username', 'password')->post(...);

// Digest認證(需要被HTTP伺服器支援)
$response = Http::withDigestAuth('username', 'password')->post(...);
攜帶 User-Agent 的請求
$response = Http::withUA('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36')->post(...);
攜帶Token令牌的請求
$response = Http::withToken('token')->post(...);
攜帶認證檔案的請求
$response = Http::withCert('/path/server.pem', 'password')->post(...);
攜帶SSL證照的請求
// 預設
$response = Http::withVerify(false)->post(...);

$response = Http::withVerify('/path/to/cert.pem')->post(...);
攜帶COOKIE的請求
$response = Http::withCookies(array $cookies, string $domain)->post(...);
攜帶協議版本的請求
$response = Http::withVersion(1.1)->post(...);
攜帶代理的請求
$response = Http::withProxy('tcp://localhost:8125')->post(...);

$response = Http::withProxy([
    'http'  => 'tcp://localhost:8125', // Use this proxy with "http"
    'https' => 'tcp://localhost:9124', // Use this proxy with "https",
    'no'    => ['.com.cn', 'gouguoyin.cn'] // Don't use a proxy with these
])->post(...);
設定超時時間(單位秒)
$response = Http::timeout(60)->post(...);
設定延遲時間(單位秒)
$response = Http::delay(60)->post(...);
設定併發次數
$response = Http::concurrency(10)->promise(...);

非同步請求

use Gouguoyin\EasyHttp\Response;
use Gouguoyin\EasyHttp\RequestException;

Http::getAsync('http://easyhttp.gouguoyin.cn/api/sleep3.json', ['token' => TOKEN], function (Response $response) {
    echo '非同步請求成功,響應內容:' . $response->body() . PHP_EOL;
}, function (RequestException $e) {
    echo '非同步請求異常,錯誤碼:' . $e->getCode() . ',錯誤資訊:' . $e->getMessage() . PHP_EOL;
});
echo json_encode(['code' => 200, 'msg' => '請求成功'], JSON_UNESCAPED_UNICODE) . PHP_EOL;

//輸出
{"code":200,"msg":"請求成功"}
非同步請求成功,響應內容:{"code":200,"msg":"success","second":3}

Http::getAsync('http1://easyhttp.gouguoyin.cn/api/sleep3.json', function (Response $response) {
    echo '非同步請求成功,響應內容:' . $response->body() . PHP_EOL;
}, function (RequestException $e) {
    echo '非同步請求異常,錯誤資訊:' . $e->getMessage() . PHP_EOL;
});
echo json_encode(['code' => 200, 'msg' => '請求成功'], JSON_UNESCAPED_UNICODE) . PHP_EOL;

//輸出
{"code":200,"msg":"請求成功"}
非同步請求異常,錯誤資訊:cURL error 1: Protocol "http1" not supported or disabled in libcurl (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

Http::postAsync(...);

Http::patchAsync(...);

Http::putAsync(...);

Http::deleteAsync(...);

Http::headAsync(...);

Http::optionsAsync(...);

非同步併發請求

use Gouguoyin\EasyHttp\Response;
use Gouguoyin\EasyHttp\RequestException;

$promises = [
    Http::getAsync('http://easyhttp.gouguoyin.cn/api/sleep3.json'),
    Http::getAsync('http1://easyhttp.gouguoyin.cn/api/sleep1.json', ['name' => 'gouguoyin']),
    Http::postAsync('http://easyhttp.gouguoyin.cn/api/sleep2.json', ['name' => 'gouguoyin']),
];

Http::concurrency(10)->multiAsync($promises, function (Response $response, $index) {
    echo "發起第 $index 個非同步請求,請求時長:" . $response->json()->second . '秒' . PHP_EOL;
}, function (RequestException $e, $index) {
    echo "發起第 $index 個請求失敗,失敗原因:" . $e->getMessage() . PHP_EOL;
});

//輸出
發起第 1 個請求失敗,失敗原因:cURL error 1: Protocol "http1" not supported or disabled in libcurl (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
發起第 2 個非同步請求,請求時長:2 秒
發起第 0 個非同步請求,請求時長:3

如果未呼叫concurrency()方法,併發次數預設為$promises的元素個數,$promises陣列裡必須是非同步請求

使用響應

發起請求後會返回一個 Gouguoyin\EasyHttp\Response $response的例項,該例項提供了以下方法來檢查請求的響應:

$response->body() : string;
$response->json() : object;
$response->array() : array;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->headers() : array;
$response->header($header) : string;

異常處理

請求在發生客戶端或服務端錯誤時會丟擲 Gouguoyin\EasyHttp\RequestException $e異常,該例項提供了以下方法來返回異常資訊:

$e->getCode() : int;
$e->getMessage() : string;
$e->getFile() : string;
$e->getLine() : int;
$e->getTrace() : array;
$e->getTraceAsString() : string;

更新日誌

2020-03-30

  • 修復部分情況下IDE不能智慧提示的BUG
  • get()、getAsync()方法支援帶引數的url
  • 新增withUA()方法
  • 新增withStream()方法
  • 新增asMultipart()方法,attach()的別名
  • 新增multiAsync()非同步併發請求方法

2020-03-20

  • 新增非同步請求getAsync()方法
  • 新增非同步請求postAsync()方法
  • 新增非同步請求patchAsync()方法
  • 新增非同步請求putAsync()方法
  • 新增非同步請求deleteAsync()方法
  • 新增非同步請求headAsync()方法
  • 新增非同步請求optionsAsync()方法

Todo List

  • 非同步請求
  • 併發請求
  • 重試機制
  • 支援http2
  • 支援swoole
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章