Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPでGoを実行する / Running Go from PHP

PHPでGoを実行する / Running Go from PHP

【オンライン】xTech ゆるっとLT: Fukuoka.php and AR_Fukuoka(2021-09-03)での発表資料です。

PHP から Go で書いた処理を呼び出す方法を扱います。

Avatar for shiro seike

shiro seike PRO

September 03, 2021

More Decks by shiro seike

Other Decks in Programming

Transcript

  1. 自己紹介 - ID - - - 清家 史郎 GitHub:seike460 Twitter:@seike460

    Work at - 株式会社 Fusic (フュージック) 技術開発本部/技術開発第一部門 - チームリーダー/エバンジェリスト/プリンシパルエンジニア Skill - PHP/Go/AWS Personal - PHPカンファレンス福岡2020 幻の実行委員長 - Fukuoka.php Organizer 46fm パーソナリティ @seike460 2
  2. Foreign Function Interface(FFI) - This extension allows the loading of

    shared libraries (.DLL or .so), calling of C functions and accessing of C data structures in pure PHP, without having to have deep knowledge of the Zend extension API, and without having to learn a third “intermediate” language. The public API is implemented as a single class FFI with several static methods (some of them may be called dynamically), and overloaded object methods, which perform the actual interaction with C data. - この拡張モジュールを使用すると、共有ライブラリ (.DLL または .so) の読み込み、C 言語の関数の呼び出し、C 言語 のデータ構造へのアクセスを純粋な PHP で行うことができ、Zend 拡張モジュールの API を深く理解する必要も、第 三の「中間」言語を学ぶ必要もありません。パブリック API は、いくつかの静的メソッド (そのうちのいくつかは動的に コールされることもあります) とオーバーロードされたオブジェクトメソッドを持つ単一の FFI クラスとして実装されてお り、C データとの実際のやり取りを行います。 8
  3. Foreign Function Interface(FFI) asdfを利用してPHP-FFIをインストールする asdf … anyenvの様な様々なのバージョンの言語管理が出来るツール # PHPのconfigure_optionを設定 $

    export PHP_CONFIGURE_OPTIONS="--with-ffi --with-iconv=/usr/local/opt/libiconv --with-openssl=/[email protected]@" # 7.4.22をインストール $ asdf install php 7.4.22 # 利用するPHPを7.4.22に切替 $ asdf glonal php 7.4.22 # モジュールがインストールされているかを確認 $ php -m | grep FFI FFI 9
  4. Foreign Function Interface(FFI) 以下のコードを実行して、C言語のprintf() を呼び出すことが可能出来た <?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! 10
  5. cgo 以下の様なGoのコードを記述 足し算と引き算をする簡単な関数 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() {} 13
  6. cgo -buildmode=c-shared で作成、Macで利用するため dylib として共有ライブラリ $ go build -buildmode=c-shared -o

    seike460.dylib seike460.go PHP側から呼び出し <?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 14