2010-07-13 23 views
6

Vengo de un fondo de C y C++ pero también juego con algunas cosas de la web. Todos nosotros, la gente de C (con suerte) sabemos que llamar al feof en un FILE* antes de leer es un error. Esto es algo que pica a los novatos en C y C++ con mucha frecuencia. ¿Es este también el caso de la implementación de PHP?Comportamiento de feof de PHP contra C

Me imagino que tiene que ser porque el archivo podría ser un zócalo o cualquier otra cosa donde es imposible saber el tamaño antes de terminar de leer. Pero casi todos los ejemplos de PHP (incluso las que se encuentran en php.net que he visto se ve algo como esto (y las alarmas se apagan en mi cabeza):

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

Sé que es preferible escribir esto como esto y evitar esta tema:

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

pero eso es además el punto probé la prueba si las cosas fallarían si lo hacía "por el camino equivocado", pero no podía conseguirlo para causar un comportamiento incorrecto Esto no es exactamente científica,.. pero pensé que valía la pena intentarlo.

Entonces, ¿es incorrecto llamar al feof antes de un fread en PHP?

Hay dos maneras en que PHP podría haber hecho esto de manera diferente a la versión de C, pero creo que tienen inconvenientes.

  • podrían tenerlo por defecto! EOF. Esto no es óptimo porque puede ser incorrecto para algunos casos de esquina.

  • podían obtener el tamaño de archivo durante una llamada fopen, pero esto no podría funcionar en todos los tipos de recursos de archivos, produciendo un comportamiento incoherente y sería más lento.

Respuesta

3

PHP no sabe si está al final del archivo hasta que haya intentado leer de él. Pruebe este sencillo ejemplo:

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

Usted recibirá una línea de lectura read 0 bytes. feof() devolvió verdadero aunque estaba técnicamente al final del archivo. Por lo general, esto no causa ningún problema porque fread($fp, 1) no devuelve datos, y cualquier procesamiento que se realice no maneja datos correctamente. Si realmente necesita saber si se encuentra al final del archivo, primero debe leer.

-1

Su afirmación sobre no llamar al feof antes de un fread no es correcta, por lo que la pregunta no es válida.

+5

¿Creó su cuenta solo para brindarnos esta valiosa contribución? –

+0

en C, sin duda es un error lógico llamar a 'feof' antes de una operación que puede establecer el indicador EOF. 'fopen' no es una de esas operaciones. –

+0

Arrrggghhh! Ciertamente no es un error, lógico, sintáctico o de otro tipo. Es perfectamente válido Si comprende lo que hace, se comportará exactamente como se espera, como explicó MightyE arriba. La pregunta enmarcó la condición como un error; no lo es. – Anonymous

0

Esto puede ser más una pregunta que una respuesta, pero ¿por qué no utilizar file_get_contents()? En mi experiencia, si está leyendo un archivo o una secuencia, esta función hace el trabajo sucio para usted (suponiendo que desea leer el recurso completo en una cadena, o sabe/puede calcular un límite y una compensación). Su función hermana file_put_contents() funciona bien, en reversa.

Por ejemplo, he aquí un ejemplo:

$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 una corriente:

$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:[email protected]/file.txt", $real_content, 0, $stream); 
} 

entonces usted no tiene que preocuparse por EOF o algo, lo hace por usted (put ftp se pone un poco incierto, pero está bien). Por supuesto, esto no funcionará en todas las situaciones ...

¿Hay algo que me falta en la pregunta original que hace que este enfoque sea inviable?

+1

Su enfoque es bueno y completamente razonable, mi pregunta es más académica que práctica. Solo quería saber si 'foef' en PHP tiene el mismo comportamiento que en C. Gracias. –

+1

Ah, un académico, no vi tu chaqueta de cuero con los codos de tweed 8o) (Homer Simpson FTW, "CORRECCIÓN, ¡arruiné dos chaquetas!") – Tim