2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

phpでコマンドラインスクリプトのオプション制御

Posted at

$argv

特に説明は無いマニュアルどおり
$argv

cmd.php
# !/usr/local/bin/php -q
<?php
var_dump($argv);

実行

./cmd.php aaa bbb ccc -ddd -eee
array(6) {
  [0]=>
  string(9) "./cmd.php"
  [1]=>
  string(3) "aaa"
  [2]=>
  string(3) "bbb"
  [3]=>
  string(3) "ccc"
  [4]=>
  string(2) "-d"
  [5]=>
  string(5) "--eee"
}

getopt

bashのgetoptと思うとかなり劣化版(想定外のオプションの制御が効かないなど)だけど人力$argvを解析するより遥かにマシ
ガッチリ組むならPEAR::Console_CommandLineが良い
→解説は「コマンドラインの引数解析を簡単に!」が親切

commander.php
# !/usr/local/bin/php -q
<?php
//[-h]など一文字で制御する方法
$shortopts = 'h';//スイッチだけ
$shortopts .= 'a:';//:は値を必須で受け取る
$shortopts .= 'b::';//::は値を任意に受け取る
$shortopts .= 'c:';//:は値を必須で受け取る

//([--help]など長名で制御する方法)
$longopts[] = 'help';//スイッチだけ
$longopts[] = 'aaa:';//:は値を必須で受け取る
$longopts[] = 'bbb::';//::は値を任意に受け取る
$longopts[] = 'ddd::';//::は値を任意に受け取る

$options = getopt($shortopts, $longopts);
if($options === false){
  fputs(STDERR, "There was a problem reading in the options.\n" . print_r($argv, true));
  exit(1);
}
$output='';

if(isset($options['h']) || isset($options['help'])){
  $output =<<<'EOL'
-h [--help]  helpこのコマンド
-a [--aaa]   あああ
-b [--bbb]   ビビビ
-c           シシシ
--ddd        デデデ

EOL;
  echo $output;
  exit(0);
}

var_dump($options);

実行

$ ./commander.php -h
-h [--help]  helpこのコマンド
-a [--aaa]   あああ
-b [--bbb]   ビビビ
-c           シシシ
--ddd        デデデ

$ ./commander.php --help
-h [--help]  helpこのコマンド
-a [--aaa]   あああ
-b [--bbb]   ビビビ
-c           シシシ
--ddd        デデデ
# 一般的なヘルプ

$ ./commander.php -a
array(0) {
}
# ↑値が無いがないので空

$ ./commander.php -a ZZZ
array(1) {
  ["a"]=>
  string(3) "ZZZ"
}

$ ./commander.php -aZZZ
array(1) {
  ["a"]=>
  string(3) "ZZZ"
}

$ ./commander.php -a=ZZZ
array(1) {
  ["a"]=>
  string(3) "ZZZ"
}

# ↑値の入力はスペース区切り、続けて入力、=区切りで可能

$ ./commander.php -a X -a=Y -aZ
array(1) {
  ["a"]=>
  array(3) {
    [0]=>
    string(1) "X"
    [1]=>
    string(1) "Y"
    [2]=>
    string(1) "Z"
  }
}
# 複数の値を受け付けられる

# 但し↓のように必須optに引数を与え無いと、後続が引数扱いになる
$ ./commander.php -a -b=XXX
array(1) {
  ["a"]=>
  string(6) "-b=XXX"
}

$ ./commander.php -a= -bXXX --aaa= -bYYY
array(2) {
  ["a"]=>
  string(0) ""
  ["b"]=>
  array(2) {
    [0]=>
    string(3) "XXX"
    [1]=>
    string(3) "YYY"
  }
}
# 値指定に `=` を使えば回避できそうだが単optに=をつけると空文字が入る

# ↓任意optの場合は正しく解析できる
$ ./commander.php -b -a=XXX
array(2) {
  ["b"]=>
  bool(false)
  ["a"]=>
  string(3) "XXX"
}



$ ./commander.php --aaa=XXX --aaaYYY --aaa ZZZ -c " " --ddd
array(3) {
  ["aaa"]=>
  array(2) {
    [0]=>
    string(3) "XXX"
    [1]=>
    string(3) "ZZZ"
  }
  ["c"]=>
  string(1) " "
  ["ddd"]=>
  bool(false)
}

# 長名オプションも扱いはほとんど同じ
# ただ `-aaaYYY` のように長名だと連結指定出来ない(そりゃそうだ)

総括

phpでコマンドオプションの制御をする場合は原則、長名オプションを使った方が誤作動が少ない
on/offのスイッチなら単名オプションでも可
オプションの厳密な制御が必要ならPEAR::Console_CommandLineを使うべき

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?