Wie die parallele Ausführung von PHP-Dateien verhindern?

  • Gibt es eine Möglichkeit zu verhindern, dass eine PHP-Datei mehrfach gleichzeitig ausgeführt wird? Das kann dann zum Problem werden, wenn die PHP-Datei eine Datendatei laden, Daten verändern und dann den geänderten Stand der Daten unter dem gleichen Dateinamen speichern soll. Bei Tests habe ich mit Hilfe der Anweisung "sleep" nachweisen können, dass dabei alle Daten verlorengehen können. ;( Das passiert dann, wenn der zweite Aufruf genau in dem Augenblick starten sollte, wenn der erste Aufruf gerade mit dem speichern begonnen hat und die Datei noch leer ist. PHP's können Dateien nämlich bereits beim speichern auslesen!!!! Das gleiche gilt für den FTP-Upload von Dateien. Durch dieses Problem können zum Beispiel auch Besucherzähler auf den Wert "1" zurückspringen und keiner weis dann wie das passieren konnte. ?(
    Diese Situation erscheint zwar sehr unwahrscheinlich, weil dieser exakte Zeitpunkt ein sehr großer Zufall wäre, aber mit einer steigenden Anzahl der Besucher, erhöht sich die natürlich diese Möglichkeit.
    Eine Lösung die ich bereits gefunden habe besteht darin, dass für jeden Aufruf eine TXT-Datei mit der IP-Nummer des Besuchers als Name erzeugt wird. (123.48.23.57.txt) Darin steht dann der exakte Zeitpunkt des Erzeugens dieser Datei als Code. (Datum und Zeit: 20140321140613) Nach dem erzeugen dieser TXT-Datei, muss die PHP-Datei bis zur nächsten Sekunde warten, also bis sich der Code geändert hat. Dann wird eine Liste aller TXT-Dateien im betreffenden Pfad erstellt. Wenn die TXT-Datei, die den kleinsten Code enthält, auch den Namen der IP hat, über die die PHP-Datei aufgerufen wurde, dann darf diese IP-Nummer die Datendatei zuerst verändern. Anschließend muss die IP-TXT-Datei natürlich wieder gelöscht werden. Hat die aktuelle IP einen höheren Code, dann springt sie wieder zurück zum Auslesen der Dateiliste. Sind zwei oder mehrere Codes identisch, dann darf die IP-Nummer zuerst arbeiten, dessen IP-Code kleiner ist. (IP 123.48.23.57 = IP-Code 123048023057) So ziehen alle gleichzeitigen Besucher quasi eine Wartenummer und müssen warten, bis sie an der Reihe sind. Diese Lösung erfordert leider sehr viel Programmcode und ist extrem umständlich! :wacko: Dafür verhindert sie aber wirkungsvoll den parallelen Ablauf der gleichen PHP-Datei. Eine Anweisung wie zum Beispiel "OnlySingleRun" wäre da natürlich besser, aber die gibt es ja leider nicht, oder doch? ?(

  • flock() sollte sein was du suchst.


    Hier ein interessanter Beitrag auf SelfHTML bezüglich File Locking bei Besucherzählern, ich vermute aufgrund eines anderen Beitrages das es sich bei dir auch um einen solchen handeln wird, wenn nicht: Das Prinzip ist immer das Gleiche :love:

  • Super!!!! :D
    Damit müsste es funktionieren... Dann kann ich mir diesen umständlichen Mist mit den IP-Dateien und der Zeitauswertung zum Glück sparen! Vielen Dank!!!! :thumbup:


    Ja, ich hatte zuerst an meinen neuen Besucherzähler gedacht. Es gibt da aber aktuell noch andere Projekte in meiner Planung, für die ich das brauche. Änderungen von Datenbanken, die teils mehrere Megabyte groß werden können, zum Beispiel. Wenn da mehrere Male die gleiche PHP-Datei starten sollte, weil gerade viele Besucher da sind, dann wäre das sehr fatal! Ich arbeite aktuell an einer Datenbank über Achterbahnen, die bereits jetzt mehr als 6000 Achterbahnen umfasst. Jede Bahn und jeder Freizeitpark, ist dann ein eigenständiger Eintrag in der Datenbank. Würde ich mir mit "Visual Basic" ein Makro schreiben, das alle Einträge meiner Excel-Tabelle in eine eigenständige HTML-Datei umwandelt, dann würde ich tausende HTML-Dateien hochladen müssen, die zusammen um die 100 Megabyte groß wären. Mit der Datenbank habe ich dann nur das PHP-Anzeigemodul und die etwa 5 Megabyte große Datenbank als TXT-Datei. Während ich den aktuellen Stand mit meinem FTP-Programm hochlade, würde es dann natürlich im Anzeigemodul Fehler geben, weil die Datei noch nicht vollständig ist und sich die Ziele der meisten FileSeek-Sprungmarken noch nicht auf dem Server befinden. Mit der Flock-Sperre mache ich das dann halt so, dass ich meine Datenbank unter einem anderen Namen hochlade und dann anschließend ein anderes PHP starte, das die Datenbank zum lesen sperrt und sie dann mit der aktuellen Version überschreibt (Dateikopie). Das sollte dann nur einen Sekundenbruchteil dauern. Andernfalls hätte ich während des Uploads der etwa 5 Megabyte für etwa 2 Minuten das Risiko, dass Besucher auf meiner Internetseite einen Datenfehler erleben.


    Eine PHP-Anwendung die anzeigen kann, wie viele Besucher gerade da sind, möchte ich auch mal programmieren. Da wird dann eine Datendatei angelegt, in der alle IP-Adressen der Besucher mit Datum und Uhrzeit gespeichert werden. Bei einem neuen Aufruf der gleichen IP, wird dann nur ihr Zeitpunkt aktualisiert. IP's die länger als 10 Minuten keine Dateien mehr aufgerufen haben, fliegen dann automatisch aus der Liste. Die Anzahl der IP-Einträge ist dann die Anzahl der aktuell aktiven Besucher. Dieses PHP muss dann natürlich in jede andere PHP-Datei eingebunden werden, damit die Anzeige funktioniert. Dass jeder aufgerufene Link ein laden und aktualisieren der IP-Liste erfordert, sollte auch klar sein. Daher muss diese Datei natürlich auch gesperrt werden.

  • @ Basiii
    Sorry, null Ahnung von "MySQL". 8| Meine Lösung funktioniert aber auch. Nur die Erzeugung der FileSeek-Sprungmarken ist eine echte Sisyphos-Arbeit. Weil das vollautomatisch von meinem Makro gemacht wird, stört mich das aber nicht weiter. :)

  • Jetzt hab ich mir Deinen Text doch mal durchgelesen - aber mach mal ab un zu paar Absätze :D
    (ich werd aber auch alt glaub ich =)


    Zum Thema:
    genau so hab ich auch angefangen: alles in txt speichern.
    Das Problem, das Du dann irgentwann haben wirst : es bremst Dich voll aus.


    Die Daten die du beschreibst, sind von der Zeilenmenge her in etwa das, was ich hatte. Und ich kann Dir sagen - bei rund 50000 Datensätzen ist Schluss.
    Dann wartest Du bis zu 2-3 sec auf einen Datensatz.
    Man kann zwar immer wieder was optimieren. Aber die Zeit lohnt es sich eher in alternative Systeme rein zu sehen.
    (aber es ist auf jeden Fall gut, wenn man sowas mal mit txt Dateien gemacht hat! =)


    Sql: "2 Wochen, dann haste das drin" - hat mir damals jemand gesagt.
    Und so war es auch. Klar - nur die Basics. Sql lernt man nie aus. Aber alleine der Geschwindigkeitsvorteil ist es wert.


    Hier hate ich zB mit Sql angefangen: http://www.php-kurs.com/mysql---datenbank-unter-php.htm

  • Jap, kann mich Basi nur anschließen, für so eine Datenspeicherung ist SQL einfach erfunden worden und damit ideal.
    Und MySQL ist für den Einstieg am Besten, da am weitesten verbreitet, dicht gefolgt von SQLite (da FlatFile und wenig Aufwand)


    Also, erstmal via Basiiis Link einlesen, rumprobieren und dann wieder hier mit Fragen um dich werfen :D Dafür ist das Forum ja da.

  • @ cottton
    @ The Scout
    Danke für Eure Hinweise! :thumbup:


    Ja, ich denke irgendwann - wenn ich mehr Ahnung habe 8| - werde ich mich mal mit "SQL" beschäftigen...


    Aktuell besteht für meine in der Planung befindliche Internetseite aber kein Handlungsbedarf. Seit Anfang der 90er-Jahre habe ich etwas mehr als 6000 Datensätze zusammengetragen, die ich nun demnächst online stellen werde. Inklusive Such-Masken, denn man will ja auch finden was man sucht. Ich kann mir dann ja später mal Gedanken darüber machen, alles auf "SQL" umzustellen.


    Euren Einwand mit der Geschwindigkeit kann ich übrigens nicht nachvollziehen... Ich habe mit einem Makro eine Test-Datenbank als TXT-Datei erstellt, die sogar 0,2 Millionen Datensätze / Einträge hat und 96 Megabyte groß ist. Es hat nur 0 Sekunden gedauert, bis der gesuchte Datensatz (der letzte) da und angezeigt war. Vermutlich hat die Suche nur wenige Millisekunden gedauert. Alles eine Frage der Programmierung und der Geschwindigkeit des Servers. :D

  • Das du den Einwand mit der Geschwindigkeit nicht nachvollziehen kannst kann ich wiederum nicht nachvollziehen.


    Ich simuliere eine Datensammlung aus je 2 wichtigen Werten: Die ID und den Code, bei der ID handelt es sich um eine simple Nummerierung der Einträge, der Code ist ein je 32 Zeichen langer, alphanumerischer Buchstabensalat.
    Nun habe ich eine Datenbank mit 3.000.000 Einträgen (jeweils ID + CODE) und eine Textdatei angelegt, diese enthält auch 3.000.000 Einträge:

    Code
    ID|CODE
    ID|CODE
    ...


    Hier 4 Suchen unter Beobachtung:




    *Das Suchen nach längeren Strings in sehr großen Dateien ist nur sehr schwer zu realisieren, es ist möglich, jedoch eher umfangreich und trickreich, die Datenbank begnügt sich mit (großzügig gesehen) 3-4 Zeilen.


    Die Größe der Textdatei war übrigens 115MB, die der Datenbank 171MB, über die Geschwindigkeit lässt sich bei umfangreicheren Datensammlungen allerdings absolut nicht streiten, außerdem fällt die Verwaltung von Datenbanken doch deutlich leichter aus und sie lassen sich ohne ein Programm zu schreiben mühelos ändern, eine 115MB Textdatei öffnen, ändern und speichern dauert lange und ist auf Computern mit schwächerer Leistung absolut unmöglich.

  • Naja, noch zu dem Vergleich db (SQL) und txt:


    (ich gehe hier mal von normalo SQL db aus und einer Suchanfrage bei beiden Varianten)
    Es ist ja so, dass die SQL db (also der SQL Server) die Daten auch in Files lagert. Irgendwo muss das Zeug ja hin.
    Der offensichtliche Unterschied:


    SQL:
    SQL Server startet (für sich) und lädt die Daten. Die Files werden also nicht immer wieder neu geöffnet und Zeile für Zeile durchsucht.
    Ein laufendes Programm lädt also nicht selbst die Daten, sondern holt sie sich von dem ständig in Bereitschaft stehenden SQL Server.


    txt:
    Programm lädt sich selbst die Daten und bei Ende des Programms sind die Daten wieder weg.
    Beim nächsten Durchlauf muss also wieder alles geladen werden.


    Wenn man das also nachbilden/annähern möchte, dann müsste man zB ein Programm in der console laufen lassen.
    Das Programm würde zB beim Start die Daten aus der txt in ein Array laden und bei Bedarf/Anfrage relativ schnell zur Hand haben.
    Update ect ist dann schon schwieriger (Doppelzugriff ect).


    Also wenn es um viele Daten geht, und mMn auch um wichtige Daten, dann ist SQL the way to go.
    Selbst bei einem Stromausfall (echt mies!) hat man noch gute Chancen die Daten zu retten.
    (bei innodb (aktuelle mysql vers.) überigens sehr easy - letztens erst passiert :D)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!