Christian Seiler: fgets Problem wenn Datei 0 enthält

Beitrag lesen

Hallo Tom,

Wenn man aus einer Datei "nichts" lesen will, dann ist das ein deutliches Zeichen für fortgeschrittenen Unsinn. Die Warnung auszuspucken ist aus meiner Sicht korrekt. Diesen Fall abzufangen also erforderlich. Vernünftige Algorithmen haben das Problem nicht.

Wieso?
Unsinn ist es, einen Befehl, der ordnungsgemäß ausgeführt wird, mit einer Fehlermeldung (Warnung) zu belegen.

Wenn man 0 Bytes lesen will, dann stimmt wirklich etwas mit dem eigenen Algorithmus nicht. Die PHP-Leute warnen davor, damit man nicht in irgend eine Falle tappt. Ich halte das für absolut unproblematisch - im Gegenteil, ich halte das für sehr programmiererfreundlich, dass so offensichtliche Fehler.

Nicht alles, was auf den ersten Blick nicht sinnvoll erscheint, ist deshalb gleich unsinnig!
In netzwerkfähigen Programmen wird ein "read 0 bytes" z.B. gerne benutzt, um festzustellen, ob der Kanal noch zur Verfügung steht.

Nein, jetzt mal aus Betriebssystemsicht: recv mit der Länge 0 ist GÄNZLICH UNGEEIGNET, um festzustellen, ob eine Socketverbindung noch offen ist. Zumindest unter UNIX (unter Windows dürfte es ähnlich sein, die haben die Sockets auch nur von BSD kopiert) ist es so, dass eine Socketverbindung von der Gegenstelle geschlossen wurde, wenn:

a) select() oder poll() angeben, dass es zu lesende Daten auf dem Socket
    gibt

und

b) recv() den Wert 0 _zurückgibt_.

Das Problem mit b) ist (ich hab's selbst nochmal getestet), dass recv() im Falle von "ich will 0 Bytes lesen" *immer* 0 zurückgibt, d.h. man hier keine Fallunterscheidung machen kann! Also ist recv() mit Länge 0 als Parameter _absolut nutzlos_. Mir fällt absolut kein sinnvolles Anwendungsbeispiel ein, wo man Länge 0 lesen wollte. Wenn man das tut, ist der eigene Algorithmus vollkommen kaputt.

Und in PHP ist das Abfangen von "Socket wurde geschlossen" *VIEL* einfacher: feof() wrappt in PHP genau die nötige Funktionalität und nimmt einem Programmierer genau die Probleme ab, die man sonst damit hat (dass man selbst einen Puffer braucht, um eventuell doch vorhandene Rückgabedaten doch zwischenzuspeichern etc.).

Mir dünkt, dass PHP hier irgendwo ein eigenes kleines Problem haben könnte, was auf diese Weise kaschiert werden soll.

Nein, PHP hat hier absolut kein Problem.

Aber deshalb darf ich es ja doch erwähnen, dass man hier gegenüber älteren Versionen plötzlich etwas zusätzlich beachten muss bei der Benutzung der Funktion.

Bug #26752. PHP hat bei Socketverbindungen vorher Mist gebaut mit 0 als Längenparameter (Endlosschleife), jetzt wird das abgefangen. Ist aber auch schon 4 Jahre her, dass das gefixed wurde.

Viele Grüße,
Christian