第 24 章 PHPをコマンドラインから使用する

4.3以降でPHPCommand Line Interfaceを意味する CLIという名前の新しいSAPI型 (Server Application Programming Interface)をサポートします。 名前から分かるように、このSAPI型は、 PHPによるシェル(またはデスクトップ)アプリケーショ ンの開発を主な対象としています。 CLI SAPIと他のSAPIの間には、 いくつかの違いがあります。本章では、これらについて詳細を説明します。

CLI SAPIは、当初PHP 4.2.0でリ リースされましたが、この時点では実験的なステータスにあったため、 ./configureを実行する際に、明示的に --enable-cliを指定することにより、有効とする必要 がありました。PHP 4.3.0以降、 CLI SAPIはもはや実験的なステータスではなくなりま した。このため、 常に構築され、 php(Windowsではphp.exeと いう名前となります)バイナリとしてインストールされます。

CLI SAPIを他のSAPIと比べた時 の大きな違いを以下に示します。

PHPバイナリにより提供されるコマンドラインオプショ ンの一覧は、-hスイッチを指定して PHPを実行することによりいつでも調べることができ ます。
Usage: php [options] [-f] <file> [args...]
       php [options] -r <code> [args...]
       php [options] [-- args...]
  -s               Display colour syntax highlighted source.
  -w               Display source with stripped comments and whitespace.
  -f <file>        Parse <file>.
  -v               Version number
  -c <path>|<file> Look for php.ini file in this directory
  -a               Run interactively
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -z <file>        Load Zend extension <file>.
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -i               PHP information
  -r <code>        Run PHP <code> without using script tags <?..?>
  -h               This help

  args...          Arguments passed to script. Use -- args when first argument 
                   starts with - or script is read from stdin

CLI SAPIは、実行するPHPコード を取得するために三種類の異なる手段をサポートしています。

  1. PHPに特定のファイルの実行を指示する。

    php my_script.php
    
    php -f my_script.php
    上記の方法は共に(-fスイッチの使用の如何に関ら ず)指定したファイルmy_script.phpを実行しま す。実行ファイルとしてあらゆるファイルを指定することができ、 PHPスクリプトは拡張子 .phpで終わる必要がなく、任意の名前や拡張子 を使用することができます。

  2. 実行するPHPコードをコマンドラインで直接指定する。

    php -r 'print_r(get_defined_constants());'
    シェル変数の置換と引用符の使用については特に注意して下さい。

    注意 この例をよくみて下さい。開始/終了タグがありません! -rスイッチを使用した場合、これらのタグは不要 となります。これらのタグを使用するとパーサエラーを発生します。

  3. 実行するPHPコードを標準入力 (stdin)で指定する。

    これは強力な機能で、以下の(仮想的な)例に示すように、動的に PHPコードを生成し、実行バイナリに入力すること ができます。
    $ some_application | some_filter | php | sort -u >final_output.txt

これらのコードを実行する三種類の方法を組み合わせて使用することはで きません。

他のシェルアプリケーションのように、PHPバイナリ に引数を指定することができるだけでなく、PHPスク リプトがこの引数を取得することも可能です。スクリプトに指定できる引 数の数はPHPによる制限を受けません。 (シェルは指定可能な文字数の最大値を設定しています。通常、この制限値 を越えることはできません。) スクリプトに指定した引数は、グローバル 配列$argvでアクセス可能です。 添字0は、常にスクリプト名が含まれています。 ( PHPコードが標準入力またはコマンドラインスイッ チ-rにより指定された場合、スクリプト名は -となります。) 登録される第2のグローバル変数は$argcで、 (スクリプトに指定された引数の数ではなく 、)配列$argvの要素数が含まれます。

スクリプトに指定する引数が文字-で始まっていない 限り、特に留意すべきことはありません。スクリプトに指定する引数が文 字-で始まる場合、PHP自体がこ れをパースする必要があるとみなすため、問題を発生します。 これを防止するため、引数リストセパレータ--を使用 して下さい。PHPにパースされる引数の後に このセパレータを置くと、その後の全ての引数はそのままパースされずに スクリプトに渡されます。

# This will not execute the given code but will show the PHP usage
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# This will pass the '-h' argument to your script and prevent PHP from showing it's usage
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

また、PHPをシェルスクリプトとして使用する他の 手段があります。最初の行が#!/usr/bin/phpで始まり、 PHPの開始/終了タグの中に通常の PHPコードが続くスクリプトを書き、適当なファイル 実行属性を設定することが可能です。この方法は、通常のシェル/Perlスク リプトと同様に実行することができます。
#!/usr/bin/php
<?php
    var_dump($argv);
?>
このファイルの名前がtestで、カレントディレクト リにあるとすると、以下のように実行することができます。
$ chmod 755 test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}
見て分かるように、-で始まるスクリプトのパラメー タを指定する際に、特に注意する必要はありません。

表 24-3コマンドラインオプション

オプション説明
-s

カラー構文ハイライト表示されたソースを表示します。

このオプションは、ファイルをパースし、HTML ハイライト表示版のファイルを生成し、標準出力に書き出す内部機 構を使用します。行うのは、 <code> [...] </code>のブロック を生成することだけで、HTMLヘッダは出力され ないことに注意して下さい。

注意 このオプションは、-rオプションと同時に使 用することはできません。

-w

コメントと空白文字を削除してソースを表示します。

注意 このオプションは、-rオプションと同時に使 用することはできません。

-f

Parses and executed the given filename to the -f option. This switch is optional and can be left out. Only providing the filename to execute is sufficient.

-v

PHP, PHP SAPI, Zendのバージョンを標準出力に出力します。例:
$ php -v
PHP 4.3.0-dev (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.2.1, Copyright (c) 1998-2002 Zend Technologies

-c

このオプションを使用することにより、php.iniを探すディレクト リを指定したり、カスタマイズされたINIファ イル(php.iniという名前である必要はありません)を直接指定する ことが可能です。例:
$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php

-a

PHPを対話的に実行します。

-d

This option allows to set a custom value for any of the configuration directives allowed in php.ini. The syntax is:
-d configuration_directive[=value]

例:
# Ommiting the value part will set the given configuration directive to "1"
$ php -d max_execution_time -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# Passing an empty value part will set the configuration directive to ""
php -d max_execution_time= -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# The configuration directive will be set to anything passed after the '=' character
$  php -d max_execution_time=20 -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php -d max_execution_time=doesntmakesense -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"

-e

デバッガ/プロファイラ用の拡張情報を出力します。

-z

Load Zend extension. If only a filename is given, PHP tries to load this extension from the current default library path on your system (usually specified /etc/ld.so.conf on Linux systems). Passing a filename with an absolute path information will not use the systems library search path. A relative filename with a directory information will tell PHP only to try to load the extension relative to the current directory.

-l

This option provides a convenient way to only perform a syntax check on the given PHP code. On succes, the text No syntax errors detected in <filename> is written to standard output and the shell return code is 0. On failure, the text Errors parsing <filename> in addition to the internal parser error message is written to standard output and the shell return code is set to 255.

This option won't find fatal errors (like undefined functions). Use -f if you would like to test for fatal errors too.

注意 This option does not work together with the -r option.

-m

Using this option, PHP prints out the built in (and loaded) PHP and Zend modules:
$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]

-i This command line option calls phpinfo(), and prints out the results. If PHP is not working well, it is advisable to make a php -i and see if any error messages are printed out before or in place of the information tables. Beware that the output is in HTML and therefore quite huge.
-r

This option allows execution of PHP right from within the command line. The PHP start and end tags (<?php and ?>) are not needed and will cause a parser errors.

注意 Care has to be taken when using this form of PHP to not collide with command line variable substitution done by the shell.

Example showing a parser error
$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '='
The problem here is that the sh/bash performs variable substritution even when using double quotes ". Since the variable $foo is unlikely to be defined, it expands to nothing which results in being the code passed to PHP for executin in fact reads:
$ php -r " = get_defined_constants();"
The correct way would be to use single quotes '. variables in strings quoted with single quotes are not expanded by sh/bash.
$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]
If you are using a shell different from sh/bash, you might experience further issues. Feel free to open a bug report or send a mail to phpdoc@lists.php.net. One still can easily run intro troubles when trying to get shell variables into the code or using backslashes for escaping. You've been warned.

-h With this option, you can get information about the actual list of command line options and some one line descriptions about what they do.

PHP実行バイナリは、Webサーバから完全に独立してPHPスクリプトを実行す るために使用することができます。Unixシステムを使用している場合、実 行可能とするために、PHPスクリプトの先頭に特別な一行を追加する必要が あります。これにより、システムがそのスクリプトを実行するプログラム を知ることができます。 Windows環境では、.phpファイルのダブルクリックオ プションにphp.exeを関連づけることができます。 または、PHPによりスクリプトを実行するバッチファイルを作成することも 可能です。Unix上で動作させるためにスクリプトに追加された先頭行は、 Windows環境での動作に悪影響を与えません。このため、この手法により、 黒須プラットフォーム環境で動作するプログラムを書くことができます。 コマンドラインPHPプログラムの書方の簡単な例を以下に示します。

例 24-1 コマンドラインから実行されることを意図したスクリプト(script.php)

#!/usr/bin/php
<?php

if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>

This is a command line PHP script with one option.

  Usage:
  <?php echo $argv[0]; ?> <option>

  <option> can be some word you would like
  to print out. With the --help, -help, -h,
  or -? options, you can get this help.

<?php
} else {
    echo $argv[1];
}
?>

In the script above, we used the special first line to indicate, that this file should be run by PHP. We work with a CLI version here, so there will be no HTTP header printouts. There are two variables you can use while writing command line applications with PHP: $argc and $argv. The first is the number of arguments plus one (the name of the script running). The second is an array containing the arguments, starting with the script name as number zero ($argv[0]).

In the program above we checked if there are less or more than one arguments. Also if the argument was --help, -help, -h or -?, we printed out the help message, printing the script name dynamically. If we received some other argument we echoed that out.

If you would like to run the above script on Unix, you need to make it executable, and simply call it as script.php echothis or script.php -h. On Windows, you can make a batch file for this task:

例 24-2 コマンドラインPHPスクリプトを実行するバッチファイル(script.bat)

@c:\php\php.exe script.php %1 %2 %3 %4

Assuming, you named the above program as script.php, and you have your php.exe in c:\php\php.exe this batch file will run it for you with your added options: script.bat echothis or script.bat -h.

See also the Readline extension documentation for more functions you can use to enhance your command line applications in PHP.