美文网首页PHP
用 FFI 写一个普通PHP程序员 “看不懂” 的 “PHP”

用 FFI 写一个普通PHP程序员 “看不懂” 的 “PHP”

作者: ___n | 来源:发表于2021-02-05 10:09 被阅读0次

    PHP 7.4 新加入了一个扩展 PHP FFI,这个扩展可以很方便的让PHP调用C语言写的各种优秀的库。

    什么是FFI

    FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP的FFI扩展就是一个让你在PHP里调用C代码的技术。FFI的使用非常简单,只用声明和调用两步就可以,对于有C语言经验,但是不了解Zend引擎的程序员来说,就变成很容易入手了。

    cd php-7.4.4/ext/ffi/
    phpize
    ./configure
    make && make install
    

    FFI::cdef的原型是: FFI::cdef([string $cdef = "" [, string $lib = null]]): FFI

    $ffi = FFI::cdef("int system(char* command);");
    $ffi ->system("cat /etc/passwd");
    

    string $cdef 中,我们可以写C语言函数式申明,FFI会parse它,了解到我们要在string $lib这个库中调用的函数的签名是啥样的。

    // 创建一个 FFI 对象,加载 libc 并且导入 printf 函数
    $ffi_printf = FFI::cdef(
        "int printf(const char *format, ...);", // C 的定义规则
        "libc.so.6"); // 指定 libc 库
    // 调用 C 的 printf 函数
    $ffi_printf->printf("Hello %s!\n", "world"); // Hello World
     
    // 加载 math 并且导入 pow 函数
    $ffi_pow = FFI::cdef(
        "double pow(double x, double y);", 
        "libboost_math_c99.so.1.66.0");
    // 这里调用的是 C 的 pow 函数,不是 PHP 自己的
    echo $ffi_pow->pow(2,3), PHP_EOL; // 8
    

    不过,虽然C类库性能很高,但是FFI调用的消耗也是非常的大,所以对于一些比较占用CPU的处理,还是可以尝试一下使用FFI。

    // 创建一个 int 变量
    $x = FFI::new("int");
    var_dump($x->cdata); // int(0)
     
    // 为变量赋值
    $x->cdata = 5;
    var_dump($x->cdata); // int(5)
     
    // 计算变量
    $x->cdata += 2;
    var_dump($x->cdata); // int(7)
     
     
    // 结合上面的两个 FFI 对象操作
     
    echo "pow value:", $ffi_pow->pow($x->cdata, 3), PHP_EOL;
    // pow value:343
    $ffi_printf->printf("Int Pow value is : %f\n", $ffi_pow->pow($x->cdata, 3));
    // Int Pow value is : 343.000000
     
     
    // 创建一个数组
    $a = FFI::new("long[1024]");
    // 为数组赋值
    for ($i = 0; $i < count($a); $i++) {
        $a[$i] = $i;
    }
    var_dump($a[25]); // int(25)
     
    $sum = 0;
    foreach ($a as $n) {
        $sum += $n;
    }
    var_dump($sum); // int(523776)
     
    var_dump(count($a)); // int(1024) 数组长度
    var_dump(FFI::sizeof($a)); // int(8192),内存大小
    

    相关文章

      网友评论

        本文标题:用 FFI 写一个普通PHP程序员 “看不懂” 的 “PHP”

        本文链接:https://www.haomeiwen.com/subject/smgbtltx.html