使用 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. ASR项目实战-构建Kaldi

    准备工作 安装构建时依赖的基础软件 软件清单如下: bzip2 python3 automake libtool cmake gcc g++ gfortran git subversion 不同平台安 ...

  2. ElasticSearch之cat aliases API

    执行aliases命令,如下: curl -X GET "https://localhost:9200/_cat/aliases?pretty&v=true" --cace ...

  3. 前端 Git 使用约定

    前端 Git 使用约定 背景 开发前端项目,有以下困惑: 使用哪个分支开发,哪个分支发布 修复线上bug的流程是什么,如何避免修复完了下次却又出现了 cms分支有十多个,是否都有用 如何快速找到之前某 ...

  4. IOS关闭锁屏状态下左滑相机

    IOS 锁屏状态下,左滑就会打开相机,还不能关闭.这种功能说真的,没有啥用,还很麻烦.看了一圈教程,写的也是没写全.自己再写一个,以后换手机还用得上. 注:此方法会导致微信的扫一扫不可用 1.找到&q ...

  5. Zookeeper 的基本使用

    维基百科对 Zookeeper 的介绍如下所示: Apache ZooKeeper是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册 ZooKe ...

  6. Ubuntu 终端如何分割多个窗口

    sudo apt-get install terminator 查看 ~/.config(隐藏文件夹 ctrl + h 即可看见) 下是否有 terminator 文件夹 如果没有手动创建一个 然后在 ...

  7. 文心一言 VS 讯飞星火 VS chatgpt (31)-- 算法导论5.2 3题

    三.利用指示器随机变量来计算掷n 个骰子之和的期望值. 文心一言: 为了计算掷n个骰子之和的期望值,我们需要先了解一个重要的概念:指示器随机变量. 指示器随机变量是一种特殊的随机变量,它只有两个取值: ...

  8. kylin&CDH理论基础

    Kylin&CDH理论基础 一.维度与度量 维度是观察数据的角度.比如电商的销售数据,可以从时间维度来观察,进一步细化时间和地区维度来观察. 度量是被聚合的统计值,也是聚合运算的结果.知道维度 ...

  9. DevSecOps“内置安全保护”,让软件研发“天生健康”

    摘要:我们主要是围绕安全架构设计保证安全落地有法可依,进行威胁建模让安全落地有迹可循.做好隐私和敏感数据保护让安全落地在每一个细节和实处这几个方面进行阐述. 本文分享自华为云社区<DevSecO ...

  10. 火山引擎DataLeap基于Apache Atlas自研异步消息处理框架

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 字节数据中台DataLeap的Data Catalog系统通过接收MQ中的近实时消息来同步部分元数据.Apache ...