FFI:Golang辅助PHP的落地方案

1,635 阅读1分钟

FFI是PHP 7.4开始引入了一种新的机制。FFI (Foreign Function Interface),也就是外部函数接口,让PHP可以动态的调用.so或者.dll文件中定义好的函数。所谓的动态调用,也就是不需要像以前一样编写一个自己的扩展(extension)然后写进php.ini里,而是在代码里直接载入so/dll文件并且立刻可以调用文件中定义的函数。

PHP的FFI还是一项实验性的扩展功能,只要能够编译成C风格的库文件的编程语言,都可以用来编写PHP的新功能,比如C/CPP, Rust,还有就是我们之前提到的Golang。下面我们来演示一个实例。

前提

PHP版本要大于7.4,然后php.ini需要把ffi打开。我使用的虚拟机里,FFI是默认打开的。

14747e905d8f4f9599af0f2a3740b5f7.png

简单例子

print ()和sum()函数

Golang的部分非常简单。

package main

import (
    "C"
    "fmt"
)


//export print
func print(out *C.char) {
    fmt.Println("[GO print] " + C.GoString(out))
}


//export sum
func sum(a C.int, b C.int) C.int {
    return a + b
}

be824443be844ca29798265309b4287f.png

打开libutil.h之后可以在末端看到函数的格式。

extern void print(char* p0);


extern int sum(int p0, int p1);

这个格式在PHP文件中会用到。


<?php


$util = FFI::cdef(
    "void print(char* p0);
    int sum(int p0, int p1);",
    __DIR__ . "/libutil.so"
);


$util->print(
    (string) $util->sum(2, 4)
);

在命令行模式下执行test.php文件,可以看到打印的结果。

fed1f4a77c1d415eba80eb52cb2c6396.png