php和go语言哪个好前言
最近工作中遇到的一个场景,php项目中需要使用一个第三方的功能,而恰好有一个用Golang写好的类库 。那么问题就来了,要如何实现不同语言之间的通信呢?下面就来一起看看吧 。
常规的方案
1、 用Golang写一个http/TCP服务 , php通过http/TCP与Golang通信
2、将Golang经过较多封装,做为php扩展 。
3、PHP通过系统命令,调取Golang的可执行文件
存在的问题
1、http请求,网络I/O将会消耗大量时间
2、需要封装大量代码
3、PHP每调取一次Golang程序 , 就需要一次初始化,时间消耗很多
优化目标
1、Golang程序只初始化一次(因为初始化很耗时)
2、所有请求不需要走网络
3、尽量不大量修改代码
解决方案
1、简单的Golang封装,将第三方类库编译生成为一个可执行文件
2、PHP与Golang通过双向管道通信
使用双向管道通信优势
1:只需要对原有Golang类库进行很少的封装
2:性能最佳 (IPC通信是进程间通信的最佳途径)
3:不需要走网络请求,节约大量时间
4:程序只需初始化一次,并一直保持在内存中
具体实现步骤
1:类库中的原始调取demo
package main
import (
"fmt"
"github.com/yanyiwu/gojieba"
"strings"
)
func main() {
x := gojieba.NewJieba()
defer x.Free()
s := "小明硕士毕业于中国科学院计算所,后在日本京都大学深造"
words := x.CutForSearch(s, true)
fmt.Println(strings.Join(words, "/"))
}
保存文件为main.go,就可以运行
2:调整后代码为:
package main
import (
"bufio"
"fmt"
"github.com/yanyiwu/gojieba"
"io"
"os"
"strings"
)
func main() {
x := gojieba.NewJieba(
"/data/tmp/jiebaDict/jieba.dict.utf8",
"/data/tmp/jiebaDict/hmm_model.utf8",
"/data/tmp/jiebaDict/user.dict.utf8"
)
defer x.Free()
inputReader := bufio.NewReader(os.Stdin)
for {
s, err := inputReader.ReadString('\n')
if err != nilerr == io.EOF {
break
}
s = strings.TrimSpace(s)
if s != "" {
words := x.CutForSearch(s, true)
fmt.Println(strings.Join(words, " "))
} else {
fmt.Println("get empty \n")
}
}
}
只需要简单的几行调整,即可实现:从标准输入接收字符串,经过分词再输出
测试:
# go build test
# ./test
# //等待用户输入,输入”这是一个测试“
# 这是 一个 测试 //程序
3:使用cat与Golang通信做简单测试
//准备一个title.txt,每行是一句文本
# cat title.txt | ./test
正常输出,表示cat已经可以和Golang正常交互了
4:PHP与Golang通信
以上所示的cat与Golang通信,使用的是单向管道 。即:只能从cat向Golang传入数据 , Golang输出的数据并没有传回给cat , 而是直接输出到屏幕 。但文中的需求是:php与Golang通信 。即php要传数据给Golang,同时Golang也必须把执行结果返回给php 。因此,需要引入双向管道 。
在PHP中管道的使用:popen("/path/test"),具体就不展开说了,因为此方法解决不了文中的问题 。
双向管道:
$descriptorspec = array(
0 = array("pipe", "r"),
1 = array("pipe", "w")
);
$handle = proc_open(
'/webroot/go/src/test/test',
$descriptorspec,
$pipes
);
fwrite($pipes['0'], "这是一个测试文本\n");
echo fgets($pipes[1]);
解释:使用proc_open打开一个进程,调用Golang程序 。同时返回一个双向管道pipes数组,php向$pipe['0']中写数据,从$pipe['1']中读数据 。
好吧,也许你已经发现,我是标题档 , 这里重点要讲的并不只是PHP与Golang如何通信 。而是在介绍一种方法: 通过双向管道让任意语言通信 。(所有语言都会实现管道相关内容)
测试:
通过对比测试 , 计算出各个流程占用的时间 。下面提到的title.txt文件,包含100万行文本 , 每行文本是从b2b平台取的商品标题
1: 整体流程耗时
time cat title.txt | ./test/dev/null
耗时:14.819秒,消耗时间包含:
进程cat读出文本
通过管道将数据传入Golang
Golang处理数据,将结果返回到屏幕
2:计算分词函数耗时 。方案:去除分词函数的调取,即:注释掉Golang源代码中的调取分词那行的代码
time cat title.txt | ./test/dev/null
耗时:1.817秒时间,消耗时间包含:
进程cat读出文本
通过管道将数据传入Golang
Golang处理数据,将结果返回到屏幕
分词耗时 = (第一步耗时) - (以上命令所耗时)
分词耗时 : 14.819 - 1.817 = 13.002秒
3:测试cat进程与Golang进程之间通信所占时间
time cat title.txt/dev/null
耗时:0.015秒,消耗时间包含:
进程cat读出文本
通过管道将数据传入Golang
go处理数据,将结果返回到屏幕
管道通信耗时:(第二步耗时) - (第三步耗时)
管道通信耗时: 1.817 - 0.015 = 1.802秒
4:PHP与Golang通信的时间消耗
编写简单的php文件:
?php
$descriptorspec = array(
0 = array("pipe", "r"),
1 = array("pipe", "w")
);
$handle = proc_open(
'/webroot/go/src/test/test',
$descriptorspec,
$pipes
);
$fp = fopen("title.txt", "rb");
while (!feof($fp)) {
fwrite($pipes['0'], trim(fgets($fp))."\n");
echo fgets($pipes[1]);
}
fclose($pipes['0']);
fclose($pipes['1']);
proc_close($handle);
流程与上面基本一致,读出title.txt内容,通过双向管道传入Golang进程分词后,再返回给php (比上面的测试多一步:数据再通过管道返回)
time php popen.php/dev/null
耗时:24.037秒,消耗时间包含:
进程PHP读出文本
通过管道将数据传入Golang
Golang处理数据
Golang将返回结果再写入管道 , PHP通过管道接收数据
将结果返回到屏幕
结论:
1 :整个分词过程中的耗时分布
使用cat控制逻辑耗时:14.819 秒
使用PHP控制逻辑耗时:24.037 秒(比cat多一次管道通信)
单向管道通信耗时:1.8秒
Golang中的分词函数耗时:13.002 秒
2:分词函数的性能: 单进程,100万商品标题分词,耗时13秒
以上时间只包括分词时间,不包括词典载入时间 。但在本方案中,词典只载入一次 , 所以载入词典时间可以忽略(1秒左右)
3:PHP比cat慢 (这结论有点多余了 , 呵呵)
语言层面慢: (24.037 - 1.8 - 14.819) / 14.819 = 50%
单进程对比测试的话,应该不会有哪个语言比cat更快 。
相关问题:
1:以上Golang源码中写的是一个循环,也就是会一直从管道中读数据 。那么存在一个问题:是不是php进程结束后,Golang的进程还会一直存在?
管道机制自身可解决此问题 。管道提供两个接口:读、写 。当写进程结束或者意外挂掉时,读进程也会报错,以上Golang源代码中的err逻辑就会执行 , Golang进程结束 。
但如果PHP进程没有结束,只是暂时没有数据传入,此时Golang进程会一直等待 。直到php结束后 , Golang进程才会自动结束 。
2:能否多个php进程并行读写同一个管道,Golang进程同时为其服务?
不可以 。管道是单向的,如果多个进程同时向管道中写,那Golang的返回值就会错乱 。
可以多开几个Golang进程实现,每个php进程对应一个Golang进程 。
最后 , 上面都是瞎扯的 。如果你了解管道、双向管道,上面的解释对你基本没啥用 。但如果你不了解管道,调试上面的代码没问题,但稍有修改就有可能掉坑里 。
如何使用go语言来运行PHP首页你需要开启apache服务器
然后把你要运行的文件放入apache的根目录
你如果安装在C盘的话,就是在这个文件夹下C:\wamp\www
还有你要是有数据的话,打开apache后将数据导入到数据库中
phpstorm golang开发环境如何配置【go语言php编译 go语言 php】golang 有编辑器可以用 如国人开发的liteide,或者sublimetext、vim、emacs,为什么一定要用phpstorm?如果你只是做php开发,phpstorm很不错,如果用golang来开发,phpstorm 并不合适
Go 是怎么使用 Go 来编译自身的Go是一个图灵完备go语言php编译的语言
任何图灵完备的语言理论上都可以用来编译自身 。比如c/c, java, vb, php等等都可以 。
至于怎么编译自身的go语言php编译:
用其它语言比如c实现一个[Go语言编译器-1]
用Go语言写一个[Go语言编译器-2]
用这个c实现的[Go语言编译器-1]编译第2步里面说的Go语言写的[Go语言编译器-2]
用第3步得到的[Go语言编译器-2],再编译一次第2步里面说的[Go语言编译器-2]的源码 。
OK , 现在有一个Go语言实现的编译器了,最开始那个c写的编译器没用了,可以扔掉不要了 。以后就不停的优化使用这个Go语言实现的自身的编译器就行了 。
Go语言实现的电商系统QOR,为什么要开源PHP:是一种通用开源脚本语言 。语法吸收了C语言、Java的特点,利于学习,使用广泛,主要适用于Web开发领域 。PHP独特的语法混合了C、Java、Perl以及PHP自创的语法 。它可以比CGI或者Perl更快速地执行动态网页 。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML文档中去执行 , 执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快 。Java:是一种可以撰写跨平台应用程序的面向对象的程序设计语言 。Java技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,电子商务大型网站与平台是电商平台使用的最好的开发语言 。C#:是一种安全的、稳定的、简单的、优雅的,由C和C衍生出来的面向对象的编程语言 。C#是微软公司发布的一种面向对象的、运行于.NETFramework之上的高级程序设计语言 。并定于在微软职业开发者论坛上登台亮相 。C#是微软公司研究员的最新成果 。C#看起来与Java有着惊人的相似;它包括了诸如单一继承、接口、与Java几乎同样的语法和编译成中间代码再运行的过程 。但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点 , 与COM是直接集成的,而且它是微软公司.NETwindows网络框架的主角 。
go语言php编译的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言 php、go语言php编译的信息别忘了在本站进行查找喔 。
推荐阅读
- 晚上开直播能做什么赚钱,晚上直播人多吗
- 奥特曼双人格斗游戏名字,双人奥特曼对战游戏
- 游戏开发教父顶点,游戏开发之路
- php如何获取数据库字段 php读取数据库内容并输出
- css撑开div,css中div怎么用
- gis那个用着好,gis软件前景
- mysql怎么改分表程序 mysql怎么给表创建一个分区
- 升级鸿蒙系统会改变设置吗,升级鸿蒙系统
- 感人养成游戏,养成游戏经典