百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

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

myzbx 2025-06-04 00:03 41 浏览

我是 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三目运算符不见了。


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

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...