PHP: PHPをコマンドラインから使用する - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<セーフモードにより制限を受けるか無効となる関数関数リファレンス>
view the version of this page
Last updated: Tue, 21 Dec 2004

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

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

CLI SAPIは、当初PHP 4.2.0でリ リースされましたが、この時点では実験的なステータスにあったため、 ./configureを実行する際に、明示的に --enable-cliを指定することにより、有効とする必要 がありました。PHP 4.3.0以降、 CLI SAPIはもはや実験的なステータスではなくなり、 --enable-cliはデフォルトでオンとなりました。 無効にする場合は--disable-cliを使用できます。

PHP4.3.0以降、システムにPHPがどのようにインストールされているかによって CLI/CGIバイナリの名前、位置、存在が異なります。デフォルトでは makeを実行するとCGIとCLIの両方がビルドされ ソースディレクトリのsapi/cgi/phpsapi/cli/phpにそれぞれ配置されます。両方とも phpという名前であることに注目してください。 make installでどうなるかはconfigureに因ります。 configureで例えばapxsのようなSAPIモジュールが選択された場合、または --disable-cgiが指定された場合、 make installによってCLIが{PREFIX}/bin/php にコピーされます。さもなければCGIがそこにコピーされます。 既にインストールされているCGIバイナリを上書きしたい場合には、 make installの後にmake install-cli を実行してください。あるいはconfigureで--disable-cgi を指定しておくこともできます。

注意: --enable-cli--enable-cgiの両方が デフォルトで有効になっているため、configureで--enable-cli をconfigureで指定しなくても必然的にmake installで CLIが{PREFIX}/bin/phpとしてコピーされます。

PHP4.2.0からPHP4.2.3までのWindowsパッケージではCLIは CGI php.exeと同じフォルダに php-cli.exeとして配布されていました。 PHP4.3.0からはWindowsパッケージではCLIはcliという 別のフォルダにphp.exeとして配布されます。 したがってcli/php.exeとなります。

自分のSAPIは何か?: シェルでphp -vをタイプすると、 phpがCGIなのかCLIなのかわかります。 php_sapi_name()と定数PHP_SAPI も参照してください。

注意: unixのmanualページがPHP4.3.2で追加されました。 シェル環境からman phpすることで見ることができます。

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

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

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

    デフォルトではCLIは静寂モードで起動されます。古いCGIスクリプトと互換性を 保って使えるように-qスイッチが残されています。

    動作するディレクトリはスクリプトの場所に変更されることはありません。 (-Cは互換性のために残されています)

    エラーメッセージはプレーンテキストで表示されます。 (HTMLでフォーマットされません)

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

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

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

    CLI SAPIを使用している場合、グローバル PHP変数$argc (アプリケーションに渡される引数の数)と $argv (引数の値の配列)は常に登録され、 適切な値が代入されます。

    PHP4.3.0以降、CLI SAPIを使用するときに PHP$argc変数と $argv変数が登録され、適切な値がセットされます。 このバージョンより前では、CGIMODULEがこれらの変数を生成するにはPHPの register_globals ディレクティブがオンになっている必要がありました。 バージョンやregister_globalsの設定がどうであろうと、 $_SERVERまたは $HTTP_SERVER_VARSは常に使用可能です。 例:$_SERVER['argv']

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

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

    表 42-2. CLI固有の定数

    定数説明
    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コードが続くスクリプトを書き、適当なファイル 実行属性を設定する(e.g. chmod +x test)ことが可能です。 この方法は、通常のシェル/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"
}
見て分かるように、-で始まるスクリプトのパラメー タを指定する際に、特に注意する必要はありません。

表 42-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以外のシェルを使用している場合には、別の問題を経験したことが あるかもしれません。バグレポートを作成するか [email protected]にメールを送ってください。 シェル変数をコードに取得しようとしたり、エスケープを行なうために バックスラッシュを使用したりした場合にも、容易に問題を発生する 可能性があります。注意が必要です。

-h このオプションを使用すると、実際の一連のコマンドラインオプションと 各1行の説明が情報を取得できます。

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

例 42-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では、この処理を行なう以下のようなバッチファイルを作成することが できます。

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

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

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

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



add a note add a note User Contributed Notes
PHPをコマンドラインから使用する
13-Mar-2005 09:52
Here is very simple, but usefull Command Line handler class. it may be usefull for your apps.


<?
require_once("CliHandler.class.php");

class
AnyClass{
  
public function start(){
       return
"started";
   }
  
public function stop(){
       return
"stoppded";
   }
}
$cli = new CliHandler(new AnyClass());
$cli->run();
?>

CliHandler accepts any class als argument.
Try this.

/usr/local/php/PHP5 CliHandler.class.php
output: Try these command:
start
stop
enter "start"
output: started
bertrand at toggg dot com
07-Mar-2005 04:40
If you want to pass directly PHP code to the interpreter and you don't have only CGI, not the CLI SAPI so you miss the -r option.
If you're lucky enough to be on a nix like system, then tou can still use the pipe solution as the 3. way to command CLI SAPI described above, using a pipe ('|').

Then works for CGI SAPI:

$ echo '<?php echo "coucou\n"; phpinfo(); /* or any code */ ?>' | php

NOTE: unlike commands passed to the -r option, here you NEED the PHP tags.
jeromenelson at gmail dot com
07-Mar-2005 09:21
This is the most simple way to get the named parameter.  Write the script test.php as ...

<?
  
echo "Yo! my name is ".$_REQUEST["name"]."\n";
?>

and run this program as follows

# php -f test.php name=Jerry
Yo! my name is Jerry

I am using PHP 4.3.3 (CGI) in Fedora Core 1 and It is working perfectly

God Bless You!
squeegee
04-Mar-2005 06:04
obfuscated at emailaddress dot com:

Try it without the php extension. Instead of the filename test.php, just use the filename test
obfuscated at emailaddress dot com
25-Feb-2005 04:15
This posting is not a php-only problem, but hopefully will save someone a few hours of headaches.  Running on MacOS (although this could happen on any *nix I suppose), I was unable to get the script to execute without specifically envoking php from the command line:

[macg4:valencia/jobs] tim% test.php
./test.php: Command not found.

However, it worked just fine when php was envoked on the command line:

[macg4:valencia/jobs] tim% php test.php
Well, here we are...  Now what?

Was file access mode set for executable?  Yup.

[macg4:valencia/jobs] tim% ls -l
total 16
-rwxr-xr-x  1 tim  staff  242 Feb 24 17:23 test.php

And you did, of course, remember to add the php command as the first line of your script, yeah?  Of course.

#!/usr/bin/php
<?php print "Well, here we are...  Now what?\n"; ?>

So why dudn't it work?  Well, like I said... on a Mac.... but I also occasionally edit the files on my Windows portable (i.e. when I'm travelling and don't have my trusty Mac available)...  Using, say, WordPad on Windows... and BBEdit on the Mac...

Aaahhh... in BBEdit check how the file is being saved!  Mac?  Unix?  or Dos?  Bingo.  It had been saved as Dos format.  Change it to Unix:

[macg4:valencia/jobs] tim% ./test.php
Well, here we are...  Now what?
[macg4:valencia/jobs] tim%

NB: If you're editing your php files on multiple platforms (i.e. Windows and Linux), make sure you double check the files are saved in a Unix format...  those \r's and \n's 'll bite cha!
db at digitalmediacreation dot ch
22-Feb-2005 07:49
A very important point missing here (I lost hours on it and hope to avoid this to you) :

* When using PHP as CGI
* When you just become crazy because of "No input file specified" appearing on the web page, while it never appears directly in the shell

Then I have a solution for you :

1. Create a script for example called cgiwrapper.cgi
2. Put inside :
 #!/bin/sh -
 export SCRIPT_FILENAME=/var/www/realpage.php
 /usr/bin/php -f $SCRIPT_FILENAME
3. Name your page realpage.php

For example with thttpd the problem is that SCRIPT_FILENAME is not defined, while PHP absolutely requires it.
My solution corrects that problem !
Flo
11-Feb-2005 12:03
On windows try ctrl-m or ctrl-z to run code in interactive (-a) mode
(*nix ctrl-d)
ken.gregg at rwre dot com
09-Jan-2005 09:38
If you want to use named command line parameters in your script,
the following code will parse command line parameters in the form
of name=value and place them in the $_REQUEST super global array.

cli_test.php
<?php

echo "argv[] = ";
print_r($argv);  // just to see what was passed in

if ($argc > 0)
{
  for (
$i=1;$i < $argc;$i++)
  {
  
parse_str($argv[$i],$tmp);
  
$_REQUEST = array_merge($_REQUEST, $tmp);
  }
}

echo
"\$_REQUEST = ";
print_r($_REQUEST);

?>

rwre:~/tmp$ /usr/local/bin/php cli_test.php foo=1 bar=2 third=a+value

argv[] = Array
(
   [0] => t.php
   [1] => foo=1
   [2] => bar=2
   [3] => third=a+value
)
$_REQUEST = Array
(
   [foo] => 1
   [bar] => 2
   [third] => a value
)
Mathieu BOIS
31-Dec-2004 12:20
Q: How to know whether we're in server or in script mode?

A (my proposal, there may be others, and maybe even a dedicated variable?):
<? if ($_SERVER['SERVER_PORT']) { echo "SERVER MODE"; } else { echo "CLI MODE"; } ?>

This can be useful, for instance if you want to send by mail a web php page that is also accessible by a browser.

Using this trick, you can then set a variable to make the links to the right location in all the relevant href=, src=, action= parameters (and may be other ones too: in stylesheets, javascripts...).
This needs also to be done in functions from included ("require") php files if they insert such tags. That's the reason why I've declared all of them as global variables below.

For instance, here is a part of "thisscript.php":

<?
 
if ($_SERVER['SERVER_PORT'])
   {
/* nothing */ }
  else
   {
    
$CLI_SERVERROOT= "";
    
$CLI_URL_DIR=$CLI_SERVERROOT."/path/to/";
    
$CLI_URL_FULL=$CLI_URL_DIR."thisscript.php";
     global
$CLI_SERVERROOT,$CLI_URL_DIR,$CLI_URL_FULL;
   }
?>

<link href="<? echo $GLOBALS["CLI_SERVERROOT"]; ?>/styles/nice.css" title="Nice stylesheet" rel="stylesheet" type="text/css">

<a href="<? echo $GLOBALS["CLI_URL_FULL"]; ?>?newparameter=543">chge param. to this script</a>
<a href="<? echo $GLOBALS["CLI_URL_DIR"]; ?>page2.php">local page</a>
<img src=<? echo $GLOBALS["CLI_SERVERROOT"]; ?>/icons/fax.png">
<img src=<? echo $GLOBALS["CLI_URL_DIR"]; ?>localimage.png">
Ben Jenkins
22-Dec-2004 05:23
This took me all day to figure out, so I hope posting it here saves someone some time:
Your PHP-CLI may have a different php.ini than your apache-php.  For example: On my Debian-based system, I discovered I have /etc/php4/apache/php.ini and /etc/php4/cli/php.ini
If you want MySQL support in the CLI, make sure the line
extension=mysql.so
is not commented out.
The differences in php.ini files may also be why some scripts will work when called through a web browser, but will not work when called via the command line.
david at acz dot org
23-Sep-2004 07:46
If you want an interactive command line shell for PHP to test out code, give phpa a try:

fabio at soi dot city dot ac dot uk
24-Aug-2004 05:06
This might seem obvious to many, but infact limits a lots the possibility of reusing software that runs on a web server.
In the command line version of PHP you cannot use session variables (because they exploit cookies). It appears that I cannot even read the $GLOBALS array.

Fabio
linn at backendmedia dot com
06-Feb-2004 02:12
For those of you who want the old CGI behaviour that changes to the actual directory of the script use:
chdir(dirname($_SERVER['argv'][0]));

at the beginning of your scripts.
ben at slax0rnet dot com
03-Feb-2004 03:34
Just a note for people trying to use interactive mode from the commandline.

The purpose of interactive mode is to parse code snippits without actually leaving php, and it works like this:

[root@localhost php-4.3.4]# php -a
Interactive mode enabled

<?php echo "hi!"; ?>
<note, here we would press CTRL-D to parse everything we've entered so far>
hi!
<?php exit(); ?>
<ctrl-d here again>
[root@localhost php-4.3.4]#

I noticed this somehow got ommited from the docs, hope it helps someone!
phprsr at mindtwin dot com
06-Aug-2003 04:12
The basic issue was that PHP-as-CGI REALLY REALLY wants SCRIPT_FILENAME.
It ignores the command line. It ignores SCRIPT_NAME.  It wants
SCRIPT_FILENAME.

"No input file specified."

This very informative error message from PHP means that your web server, WHATEVER it is, is not setting SCRIPT_FILENAME.

The minimum set of env variables:

PATH: DOESN'T MATTER if you're spawning php pages with #!/../php in them
LD_LIBRARY_PATH= should be right
SERVER_SOFTWARE=mini_httpd/1.17beta1 26may2002
SERVER_NAME=who cares
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.0
SERVER_PORT=whatever
REQUEST_METHOD=GET
SCRIPT_NAME=/foo.php
SCRIPT_FILENAME=/homes/foobie/mini/foo.php    <--- CRITICAL
QUERY_STRING==PHPE9568F35-D428-11d2-A769-00AA001ACF42
REMOTE_ADDR=172.17.12.80
HTTP_REFERER=
HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461; .NET CLR 1.0.3705; .NET CLR 1.1.4322)

If SCRIPT_FILENAME is not set, you'll get the dreaded "No input file specified" message.

mini_httpd does not do this by default. You need to patch it in to make_envp.

A secondary issue is configuration (PHP):

   ./configure --enable-discard-path --with-config-file-path=/homes/wherever/mini/php.ini
  
   (where php.ini is a slightly modified version of php.ini-recommended)
punk [_at_] studionew [_dot_] com
19-Jul-2003 11:18
You can use this function to ask user to enter smth

<?
function read ($length='255')
{
   if (!isset (
$GLOBALS['StdinPointer']))
   {
    
$GLOBALS['StdinPointer'] = fopen ("php://stdin","r");
   }
  
$line = fgets ($GLOBALS['StdinPointer'],$length);
   return
trim ($line);
}

// then

echo "Enter your name: ";
$name = read ();
echo
"\nHello $name! Where you came from? ";
$where = read ();
echo
"\nI see. $where is very good place.";
?>
Adam, php(at)getwebspace.com
17-Jun-2003 11:12
Ok, I've had a heck of a time with PHP > 4.3.x and whether to use CLI vs CGI. The CGI version of 4.3.2 would return (in browser):
---
No input file specified.
---

And the CLI version would return:
---
500 Internal Server Error
---

It appears that in CGI mode, PHP looks at the environment variable PATH_TRANSLATED to determine the script to execute and ignores command line. That is why in the absensce of this environment variable, you get "No input file specified." However, in CLI mode the HTTP headers are not printed. I believe this is intended behavior for both situations but creates a problem when you have a CGI wrapper that sends environment variables but passes the actual script name on the command line.

By modifying my CGI wrapper to create this PATH_TRANSLATED environment variable, it solved my problem, and I was able to run the CGI build of 4.3.2
monte at ispi dot net
04-Jun-2003 10:47
I had a problem with the $argv values getting split up when they contained plus (+) signs. Be sure to use the CLI version, not CGI to get around it.

Monte
Popeye at P-t-B dot com
18-Apr-2003 03:15
In *nix systems, use the WHICH command to show the location of the php binary executable. This is the path to use as the first line in your php shell script file. (#!/path/to/php -q) And execute php from the command line with the -v switch to see what version you are running.

example:

# which php
/usr/local/bin/php
# php -v
PHP 4.3.1 (cli) (built: Mar 27 2003 14:41:51)
Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies

In the above example, you would use: #!/usr/local/bin/php

Also note that, if you do not have the current/default directory in your PATH (.), you will have to use ./scriptfilename to execute your script file from the command line (or you will receive a "command not found" error). Use the ENV command to show your PATH environment variable value.
volkany at celiknet dot com
20-Feb-2003 09:44
Here goes a very simple clrscr function for newbies...
function clrscr() { system("clear"); }
Alexander Plakidin
14-Feb-2003 01:34
How to change current directory in PHP script to script's directory when running it from command line using PHP 4.3.0?
(you'll probably need to add this to older scripts when running them under PHP 4.3.0 for backwards compatibility)

Here's what I am using:
chdir(preg_replace('/\\/[^\\/]+$/',"",$PHP_SELF));

Note: documentation says that "PHP_SELF" is not available in command-line PHP scripts. Though, it IS available. Probably this will be changed in future version, so don't rely on this line of code...

Use $_SERVER['PHP_SELF'] instead of just $PHP_SELF if you have register_globals=Off
c dot kelly[no--spam] at qfsaustrlia dot com dot au
07-Feb-2003 04:03
In Windows [NT4.0 sp6a] the example
php -r ' echo getcwd();' does not work ; It appears you have to use the following php -r "echo getcwd();" --not the " around the command  to get the output to screen , just took me half an hour to figure out what was going on.
wanna at stay dot anonynous dot com
22-Jan-2003 05:42
TIP: If you want different versions of the configuration file  depending on what SAPI is used,just name them php.ini (apache module), php-cli.ini (CLI) and php-cgi.ini (CGI) and dump them all in the regular configuration directory. I.e no need to compile several versions of php anymore!
chris at free-source dot com
20-Jan-2003 10:23
The php binary that come with Mandrake (tested with 7.2, 8.2, 9.0) seems to not support -r <code>.  -r is not listed when running php -h and it gives you the -h if you try to use -r.
stuartc1 at hotmail dot com
13-Jan-2003 06:18
If you have an older version of PHP (for example 4.1.2 as I have have), and trying to execute a script from the windows NT command line then try this:

>c:\php\php -q c:\file_to_execute.php

note that you may need to execute from withing your php.exe directory as above. remeber to put the full path to the script you want to execute. The -q means quite mode and suppressed headers, you could also try -f or with no switches at all.
limberg at nospam dot grebmil dot port5 dot com
10-Jan-2003 11:39
The manual keeps referring to c:\php\cli\php.exe for windows.  I have no "cli" directory so I just tried c:\php\php.exe in my .bat file.  Not sure what the difference is but it seems to work fine on Win98 SE without any server installed or running.  Just though it might help someone.
phpnotes at ssilk dot de
22-Oct-2002 10:36
To hand over the GET-variables in interactive mode like in HTTP-Mode (e.g. your URI is myprog.html?hugo=bla&bla=hugo), you have to call

php myprog.html '&hugo=bla&bla=hugo'

(two & instead of ? and &!)

There just a little difference in the $ARGC, $ARGV values, but I think this is in those cases not relevant.
justin at visunet dot ie
21-Oct-2002 04:21
If you are trying to set up an interactive command line script and you want to get started straight away (works on 4+ I hope). Here is some code to start you off:

<?php

  
// Stop the script giving time out errors..
  
set_time_limit(0);

  
// This opens standard in ready for interactive input..
  
define('STDIN',fopen("php://stdin","r"));

  
// Main event loop to capture top level command..
  
while(!0)
   {
      
      
// Print out main menu..
      
echo "Select an option..\n\n";
       echo
"    1) Do this\n";
       echo
"    2) Do this\n";
       echo
"    3) Do this\n";
       echo
"    x) Exit\n";

      
// Decide what menu option to select based on input..
      
switch(trim(fgets(STDIN,256)))
       {
           case
1:
               break;
              
           case
2:
               break;

           case
3:
               break;

           case
"x":
               exit();
              
           default:
               break;
       }

   }

  
// Close standard in..
  
fclose(STDIN);

?>
phpNOSPAM at dogpoop dot cjb dot net
12-Oct-2002 03:28
Here are some instructions on how to make PHP files executable from the command prompt in Win2k.  I have not tested this in any other version of Windows, but I'm assuming it will work in XP, but not 9x/Me.

There is an environment variable (control panel->system->advanced->environment variables) named PATHEXT.  This is a list of file extensions Windows will recognize as executable at the command prompt.  Add .PHP (or .PL, or .CLASS, or whatever) to this list.  Windows will use the default action associated with that file type when you execute it from the command prompt.

To set up the default action:
Open Explorer.
Go to Tools->folder options->file types
Find the extension you're looking for.  If it's not there, click New to add it.
Click on the file type, then on Advanced, then New.
For the action, type "Run" or "Execute" or whatever makes sense.
For the application, type
  {path to application} "%1" %*
The %* will send any command line options that you type to the program.
The application field for PHP might look like
  c:\php\php.exe -f "%1" -- %*
(Note, you'll probably want to use the command line interface version php-cli.exe)
or for Java
  c:\java\java.exe "%1" %*
Click OK.
Click on the action that was just added, then click Set default.

If this helps you or if you have any changes/more information I would appreciate a note.  Just remove NOSPAM from the email address.
jeff at noSpam[] dot genhex dot net
06-Sep-2002 12:13
You can also call the script from the command line after chmod'ing the file (ie: chmod 755 file.php).

On your first line of the file, enter "#!/usr/bin/php" (or to wherever your php executable is located).  If you want to suppress the PHP headers, use the line of "#!/usr/bin/php -q" for your path.
zager[..A..T..]teleaction.de
15-Aug-2002 06:15
Under Solaris (at least 2.6) I have some problems with reading stdin. Original pbms report may be found here:

q=Re:+%5BPHP%5D+Q+on+php://stdin+--+an+answer!&hl=en&lr=&ie=UTF-
8&oe=UTF-8&selm=3C74AF57.6090704%40Sun.COM&rnum=1

At a first glance the only solution for it is 'fgetcsv'

#!/usr/local/bin/php -q
<?php

set_magic_quotes_runtime
(0);
$fd=fopen("php://stdin","r");
if (!
$fd)
  exit;

while (!
feof ($fd))
{
 
$s = fgetcsv($fd,128,"\n");
  if (
$s==false)
   continue;

  echo
$s[0]."\n";
}
?> 

But... keep reading....

>>> I wrote
Hello,
Sometimes I hate PHP... ;)

Right today I was trapped by some strange bug in my code with reading stdin using fgetcsv.
After a not small investigation I found that strings like "foo\nboo\ndoo"goo\n (take note of double quatation sign in it)
interpreted by fgetcsv like:
1->foo\nboo\ndoo
2->goo
since double quotation mark has a special meaning and get stripped off of the input stream.
Indeed, according to PHP manual:
[quote]
array fgetcsv ( int fp, int length [, string delimiter [, string enclosure]])

[skip]
another delimiter with the optional third parameter. _The_enclosure_character_is_double_quote_,_unless_
it_is_specified_.
[skip]
_enclosure_is_added_from_PHP 4.3.0.      !!!!!!
[/quote]

Means no chance for us prior to 4.3.0 :(
But file() works just fine !!!! Of course by the price of memory, so be careful with large files.

set_magic_quotes_runtime(0); // important, do not forget it !!!
$s=file("php://stdin");
for ($i=0,$n=sizeof($s);$i<$n;$i++)
{
  do_something_useful(rtrim($s[$i]));
}

Conclusion:
1. If you have no double quotation mark in your data use fgetcsv
2. From 4.3.0 use  fgetcsv($fd,"\n",""); // I hope it will help
3. If you data is not huge use file("php://stdin");

Hope now it's cleared for 100% (to myself ;)

Good luck!
Dim

PS. Don't forget that it's only Solaris specific problem. Under Linux just use usual fgets()...
jonNO at SPAMjellybob dot co dot uk
04-Aug-2002 04:17
If you want to get the output of a command use the function shell_exec($command) - it returns a string with the output of the command.
vboctor at hotmail dot com
27-Jun-2002 10:52
You will only be able to use $argc and $argv if you have in php.ini:
register_globals = On
register_argc_argv = On

If you have register_globals = Off, then you should use $_SERVER['argc'] and $_SERVER['argv'][0]. (recommended approach)

Also for some reason php "-c /my/path/php.ini" did not work for me.  I had to use "php -c /my/path/" which looks for php.ini in the specified path.  This is for PHP 4.2.1 (compiled under FreeBSD).
daveATtechweaversDOTnet
14-Jun-2002 07:46
a few missing d's in the handy function. here it is with the typos fixed

<?php
if (version_compare(phpversion(),'4.3.0','<'))
       {
      
define('STDIN',fopen("php://stdin","r"));
      
define('STDOUT',fopen("php://stdout","r"));
      
define('STDERR',fopen("php://stderr","r"));
      
register_shutdown_function( create_function( '' , 'fclose(STDIN);
       fclose(STDOUT); fclose(STDERR); return true;'
) );
       }
?>
ben-php dot net at wefros dot com
13-Jun-2002 10:40
PHP 4.3 and above automatically have STDOUT, STDIN, and STDERR openned ... but < 4.3.0 do not.  This is how you make code that will work in versions previous to PHP 4.3 and future versions without any changes:

<?php
  
if (version_compare(phpversion(),'4.3.0','<')) {
      
define('STDIN',fopen("php://stdin","r"));
define('STDOUT',fopen("php://stout","r"));
define('STDERR',fopen("php://sterr","r"));
      
register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STOUT); fclose(STERR); return true;' ) );
   }

/* get some STDIN up to 256 bytes */
  
$str = fgets(STDIN,256);
?>
ashley at dcs dot warwick dot ac dot uk
02-Apr-2002 09:05
If $argc and $argv seem to be undefined variables, check the settings of both register_globals and register_argc_argv in php.ini.
philip at cornado dot com
28-Feb-2002 10:53
PHP comes standard with a CLI (binary) as of 4.2.0+
philip at cornado dot com
25-Feb-2002 10:02
See also:
pyxl at jerrell dot com
18-Feb-2002 07:52
Assuming --prefix=/usr/local/php, it's better to create a symlink from /usr/bin/php or /usr/local/bin/php to target /usr/local/php/bin/php so that it's both in your path and automatically correct every time you rebuild.  If you forgot to do that copy of the binary after a rebuild, you can do all kinds of wild goose chasing when things break.
atomlinson at austin dot rr dot com
24-Jan-2002 06:28
To build the php exuecutable, you must run
configure *without* the '--with-apxs' option.
That option causes 'make' to build an apache
module.  I built php twice, once with '--with-apxs'
to build the apache module, and once without.
After compiling without, I copied the file 'php'
to a system bin directory (e.g., '/usr/local/bin').
temposeb at wanadoo dot fr
17-Nov-2001 07:32
Petite astuce pour saisir des donn�es au clavier lors de l'ex�cution d'un script (en mode console), on passe par un fichier :

$clavier = fopen('CON', 'r') ; //*** ou '/dev/tty' sous Linux
$s = fgets($clavier, 1024) ;
$s = chomp($s) ;
print("Vous avez saisi '$s'\n") ;
fclose($clavier) ;

S�b.

<セーフモードにより制限を受けるか無効となる関数関数リファレンス>
 Last updated: Tue, 21 Dec 2004
show source | credits | sitemap | contact | advertising | mirror sites 
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: /
Last updated: Mon Mar 14 08:13:06 2005 Local time zone must be set--see zic manual page