Christian Seiler: Neuer Artikel: Sperren von Dateien

Beitrag lesen

Hallo,

Anmerkung zum PHP-Teil:

if (!flock ($fp, LOCK_EX)) {
  die ('Sperren der Datei fehlgeschlagen!');

Bist Du sicher, dass das die überhaupt noch ausgeführt wird?
MMn wartet das flock() solange, bis es Erfolg hat, oder aber das PHP-Timeout zuschlägt.

Nein, das ist vollkommen falsch. flock() wartet grundsätzlich, bis es Erfolg hat. Das PHP-Timeout (Du meinst set_time_limit() bzw. die entsprechende ini-Einstellung, nehme ich an?) schlägt bei Systemaufrufen nämlich in KEINEM Fall zu! Die einzige Möglichkeit, flock() zu unterbrechen, ist ein nicht-ignoriertes Signal an den Prozess zu schicken. Aber solange man kein Deadlock produziert, ist es eigentlich nie ein Problem, auf eine Sperre zu warten, denn irgendwann wird die schon wieder frei werden.

Also: Es gibt 3 Möglichkeiten:

a) Der Aufruf kehrt zurück und die Sperre wurde etabliert
 b) Der Aufruf kehrt nicht zurück und der Prozess wartet ewig
    (falls eben ein Deadlock auftritt)
 c) Der Aufruf kehrt zurück und ein Fehler beim Sperren ist aufgetreten.
    Dies kann zum Beispiel passieren, wenn man fopen-Wrapper verwendet
    und versucht, eine Datei über FTP zu öffnen - da funktioniert das
    Sperren nämlich gar nicht (FTP kann so etwas nicht). Oder es kann
    passieren, wenn man's unter Windows 98 versucht.

Und genau den Fall (c) soll die die()-Abfrage abfangen. Nicht mehr, nicht weniger.

Und _wenn_ die() hier jemals ausgeführt würde, wäre es nicht unbedingt geschickt, ein größeres Skript derartig abzubrechen. Es sollte dann eine qualifizierte Fehlerbehandlung stattfinden, die den User nicht in den Wald stellt.

Natürlich sollte in größeren Scripten bessere Fehlerbehandlungsmöglichkeiten existieren, aber dies ist explizit ein einfaches Beispiel. Wer ein größeres Script schreibt und sich bereits Gedanken um Fehlerbehandlung gemacht hat, wird ja wohl selbst noch erkennen, dass die() in dem Kontext keine gute Wahl ist und das von selbst ersetzen.

Ich wollte das Beispiel möglichst einfach halten, so dass wirklich nur der eigentliche Sachverhalt dargestellt wird - und bei diesen einfachen Beispielen, die nichts anderes tun, funktioniert die Fehlerbehandlung über die() zufriedenstellend. Wenn ich dort jetzt noch eine ausgereifte Fehlerbehandlung einbauen würde, dann würde ich das Beispiel nur unnötig verkomplizieren. Zumal es bei ausgereifter Fehlerbehandlung wieder unterschiedliche Geschmäcker gibt: Exceptions, bestimmte Rückgabewerte, einen User-Error mit PHP werfen, usw. usf. Sorry, aber das ist schlichtweg nicht das Thema des Artikels.

Leider sind solche ja durchaus "funzenden" Beispiele geeignet, sich über den Weg des Copy & Paste beliebig oft zu vervielfältigen und sich dann als Standart (sic!) zu etablieren.

Ich habe kein Problem damit, wenn sich der aktuelle Code als Standard etablieren würde, denn ich kann Deine Kritik nicht nachvollziehen (s.o.).

Noch eine Frage zu touch(), und den anderen namensbasierten Dateifunktionen:

Hat schonmal jemand ausprobiert, was die machen, wenn es auf ein Advisory Lock laufen?

Sie funktionieren weiterhin. Das musst Du auch nicht ausprobieren, denn (und das steht übrigens auch in meinem Artikel drin) ein Advisory Lock ist eben "freiwillig", d.h. bei Advisory Locking kann ein Programm, das den Locking-Mechanismus nicht nutzt, beliebiges mit der Datei anstellen.

Und selbst bei Mandatory Locks unter Windows ist touch() kein Problem, da es ja explizit nichts in die Datei schreibt oder daraus liest - und das reine Öffnen (solange man die Datei nicht dabei zerstört) ist weiterhin problemlos erlaubt - auch bei Mandatory Locking. file_put_contents() oder ähnliches wird halt bei Mandatory Locking versagen.

Viele Grüße,
Christian