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

PHP マニュアル
前のページ |  | 次のページ

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

4.3以降で`PHP`は Command 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`と比べた時 の大きな違いを以下に示します。

- `CGI SAPI`と異なり、ヘッダが出力されません。

  `CGI SAPI`は、HTTPヘッダの出力を抑制する機能を 提供していますが、等価な機能は`CLI SAPI`ではサ ポートされていません。

- 以下に示すいくつかの`php.ini`ディレクティブは、`CLI SAPI`により上書きされます。これは、シェル環境では意味が ないためです。

  表 23-1上書きされる`php.ini`のディレクティブ

  ディレクティブ | `CLI SAPI`のデフォルト値 | コメント
  --- | --- | ---
  html_errors | `FALSE` | エラーメッセージに含まれる`HTML`タグはシェ ル上では意味がなく、可読性をかなり低下させるため、このディ レクティブはデフォルトで`FALSE`となっています。
  implicit_flush | `TRUE` | print(), echo()および 関連するものによる全ての出力は、直ちに出力され、バッファに キャッシュされないことが望ましいと言えます。この場合でも、 標準出力を保留または操作したい場合には、 output bufferingを使 用することが可能です。
  max_execution_time | 0 (unlimited) | シェル環境では、`PHP`を際限なく使用できる ようにするために、最大実行時間の制限は無しに設定されていま す。Web用アプリケーションは数秒単位で実行されるよう作られて いますが、シェルアプリケーションの実行時間は、これよりかな り長くなる傾向があります。
  register_argc_argv | `TRUE` | `CLI SAPI`を使用している場合、グローバル `PHP`変数`$argc` (アプリケーションに渡される引数の数)と `$argv` (引数の値の配列)は常に登録され、 適切な値が代入されます。

  > 注意 これらのディレクティブは、設定ファイル`php.ini`またはカスタム設 定ファイル(指定した場合のみ)で他の値に初期化できません。この制 限は、これらのデフォルト値が全ての設定ファイルをパースした後に 適用されるためです。しかし、これらの値は実行時に変更することが 可能です。 (上記のディレクティブの全てについてこれが当てはまるわけではあり ません。例えば、register_argc_argv)

- シェル環境での動作を容易とするために、以下の定数が定義されていま す。

  表 23-2CLI固有の定数

  定数 | 説明
  --- | ---
  `STDIN` | `stdin`へのオープン済みのストリーム。これ により、以下のようにオープンする必要がなくなります。
      $stdin = fopen('php://stdin', 'r');
  `STDOUT` | `stdout`へのオープン済みのストリーム。これ により、以下のようにオープンする必要がなくなります。
      $stdout = fopen('php://stdout', 'w');
  `STDERR` | `stderr`へのオープン済みのストリーム。これ により、以下のようにオープンする必要がなくなります。
      $stderr = fopen('php://stderr', 'w');

  上記のように、`stderr`のようなストリームを自分 でオープンする必要はなく、以下のようにストリームリソースの代わり に定数を使用するだけでかまいません。

      php -r 'fwrite(STDERR, "stderr\n");'

  これらのストリームを明示的に閉じる必要はありません。これは、 `PHP`により自動的に行われます。

- `CLI SAPI`は、実行されるスクリプトのディレクト リにカレントディレクトリを変更しません !

  `CGI SAPI`との違いを示す例を以下に示します。

      <?php
          /* Our simple test application */
          echo getcwd(), "\n";
      ?>

  `CGI`版により実行した場合、出力は以下のようにな ります。

      $ pwd
      /tmp

      $ php-cgi -f another_directory/test.php
      /tmp/another_directory

  これは、`PHP`が実行するスクリプトのディレクトリ にカレントディレクトリを変更することを明らかに示しています。

  `CLI SAPI`を使用した場合の出力は次のようになり ます。

      $ pwd
      /tmp

      $ php -f another_directory/test.php
      /tmp

  これにより、`PHP`でシェルツールを書く際の柔軟性 をより大きくすることができます。

  > 注意 `CGI SAPI`は、この`CLI SAPI` の動作をコマンドライン実行時のスイッチ`-C`によ りサポートしています。

`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"
    }

見て分かるように、`-`で始まるスクリプトのパラメー タを指定する際に、特に注意する必要はありません。

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

オプション | 説明
--- | ---
-s | カラー構文ハイライト表示されたソースを表示します。 このオプションは、ファイルをパースし、`HTML` ハイライト表示版のファイルを生成し、標準出力に書き出す内部機 構を使用します。行うのは、 `<code> [...] </code>`のブロック を生成することだけで、`HTML`ヘッダは出力され ないことに注意して下さい。 注意 このオプションは、`-r`オプションと同時に使 用することはできません。
-w | コメントと空白文字を削除してソースを表示します。 注意 このオプションは、`-r`オプションと同時に使 用することはできません。
-f | `-f`オプションに指定したファイル名をﾊﾟｰｽし、 実行します。このスイッチはオプションで省略することもできます。 実行するスクリプトを指定するだけで充分です。
-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 | このオプションにより `php.ini` で指定できる設定ディレクティブ にカスタム値を設定することができます。構文は以下のようになります。
    -d configuration_directive[=value]
例:
    # 値の部分を省略すると、設定ディレクティブに"1"を指定します
    $ php -d max_execution_time -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
    string(1) "1"

    # 空の値を渡すと設定ディレクティブに""を設定します
    php -d max_execution_time= -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
    string(0) ""

    # 設定ディレクティブは文字'='の後に指定したものを設定します
    $  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 | Zendエクステンションをロードします。ファイル名のみが指定された場合、 PHPはこの拡張をカレントのシステムのデフォルトライブラリパスから ロードしようとします。 (Linuxシステムの場合は`/etc/ld.so.conf`で 指定されています) ファイル名を絶対パスで指定した場合、システムのライブラリサーチパスを 使用しません。ディレクトリ情報を有する相対ファイル名を 指定すると、`PHP`は、 カレントのディレクトリの相対パスから拡張モジュールをロードする ことのみを行ないます。
-l | このオプションにより、指定した`PHP`コードの 構文チェックのみを簡単に行なうことができます。成功した場合、 テキスト `No syntax errors detected in <filename>` が、標準出力に書き込まれ、リターンコードは`0` となります。失敗した場合、テキスト `Errors parsing <filename>` に加えて、内部パーサエラーメッセージ が標準出力に書き込まれ、シェルリターンコードは、 `255`となります。 このオプションは、(未定義の関数のような)致命的なエラー(fatal error) はみつけません。致命的なエラーについても調べたい場合は、 `-f` を使用してください。 注意 このオプションは、オプション`-r`と共に使用することは できません。
-m | このオプションを使用すると、PHPは、PHPに組み込まれた (そしてロードされた) Zend モジュールを出力します。
    $ php -m
    [PHP Modules]
    xml
    tokenizer
    standard
    session
    posix
    pcre
    overload
    mysql
    mbstring
    ctype

    [Zend Modules]
-i | このコマンドラインオプションは、phpinfo()をコールし、 結果を出力します。`PHP` が正しく動作していない場合、 `php -i`を実行し、情報テーブルの前または中に出力 されるエラーメッセージを調べることをお勧めします。 出力は、`HTML` 形式で行なわれるため、かなり量が 多くなることに注意して下さい。
> -r | このオプションにより、コマンドラインのみで`PHP` の実行ができるようになります。 `PHP`の開始および終了タグ (`<?php` および `?>`) は不要で、これらを付けると パーサエラーとなります。 注意 このように`PHP`を実行する際に、コマンドラインの 変数がシェルにより行なわれる置換と干渉しないように注意して下さい。 パーサエラーを生じる例
>     $ php -r "$foo = get_defined_constants();"
>     Command line code(1) : Parse error - parse error, unexpected '='
> ここでの問題は、2重引用符 `"` を用いた場合でも sh/bashが変数置換を行うことです。 `$foo`はおそらく定義されていないので、 空文字列に展開された後、実行用に`PHP`に そのコードが渡され、以下のように読み込むことになります。
>     $ php -r " = get_defined_constants();"
> 正しい方法は、1重引用符`'`を使用することです。 1重引用符で括られた文字列の中の変数は、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"]=>
>       [...]
sh/bash以外のシェルを使用している場合には、別の問題を経験したことが あるかもしれません。バグレポートを作成するか phpdoc@lists.php.netにメールを送ってください。 シェル変数をコードに取得しようとしたり、エスケープを行なうために バックスラッシュを使用したりした場合にも、容易に問題を発生する 可能性があります。注意が必要です。
-h | このオプションを使用すると、実際の一連のコマンドラインオプションと 各1行の説明が情報を取得できます。

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

例 23-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];
    }
    ?>

上のスクリプトでは、特殊な先頭行が用いられており、このファイルが PHPにより実行されることを示しています。ここではCLI版を使用しているため、 HTTPヘッダは出力されません。PHPで コマンドラインアプリケーションを使用する際には、2つの変数 `$argc` and `$argv` を使用することが できます。 最初の変数は、引数の数に1(実行中のスクリプトの名前)を加えたものです。 2番目の変数は、引数を保持する配列で、スクリプト名を有する 要素0(`$argv[0]`)から始まっています。

上のプログラムでは、引数が1より少ないかまたは多いかを調べています。 また、引数が `--help`, `-help`, `-h`, `-?`の場合、 ヘルプメッセージを出力し、動的にスクリプト名を出力します。 他の引数を受け取った場合、これを出力します。

上のスクリプトをUnixで実行する場合、実行可能とした後、 `script.php echothis` または `script.php -h` とする必要があります。 Windowsでは、この処理を行なう以下のようなバッチファイルを作成することが できます。

例 23-2 コマンドラインPHPスクリプトを実行するバッチファイル(script.bat)
    @c:\php\php.exe script.php %1 %2 %3 %4

上のプログラムが`script.php`という名前であると し、`c:\php\php.exe`に`php.exe` があるとすると、このバッチファイルは、追加したオプション `script.bat echothis` または `script.bat -h` を指定して、スクリプトを実行します。

PHPのコマンドラインアプリケーションを拡張するために使用できる その他の関数については、拡張モジュール Readlineに関する ドキュメントも参照してください。

前のページ | ホーム | 次のページ
セーフモード | 上に戻る | 関数リファレンス