使用 golang 开发 PHP 扩展
使用 golang 开发 PHP 扩展
环境
- golang go1.19.9 darwin/arm64
- Macos/Linux
- PHP8.1.11 编译安装
实战
PHP脚手架生成
进入PHP源码,使用命令
php ext/ext_skel.php --ext go2php
会在ext目录下生成go2php的文件夹
GO静态库生成
在go2php 文件下新建目录gomodule,使用命令
cd gomodule
go mod init gomodule
编写go源码
package main
import "C"
//export addNum
func addNum(a, b int) int {
	return a + b
}
func main() {}
生成静态库文件
至于为什么不生成动态库,因为如果是动态库编译后这个文件不能删除,比较局限
go build -x -buildmode=c-archive -o libgomodule.a
此时会在gomodule文件夹生成libgomodule.h 和libgomodule.a 文件
config.m4文件修改
在PHP_NEW_EXTENSION上面添加
PHP_ADD_LIBRARY(stdc++, 1, GOLANG2PHP_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(gomodule, ./lib, GOLANG2PHP_SHARED_LIBADD)
PHP_REQUIRE_CXX()
C扩展编写
自定义函数声明文件phpAddNum golang2php_arginfo.h
/*自定义方法phpAddNum的参数*/
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_phpAddNum, 0, 2, IS_LONG, 0)
	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, a, IS_LONG, 1, 0)
	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, b, IS_LONG, 1, 0)
ZEND_END_ARG_INFO()
/*自定义方法phpAddNum*/
ZEND_FUNCTION(phpAddNum);
/*自定义方法phpAddNum加入zend_function_entry*/
static const zend_function_entry ext_functions[] = {
	ZEND_FE(phpAddNum, arginfo_phpAddNum)
	ZEND_FE_END
};
c文件修改 golang2php.c
/* golang2php extension for PHP */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "ext/standard/info.h"
#include "php_golang2php.h"
#include "golang2php_arginfo.h"
#include "lib/libgomodule.h" /* golang编译生成的头文件 */
/* For compatibility with older PHP versions */
#ifndef ZEND_PARSE_PARAMETERS_NONE
#define ZEND_PARSE_PARAMETERS_NONE()  \
	ZEND_PARSE_PARAMETERS_START(0, 0) \
	ZEND_PARSE_PARAMETERS_END()
#endif
/* {{{  自定义方法phpAddNum */
PHP_FUNCTION(phpAddNum)
{
	zend_long a;
	zend_long b;
	ZEND_PARSE_PARAMETERS_START(0, 2)
	Z_PARAM_OPTIONAL
	Z_PARAM_LONG(a)
	Z_PARAM_LONG(b)
	ZEND_PARSE_PARAMETERS_END();
	// 调用golang中的函数
	int res = addNum(a, b);
	RETURN_LONG(res);
}
/* }}}*/
/* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION(golang2php)
{
#if defined(ZTS) && defined(COMPILE_DL_GOLANG2PHP)
	ZEND_TSRMLS_CACHE_UPDATE();
#endif
	return SUCCESS;
}
/* }}} */
/* {{{ PHP_RINIT_FUNCTION */
PHP_MINIT_FUNCTION(golang2php)
{
	return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(golang2php)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "golang2php support", "enabled");
	php_info_print_table_end();
}
/* }}} */
/* {{{ golang2php_module_entry */
zend_module_entry golang2php_module_entry = {
	STANDARD_MODULE_HEADER,
	"golang2php",			/* Extension name */
	ext_functions,			/* zend_function_entry */
	PHP_MINIT(golang2php),	/* PHP_MINIT - Module initialization */
	NULL,					/* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(golang2php),	/* PHP_RINIT - Request initialization */
	NULL,					/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(golang2php),	/* PHP_MINFO - Module info */
	PHP_GOLANG2PHP_VERSION, /* Version */
	STANDARD_MODULE_PROPERTIES};
/* }}} */
#ifdef COMPILE_DL_GOLANG2PHP
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(golang2php)
#endif
编译
1. /usr/local/php8.1.11/bin/phpize #找到phpize的路径
2 ./configure --with-php-config=/usr/local/php8.1.11/bin/php-config #php-config的路径
3. make && make install #执行make操作
ini配置
extension=golang2php
测试
php -r "var_dump(phpAddNum(100,200));"
#看到返回300即为成功
int(300)
扩展
当golang中返回数据为引用时,需要在golang释放
decodeStr := string(body)
cString := C.CString(decodeStr)
encryptFileString[fileName] = cString
defer C.free(unsafe.Pointer(cString)) //释放
return cString
c与go它们的对应关系表
| C 语言类型 | CGO 类型 | Go 语言类型 | 
|---|---|---|
| char | C.char | byte | 
| singed char | C.schar | int8 | 
| unsigned char | C.uchar | uint8 | 
| short | C.short | int16 | 
| unsigned short | C.ushort | uint16 | 
| int | C.int | int32 | 
| unsigned int | C.uint | uint32 | 
| long | C.long | int32 | 
| unsigned long | C.ulong | uint32 | 
| long long int | C.longlong | int64 | 
| unsigned long long int | C.ulonglong | uint64 | 
| float | C.float | float32 | 
| double | C.double | float64 | 
| size_t | C.size_t | uint | 
使用 golang 开发 PHP 扩展的更多相关文章
- 使用golang 编写postgresql 扩展
		postgresql 的扩展可以帮助我们做好多强大的事情,支持的开发语言有lua.perl.java.js.c 社区有人开发了一个可以基于golang开发pg 扩展的项目,使用起来很方便,同时为我 ... 
- Windows下visual studio code搭建golang开发环境
		Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ... 
- Golang 开发技能图谱
		# Golang 开发技能图谱 ## Go 语言环境搭建- Go 安装- GOPATH 与工作空间- Go 命令- Go开发工具 ## GO 语言编程基础- 关键词和语法(Language Synta ... 
- 使用golang 开发的 andriod应用
		最近在捣鼓一个东东,就是使用golang开发andriod应用.说起来简单操作起来还挺麻烦,中间又学习了很多东西.比如ubuntu,docker,angular,ionic,jquery mobile ... 
- 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单
		手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩 ... 
- Sublime Text 前端开发常用扩展插件推荐
		Sublime Text 前端开发常用扩展插件推荐 Sublime Text Sublime Text 是程序员们公认的编码神奇,拥有漂亮的用户界面和强大的功能 更重要的是,Sublime Text ... 
- golang开发android环境搭建_window
		golang开发android环境搭建介绍 一 安装依赖软件: git:版本管理 go: go开发环境(版本>=1.5),可直接下载window版的go安装包. android studio: ... 
- 【翻译】我钟爱的Visual Studio前端开发工具/扩展
		原文:[翻译]我钟爱的Visual Studio前端开发工具/扩展 怎么样让Visual Studio更好地编写HTML5, CSS3, JavaScript, jQuery,换句话说就是如何更好地做 ... 
- 最锋利的Visual Studio Web开发工具扩展:Web Essentials详解
		原文:最锋利的Visual Studio Web开发工具扩展:Web Essentials详解 Web Essentials是目前为止见过的最好用的VS扩展工具了,具体功能请待我一一道来. 首先,从E ... 
- 开发 chrome 扩展 GitHub-Remarks 的一些想法以及遗憾
		前文 对于单页应用中如何监听 URL 变化的思考 说到我在开发 chrome 扩展 GitHub Remarks 中遇到的一个问题,本文来聊聊开发这个扩展的前后心路历程. 为什么开发这个扩展?前文说到 ... 
随机推荐
- ElasticSearch之Get index API
			获取指定索引的基本信息. 命令样例如下: curl -X GET "https://localhost:9200/testindex_001?pretty" --cacert $E ... 
- 一键式调试工具—Reqable 使用指南
			简介 Reqable是一款跨平台的专业HTTP开发和调试工具,在全平台支持HTTP1.HTTP2和HTTP3(QUIC)协议,简单易用.功能强大.性能高效,助力程序开发和测试人员提高生产力!本产品需要 ... 
- 某物流客户Elasticsearch集群性能优化案例
			客户背景 客户使用ES来进行数据存储.快速查询业务订单记录,但是经常会出现业务高峰期ES集群的cpu负载.内存使用均较高,查询延迟大,导致前端业务访问出现大量超时的情况,极大影响其客户使用体验. 部分 ... 
- [LitCTF 2023]1zjs
			打开环境: 一个魔方♂ 习惯性打开 F12,之后发现有个./dist/index.umd.js Ctrl u 打开 把这个蓝色的点开 0.o? 这里眼神好的话就能看到有个" /f@k3f1a ... 
- 《RAPL: A Relation-Aware Prototype Learning Approach for Few-Shot Document-Level Relation Extraction》阅读笔记
			代码 原文地址 预备知识: 1.什么是元学习(Meta Learning)? 元学习或者叫做"学会学习"(Learning to learn),它是要"学会如何学 ... 
- kylin&CDH理论基础
			Kylin&CDH理论基础 一.维度与度量 维度是观察数据的角度.比如电商的销售数据,可以从时间维度来观察,进一步细化时间和地区维度来观察. 度量是被聚合的统计值,也是聚合运算的结果.知道维度 ... 
- 华为云API Explorer重磅推出API编排,开发者0代码高效构建工作流
			本文分享自华为云社区<华为云API Explorer重磅推出API编排,开发者0代码高效构建工作流(体验用户招募中)>,作者:华为云PaaS服务小智. 打破传统开发模式,API编排应运而生 ... 
- 带你深入理解Java的IO到底是个啥
			摘要:操作系统就是管家,电脑的设备就是资源,如果进程先要操作资源,必须要进行系统调用,有操作系统去处理,然后再返回给进程,这样的代理模式是不是很常见?因此app 就是你写的程序,资源就是硬盘或者其他的 ... 
- 火山引擎DataTester:AB测试技术揭秘及应用分享
			更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在全球软件工程创新峰会上,火山引擎DataTester 研发负责人韩云飞围绕"AB测试:让数据与业务 ... 
- 火山引擎 DataTester:在广告投放场景下的 A/B 实验实践
			更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 "我知道在广告上的投资有一半是无用的,但问题是我不知道是哪一半." --零售大亨约翰·沃纳梅克 ... 
