使用 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. reboot详解

    linux下reboot命令详解 linux reboot 命令详解 功能说明:重新开机. 语 法:dreboot [-dfinw] 补充说明:执行reboot指令可让系统停止运作,并重新开机. 参 ...

  2. 如何开发一个ORM数据库框架

    如何开发一个ORM框架 ORM(Object Relational Mapping)对象关系映射,ORM的数据库框架有hibernate,mybatis.我该如何开发一个类似这样的框架呢? 为什么会有 ...

  3. Java中递归的简单应用

    递归是一种非常常见的编程技巧,它可以将一个复杂的问题分解成更小的问题,然后递归地解决这些小问题,最终得到整个问题的解.递归的本质就是函数调用自身. 我们来看一个简单的例子:计算阶乘.阶乘是指将一个数和 ...

  4. C++ 惯用法之 RAII

    RAII(Resource Acquisition Is Initialization)资源获取即初始化,是 C++ 中最基本.应用最广范的惯用法(idiom)之一. RAII 的基本思想是通过构造/ ...

  5. 日常Bug排查-集群逐步失去响应

    前言 日常Bug排查系列都是一些简单Bug排查.笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_ Bug现场 最近碰到一个产线问题,表现为某个应用集群所有的节点全部下线了.导致上游调用全部 ...

  6. 数据库“意外失联”?华为云DRS异地多活灾备为您支招

    [摘要] 为了更好地提供灾备保护,华为云数据库在"同城两中心"的基础上提出了异地保护的方案,华为云数据复制服务DRS推出了异地多活灾备,即"两地四中心". 在D ...

  7. 云小课|HSS教您如何应对LockBit勒索事件

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:勒索病毒是一种极具 ...

  8. 9个SQL运维常遇到的问题

    摘要:本文重点介绍单个SQL语句持续执行慢的场景. 本文分享自华为云社区<GaussDB(DWS) SQL性能问题案例集>,作者:黎明的风. 本文重点介绍单个SQL语句持续执行慢的场景.我 ...

  9. 鸿蒙轻内核M核源码分析:数据结构之任务就绪队列

    摘要:本文会给读者介绍鸿蒙轻内核M核源码中重要的数据结构,任务基于优先级的就绪队列Priority Queue. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列三 数据结构-任务就绪队列> ...

  10. iOS 应用上架的步骤和工具简介

    编辑 APP开发助手是一款能够辅助iOS APP上架到App Store的工具,它解决了iOS APP上架流程繁琐且耗时的问题,帮助跨平台APP开发者顺利将应用上架到苹果应用商店.最重要的是,即使没有 ...