PHP, blödes...
Christoph
- menschelei
Moin.
Ich war gerade dabei, euch bei folgendem Problem um Hilfe zu bitten:
-------8<------------------------------
Ich habe da ein kleines Problem mit einem PHP-Skript, und ich weiß nicht genau, ob der Fehler bei mir, bei PHP oder bei Windows (Testumgebung: WinXP, XAMPP lite mit PHP 5.2.4) liegt...
Das Szenario: Zwei PHP Dateien, eine davon läuft per
set_time_limit(0);
ignore_user_abort(true);
im Hintergund in einer Endlosschleife mit Datei-locking folgender Art:
while(is_file($lock_file))
{
$lock = fopen($lock_file, 'r');
flock($lock, LOCK_EX);
// mache exklusives Zeug...
flock($lock, LOCK_UN);
fclose($locK);
sleep($timeout);
clearstatcache();
}
Nun möchte ich die Ausführung dieses Skripts aus einem zweiten Skript heraus unterbrechen. Mein Ansatz:
$lock = fopen($lock_file,'r');
flock($lock, LOCK_EX);
fclose($lock);
unlink($lock_file);
Ergebnis: Warning: unlink(lock.txt) [function.unlink]: Permission denied in [...]
Kann mir jemand erklären, woran das liegt?
-------8<------------------------------
Als ich die Nachricht in der Vorschau auf Fehler überprüft habe, viel mir auf, dass an entscheidender Stelle ein 'k' zu einem 'K' geworden ist...
Besten Dank also für die Lösung meines Problems ;)
Christoph
Hallo Christoph,
Als ich die Nachricht in der Vorschau auf Fehler überprüft habe, viel mir auf, dass an entscheidender Stelle ein 'k' zu einem 'K' geworden ist...
Hättest du error_reporting auf E_ALL gesetzt und display_errors eingeschaltet gehabt, hättest du nicht einmal die Vorschau gebraucht ;-)
Schöne Grüße,
Johannes
Hallo.
Hättest du error_reporting auf E_ALL gesetzt und display_errors eingeschaltet gehabt, hättest du nicht einmal die Vorschau gebraucht ;-)
Das halte ich für ein Gerücht ;)
Das Skript sollte im Hintergrund laufen und keine Ausgabe erzeugen, da man direkt per Header 303 auf eine andere Seite weitergeleitet wird.
Fürs Debugging hatte ich die Weiterleitung natürlich deaktiviert, die Fehlermeldungen sind aber in irgendeinem Buffer hängengeblieben und nie beim Browser angekommen - nach einem zusätzlichen flush() konnte ich sie dann auch bewundern...
Christoph
Hallo,
Das Szenario: Zwei PHP Dateien, eine davon läuft per
set_time_limit(0);
ignore_user_abort(true);
> im Hintergund
Wie hast Du denn den Prozess in den Hintergrund gestellt?
Ich kann da kein Abtrennen feststellen.
Was soll das stöndige öffnen und Schließen der Datei bewirken?
Wie meinst Du, mit einem einzigen unlink() im zweiten Script genau eine Lücke treffen zu können, in der das File nicht exclusiv gesperrt, bzw. geöffnet ist?
LG
Chris
Moin.
Wie hast Du denn den Prozess in den Hintergrund gestellt?
Ich kann da kein Abtrennen feststellen.
'Im Hintergrund laufen' sollte hier einfach bedeuten, dass das Skript (exakt) einmal gestartet wird und dann ohne Interaktion mit irgendeinem Client unbegrenzt weiterläuft (solange die in $lock_file angegebene Datei existiert).
Was soll das stöndige öffnen und Schließen der Datei bewirken?
Äh - einen Locking-Mechanismus? Der Name sollte das doch irgendwie deutlich gemacht haben...
Da wo der Kommentar steht, steht natürlich eigentlich was anderes...
Wie meinst Du, mit einem einzigen unlink() im zweiten Script genau eine Lücke treffen zu können, in der das File nicht exclusiv gesperrt, bzw. geöffnet ist?
Daher das flock zwei Zeilen darüber (LOCK_EX blockiert bis zum Erhalt der Sperre - natürlich wäre es geschickt, den Rückgabewert zu prüfen und es im Zweifelsfall nochmal zu versuchen).
Das fclose in der nächsten Zeile hebt die Sperre natürlich vorzeitig auf; ich brauche es aber auch nur, um die Datei auf meiner Windows-Testumgebung löschen zu können - im Produktiveinsatz auf *nix-Systemen fliegt die Zeile einfach raus...
Christoph
Hi!
Nun möchte ich die Ausführung dieses Skripts aus einem zweiten Skript heraus unterbrechen. Mein Ansatz:
$lock = fopen($lock_file,'r');
flock($lock, LOCK_EX);
fclose($lock);
unlink($lock_file);
Wieso nimmst Du dieselbe Datei die Du mit exklusivem Lock bearbeitest und aus einem anderen Skript löschen willst, um eine Information zu übermitteln?
Ich würde eine 2. Datei nehmen, bei der das 1. Skript in jedem Schleifendurchlauf prüft, ob diese Datei vorhanden ist oder einen bestimmten Inhalt hat - ohne Lock. Dann kannst Du die Datei jederzeit löschen bzw. entsprechende Befehle reinschreiben.
> Ergebnis: Warning: unlink(lock.txt) [function.unlink]: Permission denied in [...]
Wenn Du den Hintergrundprozess beendest, funktioniert das Löschen dann per Skript?
Grüße
Andreas
Moin.
Ich würde eine 2. Datei nehmen, bei der das 1. Skript in jedem Schleifendurchlauf prüft, ob diese Datei vorhanden ist oder einen bestimmten Inhalt hat - ohne Lock.
Das ist tatsächlich die robustere Lösung - ich wollte ursprünglich die Erstellung einer weiteren Datei vermeiden, ist aber vermutlich sinnvoller, die Funktionalität zu entkoppeln.
Wenn Du den Hintergrundprozess beendest, funktioniert das Löschen dann per Skript?
Das lag daran, dass im Hintergrundprozess noch ein Dateizeiger $lock existierte, da ich ja geschickterweise $locK geschlossen hatte...
Christoph
Hallo,
Ich würde eine 2. Datei nehmen, bei der das 1. Skript in jedem Schleifendurchlauf prüft, ob diese Datei vorhanden ist oder einen bestimmten Inhalt hat - ohne Lock. Dann kannst Du die Datei jederzeit löschen bzw. entsprechende Befehle reinschreiben.
Das würde das Problem nur verlagern, aber trotzdem keinen ausreichenden Schutz gewähren.
Locking-Mechanismen sind nicht deshalb eingeführt worden, weil jemand Langeweile hatte, sondern weil es nicht ohne geht, in einem shared filesystem fehlerfrei zu arbeiten.
LG
Der Chris