大家好,我是码农先森。

说到 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 请求的使用姿势的更多相关文章

  1. SpringMVC学习系列-后记 解决GET请求时中文乱码的问题

    SpringMVC学习系列-后记 解决GET请求时中文乱码的问题 之前项目中的web.xml中的编码设置: <filter> <filter-name>CharacterEnc ...

  2. 【深入ASP.NET原理系列】--ASP.NET请求管道、应用程序生命周期、整体运行机制

    微软的程序设计和相应的IDE做的很棒,让人很快就能有生产力..NET上手容易,生产力很高,但对于一个不是那么勤奋的人,他很可能就不再进步了,没有想深入下去的动力,他不用去理解整个框架和环境是怎么执行的 ...

  3. SpringBoot系列教程web篇之Post请求参数解析姿势汇总

    作为一个常年提供各种Http接口的后端而言,如何获取请求参数可以说是一项基本技能了,本篇为<190824-SpringBoot系列教程web篇之Get请求参数解析姿势汇总>之后的第二篇,对 ...

  4. SpringBoot系列教程web篇之Get请求参数解析姿势汇总

    一般在开发web应用的时候,如果提供http接口,最常见的http请求方式为GET/POST,我们知道这两种请求方式的一个显著区别是GET请求的参数在url中,而post请求可以不在url中:那么一个 ...

  5. Spring框架系列(5) - 深入浅出SpringMVC请求流程和案例

    前文我们介绍了Spring框架和Spring框架中最为重要的两个技术点(IOC和AOP),那我们如何更好的构建上层的应用呢(比如web 应用),这便是SpringMVC:Spring MVC是Spri ...

  6. 程序员节应该写博客之.NET下使用HTTP请求的正确姿势

    程序员节应该写博客之.NET下使用HTTP请求的正确姿势 一.前言 去年9月份的时候我看到过外国朋友关于.NET Framework下HttpClient缺陷的分析后对HttpClient有了一定的了 ...

  7. .NET下使用HTTP请求的正确姿势

    来源:Lewis.Zou cnblogs.com/modestmt/p/7724821.html 一.前言 去年9月份的时候我看到过外国朋友关于.NET Framework下HttpClient缺陷的 ...

  8. SpringBoot系列教程JPA之新增记录使用姿势

    SpringBoot系列教程JPA之新增记录使用姿势 上一篇文章介绍了如何快速的搭建一个JPA的项目环境,并给出了一个简单的演示demo,接下来我们开始业务教程,也就是我们常说的CURD,接下来进入第 ...

  9. SpringBoot 系列教程之编程式事务使用姿势介绍篇

    SpringBoot 系列教程之编程式事务使用姿势介绍篇 前面介绍的几篇事务的博文,主要是利用@Transactional注解的声明式使用姿势,其好处在于使用简单,侵入性低,可辨识性高(一看就知道使用 ...

  10. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

随机推荐

  1. rubymineIDE配置启动

    debug启动 debug启动 安装插件 报错: 网络问题 下载 ruby-debug-ide-2.3.1 解压到 /home/haima/.rvm/gems/ruby-2.3.8/gems/

  2. linux下nginx安装和配置

    一.软件安装 1.环境说明 操作系统:CentOS 7.4 64位 nginx版本:1.16.1 安装日期:2019/10/01 安装用户:root 2.安装运行库 yum -y install gc ...

  3. C#实现多线程的几种方式

    前言 多线程是C#中一个重要的概念,多线程指的是在同一进程中同时运行多个线程的机制.多线程适用于需要提高系统并发性.吞吐量和响应速度的场景,可以充分利用多核处理器和系统资源,提高应用程序的性能和效率. ...

  4. DOMRect对象

    DOMRect 表示的盒子的类型由返回它的方法或属性指定.例如,WebVR API 的 VREyeParameters.renderRect (en-US) 指定了头戴式显示器的一只眼睛应该呈现的影像 ...

  5. Python 潮流周刊#50:我最喜欢的 Python 3.13 新特性!

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  6. URP(Universal Render Pipeline)渲染管线在使用中的一些分享

    本篇文章整理了URP管线使用中的一些简单的心得记述 1.使用ScriptableRendererFeature自定义渲染特性 在内建(Build-in)管线中可以使用CommandBuffer并添加到 ...

  7. SQLServer统计监控SQL执行计划突变的方法

    使用动态管理视图(DMVs)来检测SQL执行计划的突变,你需要关注那些能够提供查询执行统计和计划信息的视图.以下是一些可以用于此目的的DMVs以及相应的查询示例: sys.dm_exec_query_ ...

  8. C语言:send + more = money,单词相加求解字母数字谜问题

    我用的是穷举法,虽然有点笨,但是在想不到其他更好的方法对我而言就是穷举法. 有程序员大大想到其他方法也可以私信我一起探讨一下~ #include<stdio.h> int main() { ...

  9. .NET6 Minimal API 集成Autofac

    前提 集成Autofac前需要先添加两个依赖包 可以通过 NuGet 进行安装,使用以下命令: dotnet add package Autofac dotnet add package Autofa ...

  10. 开源Blazor UI组件库精选:让你的Blazor项目焕然一新!

    今天给大家推荐一些开源.美观的Blazor UI组件库,这些优秀的开源框架和项目不仅能够帮助开发者们提高开发效率,还能够为他们的项目带来更加丰富的用户体验. 注:排名不分先后,都是十分优秀的开源框架和 ...