PHP
コマンドラインインターフェイス(CLI)
サーチ…
引数の処理
引数は、ほとんどのC言語に似た方法でプログラムに渡されます。 $argc
はプログラム名を含む引数の数を含む整数であり、 $argv
はプログラムへの引数を含む配列です。 $argv
の最初の要素はプログラムの名前です。
#!/usr/bin/php
printf("You called the program %s with %d arguments\n", $argv[0], $argc - 1);
unset($argv[0]);
foreach ($argv as $i => $arg) {
printf("Argument %d is %s\n", $i, $arg);
}
php example.php foo bar
(上記のコードがexample.phpに含まれています)で上記のアプリケーションを呼び出すと、次のような結果になります:
2つの引数を指定してexample.phpというプログラムを呼び出した
引数1はfooです。
引数2はbar
$argc
と$argv
は大域変数であり、大域変数ではないことに注意してください。関数で必要な場合は、 global
キーワードを使用してローカルスコープにインポートする必要があります。
この例では、 ""
や\
などのエスケープが使用されたときの引数のグループ化方法を示します。
スクリプト例
var_dump($argc, $argv);
コマンドライン
$ php argc.argv.php --this-is-an-option three\ words\ together or "in one quote" but\ multiple\ spaces\ counted\ as\ one
int(6)
array(6) {
[0]=>
string(13) "argc.argv.php"
[1]=>
string(19) "--this-is-an-option"
[2]=>
string(20) "three words together"
[3]=>
string(2) "or"
[4]=>
string(12) "in one quote"
[5]=>
string(34) "but multiple spaces counted as one"
}
PHPスクリプトが-r
を使用して実行されている場合:
$ php -r 'var_dump($argv);'
array(1) {
[0]=>
string(1) "-"
}
あるいは、 php
STDINにパイプされたコード:
$ echo '<?php var_dump($argv);' | php
array(1) {
[0]=>
string(1) "-"
}
入力と出力の処理
CLIから実行すると、定数STDIN 、 STDOUT 、およびSTDERRはあらかじめ定義されています。これらの定数はファイルハンドルであり、以下のコマンドを実行した結果と同等と見なすことができます。
STDIN = fopen("php://stdin", "r");
STDOUT = fopen("php://stdout", "w");
STDERR = fopen("php://stderr", "w");
定数は、標準のファイルハンドルがあればどこでも使用できます:
#!/usr/bin/php
while ($line = fgets(STDIN)) {
$line = strtolower(trim($line));
switch ($line) {
case "bad":
fprintf(STDERR, "%s is bad" . PHP_EOL, $line);
break;
case "quit":
exit;
default:
fprintf(STDOUT, "%s is good" . PHP_EOL, $line);
break;
}
}
ほとんどのコンテキストでは、以前に参照された組み込みのストリームアドレス( php://stdin
、 php://stdout
、 php://stderr
)をファイル名の代わりに使うことができます:
file_put_contents('php://stdout', 'This is stdout content');
file_put_contents('php://stderr', 'This is stderr content');
// Open handle and write multiple times.
$stdout = fopen('php://stdout', 'w');
fwrite($stdout, 'Hello world from stdout' . PHP_EOL);
fwrite($stdout, 'Hello again');
fclose($stdout);
代わりに、入力にreadline()を使用することもできますし、 echoやprintなどの文字列印刷関数を使用して出力することもできます。
$name = readline("Please enter your name:");
print "Hello, {$name}.";
リターンコード
exitコンストラクタを使用して、実行環境にリターンコードを渡すことができます。
#!/usr/bin/php
if ($argv[1] === "bad") {
exit(1);
} else {
exit(0);
}
デフォルトでは、何も指定されていない場合、つまりexit
がexit(0)
と同じ場合は、終了コード0
が返されexit(0)
。 exit
は関数ではないので、リターンコードが渡されていない場合はかっこは必要ありません。
リターンコードは0〜254の範囲でなければなりません(255はPHPで予約されているため使用しないでください)。通常、戻りコード0
で終了すると、呼び出し元プログラムにPHPスクリプトが正常に実行されたことが通知されます。ゼロ以外の戻りコードを使用して、特定のエラー状態が発生したことを呼び出し元のプログラムに伝えます。
プログラムオプションの処理
プログラムオプションはgetopt()
関数で処理できます。 POSIX getopt
コマンドと同様の構文で動作し、GNUスタイルのロングオプションを追加サポートしています。
#!/usr/bin/php
// a single colon indicates the option takes a value
// a double colon indicates the value may be omitted
$shortopts = "hf:v::d";
// GNU-style long options are not required
$longopts = ["help", "version"];
$opts = getopt($shortopts, $longopts);
// options without values are assigned a value of boolean false
// you must check their existence, not their truthiness
if (isset($opts["h"]) || isset($opts["help"])) {
fprintf(STDERR, "Here is some help!\n");
exit;
}
// long options are called with two hyphens: "--version"
if (isset($opts["version"])) {
fprintf(STDERR, "%s Version 223.45" . PHP_EOL, $argv[0]);
exit;
}
// options with values can be called like "-f foo", "-ffoo", or "-f=foo"
$file = "";
if (isset($opts["f"])) {
$file = $opts["f"];
}
if (empty($file)) {
fprintf(STDERR, "We wanted a file!" . PHP_EOL);
exit(1);
}
fprintf(STDOUT, "File is %s" . PHP_EOL, $file);
// options with optional values must be called like "-v5" or "-v=5"
$verbosity = 0;
if (isset($opts["v"])) {
$verbosity = ($opts["v"] === false) ? 1 : (int)$opts["v"];
}
fprintf(STDOUT, "Verbosity is %d" . PHP_EOL, $verbosity);
// options called multiple times are passed as an array
$debug = 0;
if (isset($opts["d"])) {
$debug = is_array($opts["d"]) ? count($opts["d"]) : 1;
}
fprintf(STDOUT, "Debug is %d" . PHP_EOL, $debug);
// there is no automated way for getopt to handle unexpected options
このスクリプトは次のようにテストすることができます:
./test.php --help
./test.php --version
./test.php -f foo -ddd
./test.php -v -d -ffoo
./test.php -v5 -f=foo
./test.php -f foo -v 5 -d
-v 5
が有効でないため、最後の方法は機能しません。
注意: PHP 5.3.0以降、
getopt
はOSに依存せず、Windowsでも動作します。
スクリプト実行をコマンドラインに制限する
関数php_sapi_name()
と定数PHP_SAPI
どちらも、PHPで使用されているインタフェースのタイプ( S erver API )を返します 。それらは、関数の出力がcli
と等しいかどうかをチェックすることによって、スクリプトの実行をコマンドラインに制限するために使用できます。
if (php_sapi_name() === 'cli') {
echo "Executed from command line\n";
} else {
echo "Executed from web browser\n";
}
drupal_is_cli()
関数は、スクリプトがコマンドラインから実行されたかどうかを検出する関数の例です。
function drupal_is_cli() {
return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}
スクリプトの実行
Linux / UNIXまたはWindowsの場合、スクリプトはPHP実行可能ファイルの引数として渡され、そのスクリプトのオプションと引数は次のようになります。
php ~/example.php foo bar
c:\php\php.exe c:\example.php foo bar
これは、 foo
とbar
を引数としてexample.php
渡しexample.php
。
Linux / UNIXでは、スクリプトを実行するための好ましい方法は、ファイルの最初の行にシバン (例: #!/usr/bin/env php
)を使用し、ファイルの実行可能ビットを設定することです。スクリプトがあなたのパスにあると仮定すると、それを直接呼び出すことができます:
example.php foo bar
/usr/bin/env php
を使うと、PATHを使ってPHP実行ファイルを見つけることができます。 PHPのインストール方法に従って、 /usr/bin/env
から一般的に入手できるenv
とは異なり、同じ場所( /usr/bin/php
や/usr/local/bin/php
)に置かないかもしれません。
Windowsでは、PHPのディレクトリとスクリプトをPATHに追加し、PATHEXTを編集してPATHを使って.php
を検出できるようにすることで、同じ結果が得られます。別の方法として、 example.bat
またはexample.cmd
という名前のファイルをPHPスクリプトと同じディレクトリに追加して、この行を書き込む方法もあります。
c:\php\php.exe "%~dp0example.php" %*
または、PHPのディレクトリをPATHに追加した場合、便利な使い方です:
php "%~dp0example.php" %*
コマンドラインでの動作の違い
CLIから実行すると、PHPはWebサーバーから実行される場合とは異なる動作を示します。これらの違いは、特に両方の環境から同じスクリプトを実行する場合に注意してください。
- ディレクトリの変更はありません 。Webサーバーからスクリプトを実行する場合、現在の作業ディレクトリは常にスクリプト自体のものです。コード
require("./stuff.inc");
ファイルがスクリプトと同じディレクトリにあると仮定します。コマンドラインで、現在の作業ディレクトリは、スクリプトを呼び出すときのディレクトリです。コマンドラインから呼び出されるスクリプトは、常に絶対パスを使用する必要があります。 (マジック定数__DIR__
と__FILE__
は引き続き期待通りに動作し、スクリプトの場所を返すことに注意してください)。 - 出力バッファリングなし
php.ini
ディレクティブoutput_buffering
とimplicit_flush
デフォルトはそれぞれfalse
とtrue
です。バッファリングは引き続き使用できますが、明示的に有効にする必要があります。そうでなければ、出力は常にリアルタイムで表示されます。 - 時間制限なし
php.ini
ディレクティブのmax_execution_time
はゼロに設定されているため、スクリプトはデフォルトでタイムアウトしません。 - HTMLエラーなし
php.ini
ディレクティブhtml_errors
を有効にした場合、コマンドラインで無視されます。 - 異なる
php.ini
を読み込むことができます 。 cliからphpを使用しているときは、Webサーバーとは異なるphp.ini
を使用できます。php --ini
実行すると、どのファイルが使用されているかを知ることができます。
内蔵Webサーバーの実行
バージョン5.4以降、PHPにはサーバーが組み込まれています。これは、nginxやapacheのような他のhttpサーバをインストールする必要なく、アプリケーションを実行するために使用できます。組み込みサーバーは、開発とテスト目的でコントローラー環境でのみ設計されています。
コマンドphp -Sで実行できます:
それをテストするには、 index.php
ファイルを含む
<?php
echo "Hello World from built-in PHP server";
コマンドphp -S localhost:8080
を実行します
今あなたはブラウザでコンテンツを見ることができるはずです。これを確認するには、 http://localhost:8080
に移動しhttp://localhost:8080
アクセスごとに、ログエントリが端末に書き込まれる必要があります
[Mon Aug 15 18:20:19 2016] ::1:52455 [200]: /
getopt()のエッジケース
この例は、ユーザー入力が珍しい場合のgetopt
の動作を示しています。
getopt.php
var_dump(
getopt("ab:c::", ["delta", "epsilon:", "zeta::"])
);
シェルコマンドライン $ php getopt.php -a -a -bbeta -b beta -cgamma --delta --epsilon --zeta --zeta=f -c gamma
array(6) {
["a"]=>
array(2) {
[0]=>
bool(false)
[1]=>
bool(false)
}
["b"]=>
array(2) {
[0]=>
string(4) "beta"
[1]=>
string(4) "beta"
}
["c"]=>
array(2) {
[0]=>
string(5) "gamma"
[1]=>
bool(false)
}
["delta"]=>
bool(false)
["epsilon"]=>
string(6) "--zeta"
["zeta"]=>
string(1) "f"
}
この例から、次のことが分かります。
- 個々のオプション(コロンなし)は、有効になっていると常にブール値
false
。 - オプションが繰り返されると、
getopt
の出力のそれぞれの値が配列になります。 - 必要な引数オプション(1つのコロン)は、区切り文字として1つの空白を受け入れます(オプションの引数オプションなど)
- オプションにマッピングできない1つの引数の後には、後ろのオプションもマップされません。