PHP转Go系列 | GET 和 POST 请求的使用姿势

php,go,get,post · 浏览次数 : 11

小编点评

HTTP 请求工具在 Web 开发中扮演着重要的角色,无论是 PHP 还是 Go 语言,都有相应的工具包可以实现 HTTP 请求。在 PHP 中,GuzzleHttp 是一个非常流行的 HTTP 请求库,而在 Go 语言中,官方提供的 net/http 包也足以满足日常开发需求。 在 PHP 中使用 GuzzleHttp,首先需要通过 Composer 命令安装,然后在代码中通过 GuzzleHttp\Client 类发起 GET 和 POST 请求。异常捕获可以使用 try-catch 语句。而在 Go 语言中,需要导入 net/http 和 encoding/json 包,定义 http.Client 结构体对象,然后调用 client.Get() 或 client.Post() 方法发起请求。响应数据体需要使用 ioutil.ReadAll() 方法读取,并注意关闭资源。 总体来说,PHP 和 Go 语言的 HTTP 请求工具都非常强大,选择哪种语言取决于项目需求和个人喜好。掌握 Header 头参数的配置是使用 HTTP 工具的关键,希望本文的介绍能够帮助大家更好地理解和使用这些工具。

正文

大家好,我是码农先森。

说到 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系列 | GET 和 POST 请求的使用姿势相似的内容:

PHP转Go系列 | GET 和 POST 请求的使用姿势

大家好,我是码农先森。 说到 HTTP 请求工具想必对我们做 Web 开发的程序员都不陌生,只要涉及到网络请求都必须使用。对于我们 PHP 程序员来说,最熟悉不过的就是 CURL 扩展,只要安装的这个扩展便可随意发起 HTTP 请求。 但在 PHP 语言中还有一个很好用的 Composer 包「gu

PHP 程序员转 Go 语言的经历分享

大家好,我是码农先森。 之前有朋友让我分享从 PHP 转 Go 的经历,这次它来了。我主要从模仿、进阶、应用这三个方面来描述转 Go 的经历及心得。模仿是良好的开端,进阶是艰难的成长,应用是认知的提升。希望我的经历对大家能有所启发。 模仿 著名艺术家毕加索说过「模仿是人类一切学习的开端,然后才是创新

[转帖]@nginx多server及使用优化(php)

文章目录​ ​一、nginx多server优先级​​​ ​二、禁止IP访问页面​​​ ​三、nginx的包含include​​​ ​四、nginx 路径的alias和root​​​ ​1.配置​​​ ​2.总结​​​ ​五、nginx的try_files​​​ ​1.配置try_files​​​ ​

[转帖]PAM4技术

http://www.xc66.cc/baike/view.php?id=b9f94c77652c9a76fc8a442748cd54bd PAM4技术本质是一种更高效的调制技术,可以有效提升带宽利用效率。 中文全称:四阶脉冲幅度调制 英文全称:Pulse Amplitude Modulation

[转帖]CDMA

http://www.xc66.cc/baike/view.php?id=3c1e4bd67169b8153e0047536c9f541e 学习之 收藏 | 点赞(0) | 踩(0) | | | 编辑 码分多址(CDMA)是在数字技术的分支--扩频通信技术上发展起来的一种崭新而成熟的无线通信技术。

[转帖]光刻技术

http://www.xc66.cc/baike/view.php?id=97d0145823aeb8ed80617be62e08bdcc 光刻技术为一种精密的微细加工技术。 中文全称:光刻技术 英文全称:Photetch 光刻技术是现代半导体、微电子、信息产业的基础,光刻技术直接决定了这些技术的发

[转帖]丢包

http://www.xc66.cc/baike/view.php?id=712a3c9878efeae8ff06d57432016ceb 丢包指数据包由于各种原因在信道中丢失的现象。 中文全称:丢包 英文全称:Packet loss 简称:Packet loss 简介:丢包(Packet loss

[转帖]骨干网

http://www.xc66.cc/baike/view.php?id=ef2a4be5473ab0b3cc286e67b1f59f44 骨干网(Backbone Network)是用来连接多个区域或地区的高速网络。每个骨干网中至少有一个和其他骨干网进行互联互通的连接点。不同的网络供应商都拥有自己

[转帖]光模块的命名规则

http://www.xc66.cc/baike/view.php?id=15231a7ce4ba789d13b722cc5c955834 了解光模块命名规则才能读懂厂商光模块产品名称所包含的全部信息。 中文全称:光模块命名规则 今天博创科技推出了高性价比的400G数据通信硅光模块解决方案:400G

[转帖]波特率/比特率

http://www.xc66.cc/baike/view.php?id=375c71349b295fbe2dcdca9206f20a06 中文全称:波特率/比特率 最近常看文章中有提到PAM技术(pulse amplitude modulation),即脉冲幅度调制。信号编码在脉冲的幅度上,由于幅