PHP转Go系列 | GET 和 POST 请求的使用姿势
大家好,我是码农先森。
说到 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 请求的使用姿势的更多相关文章
- SpringMVC学习系列-后记 解决GET请求时中文乱码的问题
SpringMVC学习系列-后记 解决GET请求时中文乱码的问题 之前项目中的web.xml中的编码设置: <filter> <filter-name>CharacterEnc ...
- 【深入ASP.NET原理系列】--ASP.NET请求管道、应用程序生命周期、整体运行机制
微软的程序设计和相应的IDE做的很棒,让人很快就能有生产力..NET上手容易,生产力很高,但对于一个不是那么勤奋的人,他很可能就不再进步了,没有想深入下去的动力,他不用去理解整个框架和环境是怎么执行的 ...
- SpringBoot系列教程web篇之Post请求参数解析姿势汇总
作为一个常年提供各种Http接口的后端而言,如何获取请求参数可以说是一项基本技能了,本篇为<190824-SpringBoot系列教程web篇之Get请求参数解析姿势汇总>之后的第二篇,对 ...
- SpringBoot系列教程web篇之Get请求参数解析姿势汇总
一般在开发web应用的时候,如果提供http接口,最常见的http请求方式为GET/POST,我们知道这两种请求方式的一个显著区别是GET请求的参数在url中,而post请求可以不在url中:那么一个 ...
- Spring框架系列(5) - 深入浅出SpringMVC请求流程和案例
前文我们介绍了Spring框架和Spring框架中最为重要的两个技术点(IOC和AOP),那我们如何更好的构建上层的应用呢(比如web 应用),这便是SpringMVC:Spring MVC是Spri ...
- 程序员节应该写博客之.NET下使用HTTP请求的正确姿势
程序员节应该写博客之.NET下使用HTTP请求的正确姿势 一.前言 去年9月份的时候我看到过外国朋友关于.NET Framework下HttpClient缺陷的分析后对HttpClient有了一定的了 ...
- .NET下使用HTTP请求的正确姿势
来源:Lewis.Zou cnblogs.com/modestmt/p/7724821.html 一.前言 去年9月份的时候我看到过外国朋友关于.NET Framework下HttpClient缺陷的 ...
- SpringBoot系列教程JPA之新增记录使用姿势
SpringBoot系列教程JPA之新增记录使用姿势 上一篇文章介绍了如何快速的搭建一个JPA的项目环境,并给出了一个简单的演示demo,接下来我们开始业务教程,也就是我们常说的CURD,接下来进入第 ...
- SpringBoot 系列教程之编程式事务使用姿势介绍篇
SpringBoot 系列教程之编程式事务使用姿势介绍篇 前面介绍的几篇事务的博文,主要是利用@Transactional注解的声明式使用姿势,其好处在于使用简单,侵入性低,可辨识性高(一看就知道使用 ...
- Alamofire源码解读系列(十二)之请求(Request)
本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...
随机推荐
- uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈
原创研发uniapp+vue3+pinia2跨三端仿微信app聊天模板Uniapp-Wechat. uni-vue3-wchat基于uni-app+vue3+pinia2+uni-ui+uv-ui等技 ...
- 微服务 - 作业调度 · Hangfire集成式 · 仪表盘 · DolphinScheduler分布式 · 定义流程
系列目录 微服务 - 1.概念 · 应用 · 架构 · 通讯 · 授权 · 跨域 · 限流 微服务 - 2.IdentityServer4认证授权 · 概念认识 · 运行过程 · 实践应用 微服务 - ...
- 04. C语言数据使用方式
[C语言简介] 计算机的运行由CPU指令控制,为了让计算机执行指定功能,需要将这些功能对应的指令数据集中存储在一起,制作为一个计算机文件,这个文件称为程序,CPU通过读取程序中的指令确定要执行的功能, ...
- 腾讯、阿里、B站最新面经汇总,有的妥妥的凉经
除了BAT(没错我说的B是B站的B),还有网易.希音科技.美柚等中小厂的最新面经. 这次投稿的同学行文幽默风趣,处处透漏着不成功便搞笑的骚气. 祝他早日上岸,也欢迎大家在评论区讨论这些面试题,有哪些面 ...
- sass 混合指令 (Mixin Directives)详解
混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left.混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变 ...
- GeminiDB PITR,让游戏回档“进退自如”!
本文分享自华为云社区<GeminiDB PITR,让游戏回档"进退自如"!>,作者:GaussDB 数据库. 在实际业务场景中,客户数据库难免会出现数据损毁.数据丢失. ...
- CAD 标注镜像
在代码里用镜像矩阵对标注进行镜像的时候,标注上面的文字也会被镜像掉,我在网上得到一个方法,可以解决这个问题.https://forums.autodesk.com/t5/net/dbtext-and- ...
- Java中枚举类的深入理解
概述 在此之前由于个人在学习和开发中对枚举类的应用较少,所以对枚举类的知识点并没进行深入的了解,但最近写代码中突然想到了枚举类,抱着完善自身的知识的目的,就较为深入的了解了Java中的枚举类. 我在学 ...
- go语言开发的内网穿透工具,frp.
转载自:https://www.appinn.com/frp/ 什么是 Frp? 内网穿透工具有很多,其中 Frp (Fast Reverse Proxy) 是比较流行的一款.FRP 是一个免费开源的 ...
- Understanding Swift’s value type thread safety - 代码分析(二)
示范代码 ` func testScenarioA2() throws { var store: Int = 100 DispatchQueue.concurrentPerform(iteration ...