使用 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 扩展的更多相关文章

  1. 使用golang 编写postgresql 扩展

      postgresql 的扩展可以帮助我们做好多强大的事情,支持的开发语言有lua.perl.java.js.c 社区有人开发了一个可以基于golang开发pg 扩展的项目,使用起来很方便,同时为我 ...

  2. Windows下visual studio code搭建golang开发环境

    Windows下visual studio code搭建golang开发环境 序幕 其实环境搭建没什么难的,但是遇到一些问题,主要是有些网站资源访问不了(如:golang.org),导致一些包无法安装 ...

  3. Golang 开发技能图谱

    # Golang 开发技能图谱 ## Go 语言环境搭建- Go 安装- GOPATH 与工作空间- Go 命令- Go开发工具 ## GO 语言编程基础- 关键词和语法(Language Synta ...

  4. 使用golang 开发的 andriod应用

    最近在捣鼓一个东东,就是使用golang开发andriod应用.说起来简单操作起来还挺麻烦,中间又学习了很多东西.比如ubuntu,docker,angular,ionic,jquery mobile ...

  5. 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单

    手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单   手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩 ...

  6. Sublime Text 前端开发常用扩展插件推荐

    Sublime Text 前端开发常用扩展插件推荐 Sublime Text Sublime Text 是程序员们公认的编码神奇,拥有漂亮的用户界面和强大的功能 更重要的是,Sublime Text ...

  7. golang开发android环境搭建_window

    golang开发android环境搭建介绍 一 安装依赖软件: git:版本管理 go:  go开发环境(版本>=1.5),可直接下载window版的go安装包. android studio: ...

  8. 【翻译】我钟爱的Visual Studio前端开发工具/扩展

    原文:[翻译]我钟爱的Visual Studio前端开发工具/扩展 怎么样让Visual Studio更好地编写HTML5, CSS3, JavaScript, jQuery,换句话说就是如何更好地做 ...

  9. 最锋利的Visual Studio Web开发工具扩展:Web Essentials详解

    原文:最锋利的Visual Studio Web开发工具扩展:Web Essentials详解 Web Essentials是目前为止见过的最好用的VS扩展工具了,具体功能请待我一一道来. 首先,从E ...

  10. 开发 chrome 扩展 GitHub-Remarks 的一些想法以及遗憾

    前文 对于单页应用中如何监听 URL 变化的思考 说到我在开发 chrome 扩展 GitHub Remarks 中遇到的一个问题,本文来聊聊开发这个扩展的前后心路历程. 为什么开发这个扩展?前文说到 ...

随机推荐

  1. MD5 or Bcrypt?

    MD5 or Bcrypt? 摘要 首先是一个错误的认识观念问题,很多人觉得MD5是一个加密算法.不然,他实则是一种摘要算法,也可以叫哈希函数.他的作用是将目标文本转换成具有相同长度.不可逆的杂凑字符 ...

  2. 如何从零开始实现TDOA技术的 UWB 精确定位系统(1)

    前言 这是一个系列文章,将向你介绍如何从零开始实现一个使用TDOA技术的 UWB 精确定位系统. 重要提示(劝退说明): Q:做这个定位系统需要基础么? A:文章不是写给小白看的,需要有电子技术和软件 ...

  3. Java反序列化漏洞-CC1利用链分析

    @ 目录 一.前置知识 1. 反射 2. Commons Collections是什么 3. 环境准备 二.分析利用链 1. Transformer 2. InvokeTransformer 执行命令 ...

  4. Spring Boot入坑-2-第一个Spring Boot项目

    Spring Boot简介 自从2014年4月Pivotal团队推出以来,作为一个基于Spring的开源轻量级框架,备受企业级应用喜爱 简化Spring应用的搭建与开发过程 是对Spring缺点进行的 ...

  5. 2024-01-13:用go语言,现在有一个打怪类型的游戏,这个游戏是这样的,你有n个技能, 每一个技能会有一个伤害, 同时若怪物小于等于一定的血量,则该技能可能造成双倍伤害, 每一个技能最多只能释放

    2024-01-13:用go语言,现在有一个打怪类型的游戏,这个游戏是这样的,你有n个技能, 每一个技能会有一个伤害, 同时若怪物小于等于一定的血量,则该技能可能造成双倍伤害, 每一个技能最多只能释放 ...

  6. [活动(深圳)] .NET Love AI 之 .NET Conf China 2023 Party 深圳

    中国.NET 社区2023年12月16日 在北京成功举办了.NET Conf China 2023,虽然北京飘起雪,依然挡不住想要参加活动的全国各地的.NET开发兄弟姐妹的热情.大家可以通过大会精彩照 ...

  7. Flink实时处理入门

    Flink实时处理入门 1.Flink框架介绍 Flink 诞生于欧洲的一个大数据研究项目 StratoSphere.它是由 3 所地处柏林的大学和欧洲其他一 些大学在 2010~2014 年共同进行 ...

  8. gitee图床不能用了,心态崩了

    起因 大概上周五晚上吧,想着可以正常下班了.也没啥事,正好可以逛逛自己的小破站,看看有没有小伙伴留言什么的. 然后发现小破站图片显示不出来了... 一开始也没在意,想着可能是Gitee又挂了,可能一会 ...

  9. Java 在PPT中添加文本、图片超链接

    本文介绍通过Java程序在PPT幻灯片中添加超链接的方法,可以给文本或者图片设置超链接,设置超链接时,可设置包括网页链接.邮件地址链接.幻灯片跳转链接等不同指向对象的链接.文中方法使用了免费版PPT类 ...

  10. Mock服务设计与实现:MySQL驱动字节码修改增强

    摘要:华为导流测试平台通过对线上流量回放到被测环境中,利用线上真实流量进行充分测试,保证业务系统稳定上线.但是业务在导流测试过程中现网数据库往往难以同步到测试环境,导致现网数据无法正常回放,测试价值降 ...