如何从 PHP 过渡到 Golang?(php转go需要多久)

365bet官网在线 🖌️ 2025-08-27 15:28:11 🎨 admin 👁️ 3030 ❤️ 410
如何从 PHP 过渡到 Golang?(php转go需要多久)

我是 PHP 开发者,转 Go 两个月了吧,记录一下使用Golang怎么一步步开发新项目。

本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去摸索,我也表示很无奈。项目只需要提供api,所以狠狠地百度了一下,决定选用Gin框架,数据库选用的是MySql所以orm框架使用的Gorm,Redis使用的是Go-redis。

1.初始化框架:

go mod init gin

go get -u github.com/gin-gonic/gin

2.安装Gorm

go get -u github.com/jinzhu/gorm

3.安装Go-redis

go get -u github.com/go-redis/redis

4.本着mvc思想,创建项目基本目录:

config 配置文件

controllers 控制器

core 核心文件

logics 逻辑处理封装

models sql处理

routers 路由

以上是初始化开发项目的整个流程,第一次开发拼装框架有点麻烦,但是以后就顺手多了。现在我们来封装一下Mysql连接和Redis连接:

Mysql连接:

var db *gorm.DB

func Connection() (*gorm.DB) {

db, err := gorm.Open("mysql",conf.DbUser + ":" + conf.DbPassword + "@(" + conf.DbHost + ":" + conf.DbPort + ")/" + conf.DbName + "?charset=utf8mb4&parseTime=True&loc=Local")

// gorm1禁用表名加s方法

db.SingularTable(true)

db.LogMode(true)

db.SetLogger(tools.Logger())

db.DB().SetMaxIdleConns(10)

db.DB().SetMaxOpenConns(100)

if err != nil {

panic(err)

}

return db

}Redis连接:

var RedisClient *redis.Client

func init(){

NewClient()

}

func NewClient() *redis.Client {

if RedisClient != nil {

return RedisClient

}

RedisClient = redis.NewClient(&redis.Options{

Addr: conf.RedisAddr,

Password: conf.RedisPassword,

DB: conf.RedisDb,

})

_, err := RedisClient.Ping().Result()

if err != nil {

//logs.Error("redis connection failed: ", err.Error())

}

return RedisClient

}

func RedisSet(key string, value interface{}, expire int) error {

if expire > 0 {

err := RedisClient.Do("SET", key, value, "EX", expire).Err()

if err != nil {

//logs.Error("RedisSet Error! key:", key, "Details:", err.Error())

return err

}

} else {

err := RedisClient.Do("SET", key, value).Err()

if err != nil {

//logs.Error("RedisSet Error! key:", key, "Details:", err.Error())

return err

}

}

return nil

}

func RedisKeyExists(key string) (bool, error) {

ok, err := RedisClient.Do("EXISTS", key).Bool()

return ok, err

}

func RedisGet(key string) (string, error) {

value, err := RedisClient.Do("GET", key).String()

if err != nil {

return "", nil

}

return value, nil

}

func RedisDel(key string) error {

err := RedisClient.Do("DEL", key).Err()

if err != nil {

//logs.Error("RedisDel Error! key:", key, "Details:", err.Error())

}

return err

}下面我展示一下api的demo:

controllers:

// 获取列表

func GetBannerList(c*gin.Context){

maps := make(map[string]interface{})

// 页码

page,_ := strconv.Atoi(c.DefaultQuery("page","1"))

types,_ := strconv.Atoi(c.DefaultQuery("type","1"))

size := 15

maps["type"] = types

total := models.GetBannerWhereCount(maps)

pages := math.Ceil(float64(total) / float64(size))

data := models.GetBannerWhereList(page,size,maps)

var ViewBanners []models.ViewBanner

var viewBanner models.ViewBanner

for _,value := range data{

Pid, _ := strconv.Atoi(value.Pid)

arr := models.GetRowAdminUser(Pid,"")

if len(arr) == 0{

continue

}

viewBanner.ID = value.ID

viewBanner.Img = value.Img

viewBanner.Type = value.Type

viewBanner.Abstract = value.Abstract

viewBanner.UpdateTime = value.UpdateTime

viewBanner.Status = value.Status

viewBanner.PUserName = arr[0].Account

ViewBanners = append(ViewBanners,viewBanner)

}

c.JSON(http.StatusOK,gin.H{

"code" : 200,

"message" : "SUCCESS!",

"data" : ViewBanners,

"page" : page,

"pages" : pages,

})

}models:

type Banner struct {

ID int `json:"id"`

Type int `json:"type"`

Img string `json:"img"`

Abstract string `json:"abstract"`

Status int `json:"status"`

Pid string `json:"pid"`

CreateTime string `json:"create_time"`

UpdateTime string `json:"update_time"`

}

type ViewBanner struct {

ID int `json:"id"`

Type int `json:"type"`

Img string `json:"img"`

Abstract string `json:"abstract"`

PUserName string `json:"p_user_name"`

UpdateTime string `json:"update_time"`

Status int `json:"status"`

}

// 获取数量

func GetBannerWhereCount(maps interface{}) (count int) {

var db = core.Connection()

db = db.Model(Banner{}).Where(maps).Count(&count)

return

}

// 获取列表

func GetBannerWhereList(Page int,PageSize int,maps interface{}) (banner []Banner) {

var db = core.Connection()

db = db.Model(Banner{}).Where(maps).Offset((Page - 1) * PageSize).Limit(PageSize).Find(&banner)

return

}routers:

r.GET("/banner/getlist",Admin.GetBannerList)直到开发这个程度的时候,我们总结一下Golang与PHP的差异:

1.弱类型语言(PHP7有类型限制,array很强大)上述两个方面带来的好处就是降低编程门槛,可以用较少的代码实现我们想要的功能。问题就是如果不遵循一定的编程规范,代码比较飘逸,可维护降低,另外由于要维护较为灵活的结构内存占用也会较大。

golang有较为严谨的语言风格检测,迫使我们统一风格,同时强类型使得我们编程的时候更加注重数据结构的设计,对于系统设计我的理解是有帮助的,当然也不那么易用。

2.Golang无第三方扩展,某些项目不提供PHP的扩展,在这方面可以选择自己封装(有一定维护成本)或者选择其他同类型的开源项目,问题不是太大。

3.Golang很多地方扩展采用多返回参数的形式返回error,时刻提醒开发者要关心异常,做好异常处理。

4.Golang三目运算符不见了。

由于自己是小白,有些写得不对的或者可优化的欢迎大家指出。

相关文章

全新华为 P8回收价格查询估价-全新手机回收
365bet网上足球比赛

全新华为 P8回收价格查询估价-全新手机回收

📅 08-18 👁️ 4187
侠盗联盟
365bet网上足球比赛

侠盗联盟

📅 07-12 👁️ 7434
美图T9怎么样?美图T9手机全面评测
365bet网上足球比赛

美图T9怎么样?美图T9手机全面评测

📅 07-21 👁️ 9827