PHPで拡張を動的に有効にする汎用的な方法
PHPの拡張とは
PHPの機能を拡張するためにCで書かれた動的ライブラリのこと。
拡張を有効にするには
拡張を有効にする方法はphp.iniに設定する方法とdl()から動的に呼び出す方法の2つ。
動的に拡張を追加するにはdl()を使います。
dl()を使う問題点
dl('foo'); のように拡張名だけ指定して有効にできると便利なのですが、ちゃんと拡張のファイル名を指定しなければいけません。
で、ファイル名がOSによって異なるので、呼び出し方が異なります。
dl('foo.so');
Windowsの場合、拡張子が "dll" になって、さらにファイル名の先頭に "php_" という文字列がつく。
dl('php_foo.dll');
LLなんだから、こういう基本的なところは簡便にできるようにして欲しいな〜。
それとも動的に拡張を読み込むのは特殊ケースなのかしら?
PHP_SHLIB_SUFFIXを使う
最近のPHPではPHP_SHLIB_SUFFIXという定数に拡張の拡張子が定義されているので、それを使えばOK。
$prefix = PHP_SHLIB_SUFFIX === 'dll' ? 'php_' : '';
dl($prefix.'foo.'.PHP_SHLIB_SUFFIX);
PHP_SHLIB_SUFFIXが定義されてない場合
古いPHPではPHP_SHLIB_SUFFIXが定義されてない。
そういう場合はPHP_OSを見て、Windowsかどうかで無理矢理処理する。
$suffix = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? 'dll' : 'so';
$prefix = $suffix === 'dll' ? 'php_' : '';
dl($prefix.'foo.'.$suffix);
Mac OS Xで動かない><
これで完璧だと思ったんだけど、Mac OS Xで動かない><
PHP_SHLIB_SUFFIX が "dylib" なのに、拡張が ".so" でインストールのが原因。
どっちやねん(怒
でも、将来的に ".so" から ".dylib" に変更されるかもしれない可能性を考えると、あまりアドホックにやりたくない。
というわけでいくつか候補となるファイル名をいくつか試してdl()を呼び出すことにして回避。
loadExtension()
というわけで、最終的にできた完成系がこれ。
function loadExtension($extension)
{
if (extension_loaded($extension)) {
return true;
}
if (defined('PHP_SHLIB_SUFFIX')) {
$suffix = PHP_SHLIB_SUFFIX;
} else if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$suffix = 'dll';
} else {
$suffix = 'so';
}
$prefix = $suffix === 'dll' ? 'php_' : '';
$libraries = array("{$prefix}{$extension}.{$suffix}");
$libraries[] = "{$extension}.so";
$libraries[] = "php_{$extension}.dll";
$libraries = array_unique($libraries);
foreach ($libraries as $library) {
if (@dl($library)) {
return true;
}
}
return false;
}
LinuxでもWindowsでもMac OS Xでもうまくいくはず。
できるだけ汎用的に書いているので、多少環境が変わっても(Mac OS Xで拡張子がdylibに変更とか)大丈夫なようになってるはず。