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

news2025/1/16 16:09:47

大家好,我是码农先森。

说到 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 的官方文档附上,方便大家更加深入的学习。

  • https://guzzle-zh-cn.readthedocs.io/
  • https://studygolang.com/static/pkgdoc/pkg/net_http.htm

推荐

  • PHP转Go系列 | 变量常量的使用姿势
  • PHP转Go系列 | 字符串的使用姿势
  • PHP转Go系列 | 数组切片的使用姿势
  • PHP转Go系列 | 条件循环的使用姿势
  • PHP转Go系列 | 类结构体的使用姿势
  • PHP转Go系列 | ThinkPHP与Gin的使用姿势
  • 基于 GoLang 实现的 IOT 物联网在线直播抓娃娃企业级项目

欢迎关注、分享、点赞、收藏、在看,我是微信公众号「码农先森」作者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1881673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Transformer常见面试题

目录 1.Transformer为何使用多头注意力机制&#xff1f;&#xff08;为什么不使用一个头&#xff09; 2.Transformer为什么Q和K使用不同的权重矩阵生成&#xff0c;为何不能使用同一个值进行自身的点乘&#xff1f; &#xff08;注意和第一个问题的区别&#xff09; 3.Transf…

React+TS前台项目实战(二十二)-- 全局常用导出组件Export封装

文章目录 前言Export组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天我们来封装一个带导出图标的导出组件。 Export组件 1. 功能分析 通过传入链接地址&#xff0c;规定要跳转的导出页面&#xff0c;或是直接通过链接导出数据 2. 代码详细注释 // /c…

产品中心|高效能双处理器Xilinx FPGA 4通道射频收发板卡

1、产品概述 基于Xilinx XC7K325T芯片的4通道射频收发板卡&#xff0c;搭载高能效Cortex-A8内核处理器、1组16bit/2GB DDR3及1组4GB DDR3、 1组2GB Nand Flash、1路USB接口、4路高速ADC、4路高速DAC&#xff0c;支持外触发&#xff0c;外时钟。用于FPGA程序加载板卡工作温度范…

前端开发中实用小技巧

运行javascript小技巧 // 1.直接在浏览器的地址栏中输入一下代码&#xff1a;javascript:alert(hello world) // 2.注意事项ie和chrom回自动去掉开头的 【javascript:】需要手动添加火狐浏览器不支持这个技巧 // 3.场景快速测试一段js代码运行HTML代码的神奇技巧 // 1.直接在…

TensorFlow安装CPU版本和GPU版本

文章目录 前言一、TensorFlow安装CPU版本1.新建虚拟环境2.激活虚拟环境3.下载tensorflow4.验证是否下载成功 二、TensorFlow安装GPU版本1.新建虚拟环境2.激活虚拟环境3.安装tensorflow-gpu4.验证是否下载成功 前言 下载的Anaconda是Anaconda3-2024.02-1-Windows-x86_64版本 一…

firewalld防火墙转发流量到其他端口forward port rules

假设云主机eth0: 47.93.27.106 tun0: inet 10.8.0.1 netmask 255.255.255.0 Show rules for a specific zone (public) sudo firewall-cmd --zonepublic --list-all Add the tun0 interface to the public zone: sudo firewall-cmd --zonepublic --add-interfacetun0 --…

MTK7621交换芯片配置

MTK7621上自带的交换芯片为mt7530 admin@OpenWrt:~# /sbin/swconfig list Found: switch0 - mt7530 交换芯片的配置工具为swconfig程序。MTK7621采用内部的MDIO(Management Data Input/Output)接口管理MT7530的switch芯片。 MT7530共有7个物理口,通过/sbin/swconfig dev …

isupper()方法——判断字符串是否全由大写字母组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 isupper()方法用于判断字符串中所有的字母是否都是大写。isupper()方法的语法格式如下&#xff1a; str.isupper() 如果字符串中包含至少…

linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透

文章目录 写在前面实现Linux的内网穿透1、官网账号注册2、在Linux部署我们自己的项目3、一键自动下载安装cpolar4、设置自己的token5、启动cpolar服务6、MySQL穿透测试 卸载方法 写在前面 相信很多小伙伴在本地搭建了一个MySQL数据库&#xff0c;想让其他同事或者合作者一起使…

【AI大模型】跌倒监控与健康:技术实践及如何改变未来

文章目录 1. **背景与意义**2. **关键技术与方法**2.1 传感器数据融合2.2 深度学习模型2.3 行为模式识别2.4 预测与预防 3. **应用场景**3.1 老年人跌倒预警3.2 康复患者监测3.3 高风险职业防护 4. **实践案例**案例1&#xff1a;某老年社区的跌倒预警系统案例2&#xff1a;康复…

【FreeRTOS】空闲任务

目录 空闲任务及其钩子函数介绍使用钩子函数的前提 实际操作任务如何退出&#xff1f;IDLE函数 空闲任务及其钩子函数 介绍 空闲任务(Idle任务)的作用之一&#xff1a;释放被删除的任务的内存。 除了上述目的之外&#xff0c;为什么必须要有空闲任务? 这是一个良好的程序&…

使vim创建.sh文件时自动添加头部描述信息

目录 需求解决方案vimrc配置文件常见选项 修改vimrc功能解释 效果 需求 在编写shell脚本时&#xff0c;为了便于后续阅读或修改或SOP需求&#xff0c;我们常常会在shell脚本前添加一些描述信息&#xff0c;用于标注其作用和shell版本&#xff0c;例如&#xff1a; #!/bin/bas…

mongodb在windows环境安装部署

一、mongodb 1.释义 MongoDB 是一种开源的文档型 NoSQL 数据库管理系统&#xff0c;使用 C 编写&#xff0c;旨在实现高性能、高可靠性和易扩展性。MongoDB 采用了面向文档的数据模型&#xff0c;数据以 JSON 风格的 BSON&#xff08;Binary JSON&#xff09;文档存储&#x…

Android经典面试题之Glide的缓存大揭秘

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 Glide缓存 关联类&#xff1a;Engine、LruResourceCache、LruCache、ActiveResources ActiveResources&#xff1a;弱引用缓存池 VisibleForTe…

React-Native优质开源项目

React Native 是一个由 Facebook 开发的开源框架&#xff0c;允许开发者使用 JavaScript 和 React 来构建原生移动应用。它允许开发者编写一次代码&#xff0c;然后可以在 iOS 和 Android 平台上运行&#xff0c;而无需为每个平台单独编写代码。以下是 React Native 的一些关键…

现代信息检索笔记(二)——布尔检索

目录 信息检索概述 IR vs数据库: 结构化vs 非结构化数据 结构化数据 非结构化数据 半结构化数据 传统信息检索VS现代信息检索 布尔检索 倒排索引 一个例子 建立词项&#xff08;可以是字、词、短语、一句话&#xff09;-文档的关联矩阵。 关联向量 检索效果的评价 …

ESP32-C3(基本信息)

ESP32-C3 是一款低功耗、高集成度的 MCU 系统级芯片 (SoC)&#xff0c;它集成了 2.4 GHz Wi-Fi 和低功耗蓝牙 (Bluetooth LE) 无线通信功能&#xff0c;并拥有丰富的外设接口和先进的电源管理机制。 主要特性&#xff1a; 无线通信&#xff1a; 支持 2.4 GHz Wi-Fi (802.11b/…

JVM(13):虚拟机性能分析和故障解决工具之Visual VM

1 Visual VM作用 是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序&#xff0c;并且可以遇见在未来一段时间内都是官方主力发展的虚拟机故障处理工具。官方在VisualVM的软件说明中写上了“All-in-One”的描述字样&#xff0c;预示着他除了运行监视、故障处理外&…

SpringBoot实现文章点赞功能

提示&#xff1a;今日是2024年的6月30日&#xff0c;未来的你看到这篇文章&#xff0c;希望你依旧快乐 文章目录 前言 首先在这里前缀部分我就不做要求了,比如说登录信息什么的 数据库表格 这里实现点赞功能&#xff0c;主要是围绕论坛项目完成的 user_info代表用户信息表 for…

动态系统开发方法(DSDM): 基于RAD的全面指导与管理

目录 前言1. 动态系统开发方法概述1.1 DSDM的起源与背景1.2 DSDM的核心理念 2. DSDM的关键原则2.1 用户主动参与2.2 频繁交付2.3 时间盒管理2.4 高效的合作 3. DSDM的主要阶段3.1 可行性研究阶段3.2 业务研究阶段3.3 原型开发阶段3.4 设计与构建阶段3.5 部署阶段3.6 维护与支持…