2011-06-24 9 views
2
<?php 
    fclose(STDIN); 
    fclose(STDOUT); 
    fclose(STDERR); 

    $STDIN = fopen("/tmp/some-named-pipe", "r"); 
    $STDOUT = fopen("/tmp/foo.out", "wb"); 
    $STDERR = fopen("/tmp/foo.err", "wb"); 

    echo "Hello, World!";     // goes to /tmp/foo.out, implied STDOUT 
    fscanf($STDIN, "%s\n", $top_secret); // explicit $STDIN, cant use STDIN 
?> 

新しいSTDOUTへのリダイレクトが暗黙的に機能するのはなぜですか?新しいSTDINからのリダイレクトは明示的に行われなければならないのはなぜですか?PHPでI/Oをリダイレクト

+0

出力は、私にとっては '/ tmp/foo.out'にはなりません。あなたはどのPHPのバージョンを使用していますか? –

+0

あなたが見ていると言っている$ STDOUTの動作を説明する文書はまったく見つかりません。 http://php.net/manual/en/wrappers.php.php http://php.net/manual/en/features.commandline.io-streams.php http://php.net/manual/ja/ language.variables.superglobals.php –

+0

バージョン5.30の使用 –

答えて

5

オリジナルのSTDIN、STDOUTおよびSTDERRは、PHPのシステム定数です。 PHPの初期化時に標準入力、出力、エラーのファイル記述子リソースが読み込まれます。

php.netのドキュメントは、定数内のリソースに関する次の内容について説明します。

定数の値。スカラ値とヌル値のみが許可されます。 スカラ値は整数、浮動小数点数、文字列またはブール値です。リソース定数を定義するには が可能ですが、これは推奨されません。 予期しない動作が発生する可能性があります。

fclose(STDOUT)が呼び出されると、ファイル記述子リソースは閉じられ、STDOUT定数から切り離されます。定数のデフォルト動作とは異なり、STDOUT定数は変更されます。

文字列がecho "Hello, World!"のようにエコーされると、PHPはSTDOUT定数を使用しませんが、オペレーティングシステムから現在の「標準出力」ファイル記述子をリアルタイムで照会します。さらに、STDOUT定数自体は一度fcloseされると使用不能になります。 fwrite(STDOUT, "hello")のような声明でさえ、ではなく、の仕事になります。

新しいファイルディスクリプタが標準出力用に構成されている場合、この新しいファイルディスクリプタは便利に$STDOUTに配置されます。これは定数ではなく変数であることに注意してください。 PHPでは定数を再定義することは定義上不可能であり、システム定数STDOUTも例外ではありません。現在、新しいファイル記述子をSTDOUT定数に再割り当てする方法はありません。

最終的にこの作業をより直感的に行うために、PHPチームはこれらのファイル記述子を再割り当てするか、少なくともシステム定数を「マジック定数」のように動作させるという便利な機能を実際のファイル記述子。

0

最初にスニペットを読むときは、まずSTDIN、STDOUTなどの定数を閉じるようにしてください。しかし、ファイルを開くのに同じ名前の変数を使用してください。したがって、作業している値はまったく異なります。$ STDINはSTDINと同じではありません。定義関数を使用してSTDINを再定義することは可能かもしれませんが、コンピュータがないと確認できません。

1

これはUNIX系システム(Linuxなど)でのみ発生します。プロセスでSTDIN、STDOUTとSTDERRが常にあるので、UNIXはマイナーなファイル記述子を使用したファイルを開く0,1と2 あなたが行う場合は、この:

fclose(STDIN); 
fclose(STDOUT); 
fclose(STDERR); 

$STDIN = fopen("/tmp/some-named-pipe", "r"); 
$STDOUT = fopen("/tmp/foo.out", "wb"); 
$STDERR = fopen("/tmp/foo.err", "wb"); 

あなたはSTDIN(0)、STDOUTを閉じています( 1)とSTDERR(2)と同じ順序でファイルを開くと、ファイル記述子として0,1,2が得られます。同じコードをウィンドウで実行すると、動作しません。

2

これは、stdoutを何度もリダイレクトする例です。 STDOUTのクローズは初めて機能しますが、次回は の$ STDOUTのクローズが必要です。

<?php 
# Redirecting 10 times ... 
# Need to close 'STDOUT' & '$STDOUT', otherwise the 2nd time 
# the redirecting fails. 

for ($i = 1; $i <= 10; $i++) 
{ 
    $sLogName = sprintf("reopen_%02d.log", $i); 
    echo "Redirecting to '" . $sLogName . "' ...\n"; 

    fclose(STDOUT); 
    fclose($STDOUT); # Needed for reopening after the first time. 

    $STDOUT = fopen($sLogName, "w"); 
    echo "Now logging in file '" . $sLogName . "' ...\n"; 
} 
?> 
関連する問題