質問

私は C と C++ のバックグラウンドを持っていますが、Web のものも少しいじっています。私たち C の人々は全員 (おそらく)、その呼びかけを知っています。 feofFILE* 読み取りを実行する前はエラーです。これは、C および C++ の初心者にとって非常に頻繁に悩まされることです。これはPHPの実装にも当てはまりますか?

ファイルがソケットなど、読み取りを完了する前にサイズを知ることができないものである可能性があるためだと思います。しかし、ほぼすべての PHP サンプル ( php.net 私は次のようなものを見てきました(そして私の頭の中で警報が鳴りました):

$f = fopen("whatever.txt", "rb");
while(!feof($f)) {
    echo fgets($f);
}
fclose($f);

この問題を回避するには、次のように記述することが望ましいことはわかっています。

$f = fopen("whatever.txt", "rb");
while($line = fgets($f)) {
    echo $line;
}
fclose($f);

しかし、それは問題ではありません。「間違った方法」で実行した場合に問題が発生するかどうかをテストしてみましたが、間違った動作を引き起こすことはできませんでした。これは厳密には科学的ではありませんが、試してみる価値はあると思いました。

それで、呼ぶのは間違っていますか? feof 前に fread PHPで?

PHP では C バージョンとは異なる方法でこれを行うことができる方法がいくつかありますが、それらには欠点があると感じています。

  • デフォルトを !EOF に設定することもできます。これは、特殊なケースでは正しくない可能性があるため、最適とは言えません。

  • 実行中にファイル サイズを取得できる可能性があります。 fopen ただし、これはすべての種類のファイル リソースで機能するわけではなく、一貫性のない動作が発生し、速度が遅くなります。

役に立ちましたか?

解決

PHP は、ファイルから読み取ろうとするまで、それがファイルの最後にあるかどうかを知りません。この簡単な例を試してください。

<?php 
$fp = fopen("/dev/null","rb"); 
while (!feof($fp)) { 
    $data = fread($fp, 1);
    echo "read " . strlen($data) . " bytes";  
} 
fclose($fp); 
?>

1行の読み取りが得られます read 0 bytes. 。feof() は、技術的にはファイルの最後にいたにもかかわらず true を返しました。通常、これは問題を引き起こしません。 fread($fp, 1) データは返されません。また、実行している処理がデータを返さない場合でも問題なく処理されます。ファイルの最後にいるかどうかを本当に知る必要がある場合は、最初に読み取りを行う必要があります。

他のヒント

これは答えというより質問かもしれませんが、なぜ使用しないのですか file_get_contents()?私の経験では、ファイルまたはストリームを読み取っている場合、この関数が面倒な作業を行ってくれます (リソース全体を文字列に読み込むか、制限とオフセットを知っている/計算できると仮定します)。その姉妹関数 file_put_contents() は、逆にうまく機能します。

たとえば、次のような例があります。

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("/path/to/file.txt");
if ($expected_content != $real_content){
   file_put_contents("/path/to/file.txt", $real_content);
}

またはストリーム:

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("http://host.domain.com/file.txt");
if ($expected_content != $real_content){
   $options = array('ftp' => array('overwrite' => true));
   $stream = stream_context_create($options); 
   file_put_contents("ftp://user:pass@host.domain.com/file.txt", $real_content, 0, $stream);
}

そうすれば、EOF などについて心配する必要はありません。自動的に実行されます (ftp put は少し危険ですが、大丈夫です)。もちろん、これがすべての状況で機能するわけではありません...

このアプローチを実行不可能にする、元の質問に欠けているものはありますか?

電話をかけないことについてのあなたの主張 feof 前に fread は正しくありません。したがって、質問は無効です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top