Question

Je viens d'une formation C et C++ mais je joue également avec des éléments Web.Nous tous, les gens de C (espérons-le), savons que l'appel feof sur un FILE* avant de faire une lecture, c'est une erreur.C’est quelque chose qui pique très souvent les débutants en C et C++.Est-ce également le cas pour l’implémentation de PHP ?

Je pense que cela doit être dû au fait que le fichier pourrait être un socket ou autre chose dont il est impossible de connaître la taille avant de terminer la lecture.Mais presque tous les exemples PHP (même ceux trouvés sur php.net J'ai vu quelque chose comme ceci (et des alarmes se déclenchent dans ma tête) :

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

Je sais qu'il est préférable d'écrire ceci comme ceci et d'éviter ce problème :

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

mais ce n'est pas le sujet.J'ai essayé de tester si les choses échoueraient si je le faisais "dans le mauvais sens", mais je n'ai pas réussi à provoquer un comportement incorrect.Ce n’est pas vraiment scientifique, mais j’ai pensé que ça valait la peine d’essayer.

Alors, est-il incorrect d'appeler feof avant un fread en PHP ?

PHP aurait pu procéder de plusieurs manières différemment de la version C, mais je pense qu'elles présentent des inconvénients.

  • ils pourraient l'avoir par défaut sur !EOF.Ceci n’est pas optimal car il peut être incorrect dans certains cas particuliers.

  • ils pourraient obtenir la taille du fichier lors d'un fopen appel, mais cela ne pourrait pas fonctionner sur tous les types de ressources de fichiers, ce qui entraînerait un comportement incohérent et serait plus lent.

Était-ce utile?

La solution

PHP ne sait pas s'il se trouve à la fin du fichier tant que vous n'avez pas essayé de le lire.Essayez cet exemple simple :

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

Vous obtiendrez une lecture d'une ligne read 0 bytes.feof() a renvoyé true même si vous étiez techniquement à la fin du fichier.Habituellement, cela ne pose pas de problème car fread($fp, 1) ne renvoie aucune donnée, et quel que soit le traitement que vous effectuez, il ne gère très bien aucune donnée.Si vous avez vraiment besoin de savoir si vous êtes à la fin du fichier, vous devez d'abord effectuer une lecture.

Autres conseils

C'est peut-être plus une question qu'une réponse, mais pourquoi ne pas utiliser fichier_get_contents()?D'après mon expérience, si vous lisez un fichier ou un flux, cette fonction fait le sale boulot à votre place (en supposant que vous souhaitiez lire la ressource entière dans une chaîne, ou que vous sachiez/pouviez calculer une limite et un décalage).Sa fonction sœur file_put_contents() fonctionne bien, à l'envers.

Par exemple, voici un exemple :

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

ou un flux :

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

Ensuite, vous n'avez pas à vous soucier d'EOF ou quoi que ce soit, il le fait pour vous (le FTP Put devient un peu risqué, mais ce n'est pas grave).Bien sûr, cela ne fonctionnera pas dans toutes les situations…

Y a-t-il quelque chose qui me manque dans la question initiale et qui rend cette approche irréalisable ?

Votre affirmation sur le fait de ne pas appeler feof avant un fread n'est pas correct - par conséquent la question n'est pas valable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top