コマンドラインの引数解析を簡単に!

皆さんはPHPでコマンドラインスクリプトを作成するとき、引数の解析はどうされてますか?

引数が単純であればargvをそのまま使うだけで十分ですが、オプションが多かったりすると結構面倒ですよね。

たまたまPHPプロ!Weekly PEAR リリース @ 08/08/05号Console_CommandLineという引数を解析するライブラリを見つけて使ってみたところ、なかなか便利だったのでご紹介したいと思います。

ちなみに、オプションの解析には、PHP標準のgetopt関数を使えば多少楽はできるのですが、

getopt.php


<?php
$options = getopt('d:');
print_r($options);
?>


$ php getopt.php -h -d 20080807 filename


Array
(
    [d] => 20080101
)

といったように、不明なオプションが指定されているのを判断できなかったり、引数のfilenameを取得できなかったりと、あまり使い勝手が良くありません。

PEAR::Console_CommandLineはそこもきちんと対処してくれます。なお、Pythonのoptparseモジュールにインスパイアされて作られたものらしいです。

では、まずインストールします。


# pear install Console_CommandLine

例として、日付と複数のファイル名を引数にとるスクリプトを作成してみます。

command_line.php


<?php
require_once 'Console/CommandLine.php';
// パーサの作成
$parser = new Console_CommandLine(array(
  'description' => 'Console_CommandLineのサンプル',
  'version'     => '1.0.0'
));
// オプションの追加
$parser->addOption('date', array(
  'short_name'  => '-d',
  'long_name'   => '--date',
  'action'      => 'StoreString',
  'help_name'   => 'YYYYMMDD',
  'description' => '対象となる日付',
));
// 引数の追加
$parser->addArgument('files', array(
  'multiple'    => true,
  'description' => '処理するファイル'
));
// パーサの実行
try {
  $result = $parser->parse();
  print_r($result->options);
  print_r($result->args);
} catch (Exception $e) {
  $parser->displayError($e->getMessage());
}
?>

それでは、とりあえず何も指定せずに実行します。


$ php command_line.php


Error: You must provide at least 1 argument.
Type "command_line.php -h" to get help.

エラーメッセージにあるように「-h」をつけてみます。


$ php command_line.php -h


Console_CommandLineのサンプル
Usage:
  command_line.php [options] <files...>
Options:
  -d YYYYMMDD, --date=YYYYMMDD  対象となる日付
  -h, --help                    show this help message and exit
  -v, --version                 show the program version and exit
Arguments:
  files  処理するファイル

普通のコマンドのようなヘルプが表示されましたね。

それでは、パラメータを指定して実行してみます。


$ php command_line.php -d 20080807 filename1 filename2


Array
(
    [date] => 20080807
    [help] =>
    [version] =>
)
Array
(
    [files] => Array
        (
            [0] => filename1
            [1] => filename2
        )
)

連想配列に必要な情報がすべて入ってますね。あとはこれを利用して実際の処理を行うだけです。

なお、存在しないオプションを指定すると、きちんとエラーが表示されます。


$ php command_line.php -i


Error: Unknown option "-i".
Type "command_line.php -h" to get help.

また、「-v」や「--version」をつけて実行すると、バージョンが表示されます。


$ php command_line.php --version


command_line.php version 1.0.0.

また、面白い機能として、XMLでオプションの設定をすることもできるようです。

バッチ処理などPHPでコマンドラインスクリプトを作成する際、引数が複雑な場合はPEAR::Console_CommandLineを使ってみては如何でしょうか。