首页 > 编程语言 >PHP转Go系列 | GET 和 POST 请求的使用姿势

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

时间:2024-07-01 09:33:46浏览次数:22  
标签:http 请求 GET go Go HTTP POST PHP

大家好,我是码农先森。

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

推荐


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

标签:http,请求,GET,go,Go,HTTP,POST,PHP
From: https://www.cnblogs.com/yxhblogs/p/18267989

相关文章

  • MongoDB 查看慢查询级别及慢查询日志
    MongoDB慢查询记录功能简介如何定位MongoDB数据库的慢查询,我想应该是很多刚使用MongoDB数据库的朋友最想知道的问题。通过慢查询的定位,可以辅助对MongoDB中的collection进行优化。MongoDB数据库的慢查询数据其实存放在一个数据库集合(collection)中(system.profile......
  • Go:深入解析internal/race包,数据竞争检测的
    Go:深入解析internal/race包,数据竞争检测的利器原创 王义杰 AI学者王义杰 2024-05-1721:14 广东 1人听过在Go语言中,internal/race 包是用于支持数据竞争检测的内部包。数据竞争(datarace)是并发编程中常见且棘手的问题,通常发生在多个goroutine并发访问共享变量且......
  • 【使用sudo apt-get出现报错】——无法获得锁 /var/lib/dpkg/lock-open(11:资 源暂时
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、ubuntu中进程正在被占用1.问题描述2.原因分析3.解决总结前言一、ubuntu中进程正在被占用1.问题描述在Ubuntu中,使用终端时输入带有sudoapt-get指令更新软件包时,出现如下的报......
  • webrtc 的datachannel在golang中的使用
    因为在发送端需要接收一些接收端的统计信息,而且具有不可丢失的需求,所以采取利用datachannel进行传输。datachannel是基于sctp协议的传输通道,sctp可提供按需可靠到达的服务,在datachannel中可以设置是否按序,是否可靠,最大重传次数,数据最大保存时间(当数据超过保存时间仍未发出时将被丢......
  • 【转】Androidstudio报错Algorithm HmacPBESHA256 not available
     删除debug.keystone这个文件就可以了。 https://blog.csdn.net/O_PUTI/article/details/138227534 -----参考了更改GradleJDK等的办法都没有用,最终通过一个一个问题拍错解决。第一个问题:版本不一致 第二个问题秘钥获取不成功:删除这个文件 然后就编译成功了。......
  • Django数据库
    一、MySQL驱动程序安装我们使用Django来操作MySQL,实际上底层还是通过python来操作的。因此我们想要用Django来操作MySQL,首先还是需要安装一个驱动程序。在Python3中,驱动程序有多种选择。比如pymysql以及mysqlclient等。这里我们就使用mysqlclient来操作。mysqlclient安装非常简单......
  • PostgreSQL的系统视图pg_statio_all_indexes
    PostgreSQL的系统视图pg_statio_all_indexes在PostgreSQL数据库中,pg_statio_all_indexes视图提供了有关所有索引的I/O活动的统计信息。这些统计信息对于了解索引的使用情况和性能调优非常有帮助。pg_statio_all_indexes视图的结构以下是pg_statio_all_indexes视......
  • Golang文件操作
    文件是数据源(保存数据的地方)的一种,word文档,txt文件,excel文件...都是文件。文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保持视频,声音...os.file封装了所有对文件的操作,且file是一个结构体: 打开和关闭文件1.打开文件,用于读取: 传入的是一个字符......
  • 基于Python+Django的商城购物系统设计与实现(源码+数据库+讲解)
    文章目录前言详细视频演示项目运行截图技术框架后端采用Django框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • Django 笔记 - Django Shell
    启动DjangoShell交互式界面,具体命令如下:pythonmanage.pyshell具体实例实例1.直接修改用户密码,无需原密码。在DjangoShell交互式界面下,修改admin用户密码的具体代码如下:fromdjango.contrib.auth.modelsimportUseruser=User.objects.get(username='admin'......