使用 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. JavaFx之SceneBuilder添加其他依赖库(十六)

    JavaFx之SceneBuilder添加其他依赖库(十六) Could not open 'xxxxx.jar' Open operation has failed. Make sure that ...

  2. Redis 的主从复制

    Redis 主从复制是指:将一台 Redis 服务器的数据复制到其它的 Redis 服务器,前者所在的 Redis 服务器也被称为 "主节点"(Master / Leader),后 ...

  3. maven系列:依赖管理和依赖范围

    目录 一.依赖管理 使用坐标导入jar包 使用坐标导入 jar 包 – 快捷方式 使用坐标导入 jar 包 – 自动导入 二.依赖范围 三.可选依赖 四.排除依赖 一.依赖管理 使用坐标导入jar包 ...

  4. 用IoT放羊养牛,不出门也能知道它们的动向

    摘要:羊圈里几只小羊羔有点无精打采,"叮",牧民拉索划开手机,第一时间得知了这个情况.草场上有只牛一直到天黑都没回来,拉索再次通过手机软件,很快定位到那只独自流落在外的牛儿-- 本 ...

  5. 高颜值开源数据可视化工具——Superset 2.0正式发布!

    ​ Superset终于迎来了又一个重大的版本更新.使用superset已经近三年的时间了,其为我们提供了数据可视化的解决方案.也成为了最好的商用BI的替代方案. ​ 在Github上本次更新已经发布 ...

  6. 有什么好用的C/C++源代码混淆工具?

    开始使用ipaguard 前言 iOS加固保护是直接针对ios ipa二进制文件的保护技术,可以对iOS APP中的可执行文件进行深度混淆.加密.使用任何工具都无法逆向.破解还原源文件.对APP进行完 ...

  7. 2023 年如何将您的应用提交到 App Store

    您夜以继日地工作来创建您的梦想应用程序.最后,是时候向全世界宣布您的应用程序了.但不知道如何将您的应用提交到 App Store? 为您的商店获取现成的移动应用程序 将应用程序提交到 App Stor ...

  8. 无法停止服务、无法终止 PID 4100 的进程

    服务中无法停止服务. 先查出服务对应的进程 Microsoft Windows [版本 10.0.19043.1348] (c) Microsoft Corporation.保留所有权利. C:\Us ...

  9. 愉快的了解Charles

    charles是PC端常用的网络封包截取工具,在做移动开发时,我们为了调试与服务器端的网络通讯协议,常常需要截取网络封包来分析.除了在做移动开发中调式端口外,charles也可以用于分析第三方应用的通 ...

  10. 2024-01-17:lc的30. 串联所有单词的子串

    2024-01-17:用go语言,给定一个字符串 s 和一个字符串数组 words. words 中所有字符串 长度相同. s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接 ...