Pregunta

Yo vengo de una C y C++ fondo, pero también jugar con algunas cosas web.Todos nos C de la gente (esperemos que) saben que llamar feof en un FILE* antes de hacer una lectura es un error.Esto es algo que las picaduras de los novatos en C y C++, muy a menudo.Es este también el caso de la implementación de PHP?

Me imagino que tiene que ser porque el archivo podría ser un socket o cualquier otra cosa donde es imposible saber el tamaño antes de terminar la lectura.Pero casi todos los PHP de ejemplo (incluso los que se encuentran en php.net He visto se ve algo como esto (y se activan las alarmas en mi cabeza):

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

Sé que es preferible escribir esta como esta y evitar este problema:

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

pero es que además el punto.He intentado probar si las cosas iban a fallar si yo lo hice "el camino equivocado", pero yo no podía llegar a causar un comportamiento incorrecto.Esto no es muy científico, pero pensé que valía la pena intentarlo.

Por lo tanto, es incorrecta la llamada feof antes de que un fread en PHP?

Hay un par de maneras en que PHP se podría haber hecho de una manera que C versión, pero yo creo que ellos tienen sus desventajas.

  • se podría tener por defecto !EF.Este es sub-óptima debido a que puede ser incorrecto para algunos casos de esquina.

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

¿Fue útil?

Solución

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

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

Obtendrá una línea de lectura read 0 bytes.feof() devuelve true aunque técnicamente al final del archivo.Por lo general no causa un problema porque fread($fp, 1) no devuelve datos, y lo que sea que el procesamiento se está realizando en que maneja los datos no sólo de multa.Si usted realmente necesita saber si usted está en el final del archivo, usted tiene que hacer una lectura de primera.

Otros consejos

Esto puede ser más una pregunta que una respuesta, pero ¿por qué no usar file_get_contents()?En mi experiencia, si usted está leyendo un archivo o de un arroyo, esta función hace el trabajo sucio por usted (suponiendo que se desea leer todo el recurso a una cadena, o sabe/puede calcular un límite y offset).Su hermana función file_put_contents() funciona bien, a la inversa.

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 de un arroyo:

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

Entonces usted no necesita preocuparse acerca de EF ni nada, se lo hace por usted (ftp poner un poco arriesgado, pero eso está bien).Por supuesto, esto no funciona en todas las situaciones...

Hay algo que me estoy perdiendo de la pregunta original que hace que este enfoque inviable?

Su afirmación acerca de no llamar feof antes de que un fread no es correcto - en consecuencia, la cuestión no es válido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top