Table of Contents
php-ffiのインストール
最近社内記事で知ったasdfを利用してffiを入れていきます。 環境はMacです。
GitHub - asdf-vm/asdf: Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more
Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more - asdf-vm/asdf
GitHub - asdf-community/asdf-php: PHP plugin for the asdf version manager
PHP plugin for the asdf version manager. Contribute to asdf-community/asdf-php development by creating an account on GitHub.
# PHPのconfigure_optionを設定
$ export PHP_CONFIGURE_OPTIONS="--with-ffi --with-iconv=/usr/local/opt/libiconv --with-openssl=/openssl@1.1@"
# 7.4.22をインストール
$ asdf install php 7.4.22
# 利用するPHPを7.4.22に切替
$ asdf glonal php 7.4.22
# モジュールがインストールされているかを確認
$ php -m | grep FFI
FFI
php-ffiが入りました。
php-ffiにてサンプルを実行する
実際にC言語のサンプルを動かします。
サンプルはLinux向けなので、ここではDockerで動かしてしまいます。
ffiが入ったDockerイメージを通して以下phpを実行
<?php
// create FFI object, loading libc and exporting function printf()
$ffi = FFI::cdef(
"int printf(const char *format, ...);", // this is a regular C declaration
"libc.so.6");
// call C's printf()
$ffi->printf("Hello %s!\n", "world");
$ docker run -it --rm -v "$PWD":/tmp -w /tmp php-ffi php BasicFFIusage.php
Hello world!
cgoを利用した共有ライブラリを作成する
以下の様なコードを書きます。
その際にexport 〇〇 といったコメントを書く事で外部から利用出来るようにします
package main
import "C"
//export add ※add関数をexport
func add(i int, n int) int {
return i + n
}
//export minus ※minus関数をexport
func minus(i int, n int) int {
return i - n
}
func main() {}
共有ライブラリとしてBuildします。
Macようなので名前は念の為dylibとします。
$ go build -buildmode=c-shared -o seike460.dylib seike460.go
共有ライブラリをphp-ffiで読み込んで実行します
<?php
// 第1引数に利用する関数の宣言、第2引数に読み込む共有ライブラリ
$ffiGo = \FFI::cdef(
'extern int add(int p0, int p0);
extern int minus(int p0, int p0);',
'seike460.dylib'
);
echo $ffiGo->add(3, 2) . PHP_EOL;
echo $ffiGo->minus(3, 2) . PHP_EOL;
このファイルを実行すると、なんと足し算と引き算が出来ます。
$ php ffi.php
5
1
文字列や配列などを扱うのは一工夫必要で、
調査してたところ非常に有用な記事がありましたので合わせて紹介致します。
hanhan's blog
PHP-FFIの使い方サンプル書いた
PHP-FFIの簡単な動作テストは以前にもやったので、今回は色んな引数、色んな戻り値のパターンでサンプル実装を書いてみた。
hanhan1978/php-ffi-samples...
まとめ
PHPとGoを使ってる身としてPHPからGoを使うことで速度的な優位製を 表現力の高いPHPでかけることは使いみちとしてなくはないなと感じました。
またC共有ライブラリのこの関数を使いたい…!というときでも使えるので、 興味があれば試してみてください。