大家好,我是碼農先森。 說到 HTTP 請求工具想必對我們做 Web 開發的程式員都不陌生,只要涉及到網路請求都必須使用。對於我們 PHP 程式員來說,最熟悉不過的就是 CURL 擴展,只要安裝的這個擴展便可隨意發起 HTTP 請求。 但在 PHP 語言中還有一個很好用的 Composer 包「gu ...
大家好,我是碼農先森。
說到 HTTP 請求工具想必對我們做 Web 開發的程式員都不陌生,只要涉及到網路請求都必須使用。對於我們 PHP 程式員來說,最熟悉不過的就是 CURL 擴展,只要安裝的這個擴展便可隨意發起 HTTP 請求。 但在 PHP 語言中還有一個很好用的 Composer 包「guzzlehttp/guzzle」,相信大家只要做 PHP 開發的都接觸過。
轉到 Go 語言後,有些人也會在想 Go 中有沒有這樣的工具包呢?說實話,我從事 Go 語言開發這麼挺久,也始終沒有發現有類似 guzzle 這麼好用的工具包。我想其中的原因可能是 Go 語言的官方標準庫中提供了「net/http」工具,這個也能滿足日常的開發需求,大家也就沒有想再造輪子的興趣了。話不多說,接下來我們開始介紹在 PHP 語言和 Go 語言中的使用姿勢。
在 php_http 目錄下中使用 Composer 命令安裝 guzzle 包。
[manongsen@root ~]$ pwd
/home/manongsen/workspace/php_to_go/php_http
[manongsen@root php_http]$ composer require guzzlehttp/guzzle
在 go_http 目錄下中使用 go mod init 初始化 Go 項目。
[manongsen@root ~]$ pwd
/home/manongsen/workspace/php_to_go/go_http
[manongsen@root go_http]$ go mod init go_http
這是初始化完成後的項目結構。
[manongsen@root php_to_go]$ tree -L 2
.
├── README.md
├── go_http
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── php_http
├── composer.json
├── composer.lock
├── index.php
└── vendor
這次我們主要介紹最常用的兩種請求方法,分別是 GET 請求和 POST 請求。
在 PHP 中先通過 require 載入到 GuzzleHttp 類庫,然後實例化 \GuzzleHttp\Client 類,並通過構造函數設置 base_uri 和 timeout 參數,再基於 $client 對象發起 GET 請求和 POST 請求,在使用過程中需要註意捕獲異常情況。
// php_to_go/php_http/index.php
<?php
require 'vendor/autoload.php';
try {
// 構建請求客戶端
$client = new GuzzleHttp\Client([
// 設置基礎的請求地址
'base_uri' => 'https://www.baidu.com',
// 設置超時時間
'timeout' => 3.0,
]);
// -----------------GET 請求-----------------------
$response = $client->request('GET', '/', [
'query' => ['wd' => 'php'] // 設置搜索參數
]);
// 獲取 HTTP 響應狀態碼
print_r($response->getStatusCode());
// 獲取 HTTP 響應數據體
print_r($response->getBody());
// -----------------POST 請求-----------------------
$response = $client->request('POST', '/', [
'json' => ['wd' => 'php'] // 設置搜索參數
]);
// 獲取 HTTP 響應狀態碼
print_r($response->getStatusCode());
// 獲取 HTTP 響應數據體
print_r($response->getBody());
} catch (GuzzleHttp\Exception\RequestException $e) {
// 捕獲請求異常
echo "Error: " . $e->getMessage();
}
從上面的代碼可以看出在 PHP 中發起 HTTP 請求使用起來還是很簡單的。那麼在 Go 中 GET 和 POST 的使用方法是怎樣的呢?從下麵的代碼量上來看就要多很多了,先要 import 相關的標準庫,比如 net/http、encoding/json 等。
其次定義一個 http.Client{} 結構體的對象,並且設置 HTTP 請求的超時時間。然後再調用 client.Get() 或 client.Post() 方法來發起 GET 及 Post 請求。最後再使用 ioutil.ReadAll 方法從 response.Body 網路數據流中讀取出 HTTP 請求體數據,讀取完數據之後要記得關閉資源。這裡需要註意的一點是 response.Body 網路數據流是不能重覆讀取,初學者這裡是容易犯錯的點。
// php_to_go/go_http/main.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
)
func main() {
// 定義 基礎的請求地址
baseUrl := "https://www.baidu.com"
// 創建一個 HTTP 客戶端
client := &http.Client{
Timeout: 3 * time.Second, // 設置超時時間為 3 秒
}
// ----------------------GET請求--------------------------
// 構建請求參數
params := url.Values{}
params.Add("wd", "go")
// 發起 GET 請求
response, err := client.Get(baseUrl + params.Encode())
if err != nil {
fmt.Printf("發起請求時出現錯誤: %v\n", err)
return
}
// 關閉資源 防止資源泄露
defer response.Body.Close()
// 讀取 HTTP 響應體數據
body, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("讀取響應時出現錯誤: %v\n", err)
return
}
// 輸出 HTTP 響應狀態碼
fmt.Printf("status: %v\n", response.Status)
// 輸出 HTTP 響應體數據
fmt.Printf("body: %v\n", string(body))
// ----------------------POST請求--------------------------
// 定義請求的參數
reqParams := map[string]string{
"wd": "go",
}
jsonData, err := json.Marshal(reqParams)
if err != nil {
fmt.Printf("JSON 編碼錯誤: %v", err)
return
}
// 創建一個新的位元組緩衝區並將 jsonData 數據放入緩存區
reqBody := bytes.NewBuffer(jsonData)
// 發起 POST 請求,請求的內容格式為 JSON 格式
response, err = client.Post(baseUrl, "application/json", reqBody)
if err != nil {
fmt.Printf("發起請求時出現錯誤: %v", err)
return
}
// 關閉資源 防止資源泄露
defer response.Body.Close()
// 讀取 HTTP 響應體數據
body, err = ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("讀取響應時出現錯誤: %v", err)
return
}
// 輸出 HTTP 響應狀態碼
fmt.Printf("status: %v\n", response.Status)
// 輸出 HTTP 響應體數據
fmt.Printf("body: %v\n", string(body))
}
從使用的角度來看 PHP 比 Go 要簡單的多,異常捕獲使用 try catch{} 即可,反觀 Go 中要通過 if != err {} 來反覆的判斷是否有錯誤,略顯繁瑣。同時在這個例子中也就可以看得出 php 的開發效率比 go 要快的多,go 中要時刻註意變數的類型、數據的讀取、資源的關閉等情況,php 則一梭子就開發完了。
但 Go 的執行效率可比 PHP 高的多,Go 作為靜態語言直接打包成了二進位可執行文件,而 PHP 是動態語言執行時才開始解析代碼。因此兩者剛好互補,學習 Go 也更利於我們 PHPer 瞭解系統資源、網路請求、緩存區等的使用方式,這些都是在 PHP 中很少能接觸到的。
對於 HTTP 工具的使用姿勢,其實最重要的是要掌握 Header 頭各種參數的配置,比如 Content-Type、Proxy、Authorization、Cookies、Cert 等,那麼我這裡在把 GuzzleHttp 和 net/http 的官方文檔附上,方便大家更加深入的學習。
推薦
- PHP轉Go系列 | 變數常量的使用姿勢
- PHP轉Go系列 | 字元串的使用姿勢
- PHP轉Go系列 | 數組切片的使用姿勢
- PHP轉Go系列 | 條件迴圈的使用姿勢
- PHP轉Go系列 | 類結構體的使用姿勢
- PHP轉Go系列 | ThinkPHP與Gin的使用姿勢
- 基於 GoLang 實現的 IOT 物聯網線上直播抓娃娃企業級項目
歡迎關註、分享、點贊、收藏、在看,我是微信公眾號「碼農先森」作者。