ローカル環境のPHPでFFI(Foreign Function Interface)拡張を使いたくなったので、FFI拡張をphpenv経由で追加して有効化してみました。

FFI拡張とは
この拡張機能を使用すると、Zend 拡張 API に関する深い知識がなくても、また 3 番目の学習を必要とせずに、共有ライブラリ (.DLL または .so) のロード、C 関数の呼び出し、および純粋な PHP での C データ構造へのアクセスが可能になります。 「中間」言語。パブリック API は、いくつかの静的メソッド (動的に呼び出されるものもある) と、C データとの実際の対話を実行するオーバーロードされたオブジェクト メソッドを備えた単一クラスの FFI として実装されます。
警告 FFI は非常に低いレベルでシステムとのインターフェースを可能にするため、危険です。 FFI 拡張機能は、C および使用される C API の実用的な知識を持つ開発者のみが使用してください。リスクを最小限に抑えるために、ffi.enable php.ini ディレクティブを使用して FFI API の使用を制限することができます。
前提条件
- phpenvインストール済
- Ubuntu24.04(WSL2)上で作業しています
※最近phpenvのアップデートPull Requestがマージされなくなってきているので、代替手段を検討中です。
※2024/11/07にPHP8.4.0 RC4がリリースされ、2024/11/21にはPHP8.4.1がリリースされていますが、
執筆時点の2024/12/15では、対応するPull Requestが長期間放置された状態です。。
※asdfに乗り換えれば解決するのでしょうか?近々試してみようと思います。
※2024/12/30追記:vfox、mise、asdfの3ツールへの乗り換えを試してみました。
libffiインストール
事前に libffi がインストールされている必要があります。
次のコマンドで確認できます。
apt list libffi*

筆者の環境では既にインストールされています。
インストールする場合は
sudo apt install libffi-dev libffi8
としておけば問題ないと思います。
FFI拡張を有効化する設定
PHPをコンパイルする際のConfigureオプションで「–with-ffi」を指定します。
オプション定義ファイルは2種類あります。
どちらか一方に設定しておきます。
▼1.全バージョン共通のデフォルト定義ファイル
~/.phpenv/plugins/php-build/share/php-build/default_configure_options
こちらに設定する場合は、最終行にでも「–with-ffi」を追記しておきます。
--enable-sockets
--enable-exif
--with-zlib
--with-zlib-dir=/usr
・・・(中略)・・・
--enable-fpm
--enable-bcmath
--enable-phpdbg
--with-ffi
▼2.各バージョン毎の定義ファイル
~/.phpenv/plugins/php-build/share/php-build/definitions/[バージョン番号]
こちらに設定する場合は、対象バージョンの定義ファイルに「–with-ffi」を追記しておきます。
configure_option "--enable-gd"
configure_option "--with-jpeg"
configure_option "--with-zip"
configure_option "--with-mhash"
configure_option "--with-ffi"
configure_option -D "--with-xmlrpc"
install_package "https://www.php.net/distributions/php-8.3.13.tar.bz2"
install_xdebug "3.3.1"
enable_builtin_opcache
PHPインストール
執筆時点でphpenv定義の最新バージョン3.8.13を「imagick拡張」有効化して上書きインストールしてみます。
PHP_BUILD_INSTALL_EXTENSION="imagick=@" phpenv install 8.3.13

ffiが有効か確認します。
php -i | grep ffi

動作確認
FFIが機能するかの確認のために、適当な場所に次のPHPコードを保存します。
▼「ffi-test.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");

実行してみます。
php -f ffi-test.php

正常に出力がなされました。
以上です。
- 0
- 0
- 0
- 0






コメント