Domanda

Vengo da uno sfondo C e C ++ ma gioca anche con alcune cose web. Tutti gli Stati Uniti folks (si spera) sapere che chiamare feof su un FILE* prima di fare una lettura è un errore. Questo è qualcosa che punge spesso i neofiti a C e C ++ molto spesso. È anche questo il caso per l'implementazione di PHP?

Immagino che deve essere dovuto al fatto che il file potrebbe essere un socket o qualsiasi altra cosa in cui è impossibile conoscere le dimensioni prima di finire la lettura. Ma quasi ogni esempio di PHP (anche quelli trovati su php.net Ho visto sembra qualcosa di simile (e gli allarmi vanno in testa):

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

So che è preferibile scrivere questo simile ed evitare questo problema:

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

Ma questo è oltre al punto. Ho provato a testare se le cose avrebbero fallito se l'avessi fatto "il modo sbagliato", ma non potevo ottenerlo per causare un comportamento errato. Questo non è esattamente scientifico, ma ho pensato che valeva la pena provare.

Quindi, è errato chiamare feof prima di un fread in PHP?

Ci sono un paio di modi in cui PHP avrebbe potuto farlo in modo diverso dalla versione di C, ma sento che hanno il diasides.

    .
  • Potrebbero averlo predefinito! eof. Questo è sub-ottimale perché potrebbe non essere corretto per alcuni casi d'angolo.

  • Potrebbero ottenere le dimensioni del file durante una chiamata fopen, ma questo non è stato possibile lavorare su tutti i tipi di risorse dei file, producendo comportamenti incoerenti e sarebbe più lento.

È stato utile?

Soluzione

PHP non sa se è alla fine del file fino a quando non hai provato a leggere da esso.Prova questo semplice esempio:

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

Otterrai una linea leggendo read 0 bytes.Feof () è tornato vero anche se sei stato tecnicamente alla fine del file.Di solito questo non provoca un problema perché fread($fp, 1) non ritorna senza dati e qualsiasi elaborazione che stai facendo su quella maniglia nessun dato va bene.Se hai davvero bisogno di sapere se sei alla fine del file, devi prima fare una lettura.

Altri suggerimenti

Questa potrebbe essere più una domanda che una risposta, ma perché non usare file_get_contents () ?Nella mia esperienza, se stai leggendo un file o un flusso, questa funzione è il lavoro sporco per te (supponendo che tu voglia leggere l'intera risorsa a una stringa o conosci / può calcolare un limite e un offset).La sua funzione sorella File_put_Contents () funziona bene, al contrario.

Ad esempio, ecco un esempio:

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

o un flusso:

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

Allora non devi preoccuparti di EOF o di qualsiasi cosa, lo fa per te (FTP PUT diventa un po 'DACEY, ma va bene).Certo, questo non funzionerà in tutte le situazioni ...

C'è qualcosa che mi manca dalla domanda originale che rende questo approccio irrealizzabile?

La tua affermazione di non chiamare feof prima che un fread non sia corretto, di conseguenza la domanda non è valida.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top