Frage

Ich komme aus einem C- und C ++ - Hintergrund, spiele aber auch mit einigen Web-Sachen.Alle Us-C-Leute kennen (hoffentlich) diese Berufung feof auf einem FILE* vor dem Lesen ist ein Fehler.Dies ist etwas, das Neulinge in C und C ++ sehr oft sticht.Ist dies auch bei der Implementierung von PHP der Fall?

Ich denke, es muss daran liegen, dass die Datei ein Socket oder irgendetwas anderes sein könnte, bei dem es unmöglich ist, die Größe vor dem Lesen zu kennen.Aber fast jedes PHP-Beispiel (auch die auf php.net Ich habe so etwas gesehen (und in meinem Kopf gehen Alarme los):

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

Ich weiß, dass es vorzuziehen ist, dies so zu schreiben und dieses Problem zu vermeiden:

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

aber das ist nicht der Punkt.Ich habe versucht zu testen, ob die Dinge fehlschlagen würden, wenn ich es "falsch" machen würde, aber ich konnte es nicht dazu bringen, falsches Verhalten zu verursachen.Das ist nicht gerade wissenschaftlich, aber ich dachte, es wäre einen Versuch wert.

Ist es also falsch anzurufen feof vor einem fread mit PHP?

Es gibt ein paar Möglichkeiten, wie PHP dies anders hätte machen können als die Version von C, aber ich glaube, sie haben Nachteile.

  • sie könnten es standardmäßig haben!EOF.Dies ist suboptimal, da es für einige Eckfälle möglicherweise falsch ist.

  • sie könnten die Dateigröße während eines fopen aufruf, aber dies könnte nicht bei allen Arten von Dateiressourcen funktionieren, was zu inkonsistentem Verhalten führt und langsamer wäre.

War es hilfreich?

Lösung

PHP weiß nicht, ob es sich am Ende der Datei befindet, bis Sie versucht haben, daraus zu lesen.Probieren Sie dieses einfache Beispiel aus:

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

Sie erhalten eine Zeile Lesung read 0 bytes.feof() hat true zurückgegeben, obwohl Sie technisch am Ende der Datei waren.Normalerweise verursacht dies kein Problem, weil fread($fp, 1) gibt keine Daten zurück, und bei jeder Verarbeitung, die Sie durchführen, werden keine Daten einwandfrei verarbeitet.Wenn Sie wirklich wissen müssen, ob Sie am Ende der Datei sind, müssen Sie zuerst einen Lesevorgang durchführen.

Andere Tipps

Dies mag eher eine Frage als eine Antwort sein, aber warum nicht verwenden datei_get_contents()?Wenn Sie eine Datei oder einen Stream lesen, erledigt diese Funktion meiner Erfahrung nach die Drecksarbeit für Sie (vorausgesetzt, Sie möchten die gesamte Ressource in eine Zeichenfolge einlesen oder wissen / können ein Limit und einen Offset berechnen).Die Schwesterfunktion file_put_contents () funktioniert umgekehrt gut.

Hier ist zum Beispiel ein Beispiel:

$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);
}

oder ein Strom:

$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);
}

Dann brauchen Sie sich keine Sorgen um EOF oder so zu machen, es erledigt das für Sie (FTP-Put wird etwas heikel, aber das ist in Ordnung).Natürlich wird das nicht in allen Situationen funktionieren...

Gibt es etwas, das mir in der ursprünglichen Frage fehlt, das diesen Ansatz undurchführbar macht?

Ihre Behauptung, nicht anzurufen feof vor einem fread ist nicht richtig - folglich ist die Frage nicht gültig.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top