でびあんだとsudo apt-get install pearで入ってくれるPEARですが、いろんなパッケージをダウンロードしたりインストールしたりしてくれるpearコマンド(/usr/bin/pear)の実体は、/usr/share/php/pearcmd.phpを経由してPEAR_Commandクラスの対応する関数を実行しているだけです。
なので、シェルから
% pear discover-channel pear.example.jp % pear install example/Example
とかやっていたのは、phpから直接PEARパッケージのクラスを使って実行することもできるんですよ!
必要なもの
まず、pearコマンドを構成する要素として
がたぶん重要です。ぜんぶ http://pear.php.net/package/PEAR/docs/latest/ のクラス一覧にあるやつです。
今はphpのスクリプトから直接呼び出したいだけなので、PEAR_FrontendについてはCLIだけ考えればよさそうです。Webとかは、たぶん/usr/bin/pearコマンド(CLI)に相当するCGIとかあるんでしょうね。
pearcmd.phpを眺める
重要そうなところをつまみぐいしていくと、
PEAR_Command::setFrontendType('CLI'); $ui = &PEAR_Command::getFrontendObject(); $config = &PEAR_Config::singleton($pear_user_config, $pear_system_config); $cmd = PEAR_Command::factory($command, $config); $ui->outputData("ERROR: $_file is not a valid config file or is corrupted."); $ok = $cmd->run($command, $opts, $params);
というかんじですね。
それぞれの役割を考えると、
- $ui: エラーメッセージの表示とかをおまかせするオブジェクト
- $config: 登録したチャンネルとか、どこにインストールするかなどの設定情報
- $command: 'install' とか 'remote-list' とか、いわゆるコマンド名
- $cmd: コマンドオブジェクト, $cmd->run() で実行する
ということのようです。
ちょっと面倒そうなのは、run()の引数の$opts, $paramsってとこですね。
run()の中身は?
% pear help
とやると、ずらずらといろんなコマンドが出てくるわけですが、PEAR_Command_*の数と比べるとずいぶん少ないかんじです。
どうやら$commandとして指定していたものは、/usr/share/php/PEAR/Command/*.phpに直接対応するのではなく、その中でいくつかまとめて定義されているコマンドの1つを指定していたのでした。
たとえばPEAR/Command/Install.php(PEAR_Command_Installクラス)では、
- install
- upgrade
- upgrade-all
- uninstall
- bundle (コレなに?)
- run-scripts
という$commandがまとめて定義されています。ファイルの先頭に var $commands = array( ... ); という長いのがありますよね。
思えばPEAR_Command::factory()に$command渡しておきながら、run()でもう一度$command渡さなきゃいけなかったのは、こういう2段構えだったからなんですね。
さっきのvar $commandsをよく眺めると、
'install' => array( 'summary' => 'Install Package', 'function' => 'doInstall', 'shortcut' => 'i', 'options' => array( 'force' => array( 'shortopt' => 'f', 'doc' => 'will overwrite newer installed packages', ),
とか書いてるので、run()で呼ばれるのは doInstall() とか(後ろのほうで定義されてます)で、$optsはこれを見ながら決めればよさそうです。
あとpearcmd.phpで$paramsを作っている様子を見るに、ふだんpearコマンドで引数に与えていたのをそのまま(普通の)配列にしてあげれば良いと。
やってみよう
ということでものは試し。$optsと$paramsがちゃんとあるやつ、ってことで、
% pear remote-info -c pear PEAR
をやってみます。
<?php require_once 'PEAR.php'; require_once 'PEAR/Command.php'; require_once 'PEAR/Config.php'; $command = 'remote-info'; $opts = array('channel' => 'pear'); $params = array('DB'); PEAR_Command::setFrontendType('CLI'); $config = PEAR_Config::singleton(); $cmd = PEAR_Command::factory($command, $config); $cmd->run($command, $opts, $params); ?>
pearは反応が遅いのですげー待たされますが、タバコ1本吸って戻ってみると、ちゃんと結果が表示されました! わーい!
Package details: ================ Latest 1.7.6 Installed 1.7.6 Package DB License PHP License Category Database Summary Database Abstraction Layer Description DB is a database abstraction layer providing: * an OO-style query API ...
$ui(Frontend)が出てきてないですが、とくに自分でメッセージを出す気がなければPEAR_Command::factory()のなかで勝手に作っておいてくれます。上のメッセージはそこから出てきたんだと思う。
明日はinstallをもうちょっと追ってみようと思います。