anstatt löschen wird datei immer größer

Fragen zu allen Themen rund ums Programmieren außerhalb von phpBB können hier gestellt werden - auch zu anderen Programmiersprachen oder Software wie Webservern und Editoren.
Benutzeravatar
Ambience
Mitglied
Beiträge: 628
Registriert: 02.09.2006 11:28
Wohnort: daheim
Kontaktdaten:

anstatt löschen wird datei immer größer

Beitrag von Ambience »

Hallo, ich bin gerade dabei einen chat zu basteln.. funzt auch alles wunderbar... nur diese funktion hier will nicht...

anstatt zu löschen, wird die datei größer und größer, ohne das ich seite reloaded vergrößert die sich.. wenn ich nicht den browser beende liege ich schnell bei 25MB in ungefähr 6 sec.. das liegt denke ich an dem ajax script weil ich gleichzeitig beim hohlen auch löschen lasse... nur irgendwas muss an der funktion falsch sein dass die mir immer anstatt löscht lauter

kästchen einträgt, also "\n" nur umgewandelt...

hier mal die funktion.. wobei ich das so haben will, das es immer nur 22 chat nachrichten in der txt datei gibt...

Code: Alles auswählen

function delete_chat_message($room_id)
  {
    $this->room_id = $room_id;
    $this->fopen_file = file('rooms/' . $this->room_id . '.txt');
    $this->count = count($this->fopen_file);
    $this->fopen = fopen('rooms/' . $this->room_id . '.txt', 'w+');
    
    if ($this->count > 23)
    {    
      unset($this->fopen_file[0]);
    }    
    
    foreach ($this->fopen_file as $this->line)
    {
      fputs($this->fopen, $this->line . "\n");
    }
    fclose($this->fopen);
    
    return true;
  }
Benutzeravatar
Banger
Ehemaliges Teammitglied
Beiträge: 375
Registriert: 03.05.2005 21:53
Wohnort: Düsseldorf
Kontaktdaten:

Re: anstatt löschen wird datei immer größer

Beitrag von Banger »

Servus,

da sind ein paar Denkfehler drin.

1. hinzugefügter Zeilenumbruch:
Lies mal die Doku zu file();
Der Zeilenumbruch bleibt erhalten.
- Du brauchst also keinen weiteren Zeilenumbruch hinzuzufügen, ansonsten hast Du immer mehr Leerzeilen drin.

2. Abfrage der Zeilenanzahl bzw. Reaktion:
Du löschst jeweils nur eine Zeile, falls die Anzahl > 23 ist; richtig wäre aber, so lange die Zeilen zu löschen, bis nur noch 23 übrig sind.

3. Klassenvariablen
Warum verwendest Du Klassenvariablen, auf die anscheinend nur innerhalb dieser Methode zugegriffen wird? Naja - whatever.

So stelle ich mir eine Lösung vor; die maximale Anzahl der Zeilen habe ich mal zwecks zentraler Definition in eine Konstante gepackt, zudem spart man sich einen Haufen Dateioperationen, wenn man erst überprüft, ob eine Aktion überhautp notwendig ist, bevor man das File zum erneuten Schreiben öffnet...

Code: Alles auswählen

function delete_chat_message($room_id)
  {
    $this->room_id = $room_id;
    $this->fopen_file = file('rooms/' . $this->room_id . '.txt');
   
    if(MAX_ROWS <= count($this->fopen_file)) return TRUE;
   
    while(MAX_ROWS > count($this->fopen_file))
        array_shift($this->fopen_file);
    
    $this->fopen = fopen('rooms/' . $this->room_id . '.txt', 'w+');

    $buf = implode('', $this->fopen_file);       
    fputs($this->fopen, $buf, strlen($buf));
    
    fclose($this->fopen);
   
    return TRUE;
  }
Benutzeravatar
Ambience
Mitglied
Beiträge: 628
Registriert: 02.09.2006 11:28
Wohnort: daheim
Kontaktdaten:

Beitrag von Ambience »

hallo, deine funktion scheint auch nicht zu laufen.. es sind jetzt bereits 30 nachrichten eingegeben, aber er löscht die ersten 8 dann nicht...

function sieht eingebaut so aus:

Code: Alles auswählen

 function delete_chat_message($room_id) 
  { 
    $this->room_id = $room_id; 
    $this->fopen_file = file('rooms/' . $this->room_id . '.txt'); 
    $this->count = count($this->fopen_file);
    define('MAX_ROWS', $this->count);
    
    if(MAX_ROWS <= count($this->fopen_file)) return TRUE; 
    
    while(MAX_ROWS > count($this->fopen_file)) 
        array_shift($this->fopen_file); 
    
    $this->fopen = fopen('rooms/' . $this->room_id . '.txt', 'w+'); 

    $buf = implode('', $this->fopen_file);        
    fputs($this->fopen, $buf, strlen($buf)); 
    
    fclose($this->fopen); 
    
    return TRUE; 
  }

hba mich selber nochmal drangesetzt und lösche nun einfach

gesammmteinträge - 22

lösche von 0 - ergebnis


aber trotzdem danke
Benutzeravatar
Banger
Ehemaliges Teammitglied
Beiträge: 375
Registriert: 03.05.2005 21:53
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von Banger »

Hi Ambience,
ich habe den Schnipsel vorhin im Büro nebenher zusammengeschrieben, ohne ihn zu testen...

Allerdings ist die Vorgehensweise an sich nicht sonderlich günstig; sie lädt nahezu zu Race-Conditions ein - soll heißen: wenn User A einen Beitrag absendet, während das Script (durch User B angestoßen) gerade die Zeilenanzahl prüft und dann ggf. das File neu speichert, geht der Beitrag von User A flöten...
Benutzeravatar
Ambience
Mitglied
Beiträge: 628
Registriert: 02.09.2006 11:28
Wohnort: daheim
Kontaktdaten:

Beitrag von Ambience »

sry das ich nicht so schnell geantwortet habe... ja dieses problem habe ich gerade... alle paar mal geht ein beitrag von mir flöten.. wie kann man das ändern=
Benutzeravatar
Ambience
Mitglied
Beiträge: 628
Registriert: 02.09.2006 11:28
Wohnort: daheim
Kontaktdaten:

Beitrag von Ambience »

nach 3.wochen und plötzlicher einfall, will ich diesen Thread mal wieder zum leben erwecken.

Wie kann man dieses Problem umgehen?

meine vorstellung wäre, gleichzeitig mit einem eintrag, auch eine prüfvariable in die datenbank zu schreiben. wenn der eintrag erfolgreich war, wird diese wieder gelöscht und der nächste kann eintragen... dann müsste man allerdings die einträge eines users cachen, sodass diese nacheinander abgearbeitet werden...

Oder gibt es andere möglichkeiten? ich meine, die anderen chatportale: antenne-bayern.de spinchat.de etc. die mussten sich ja auch mit dieser thematik befassen, aber leider bekommt man ja keinen einblick auf der ihren quellcode.

Danke
Benutzeravatar
Ambience
Mitglied
Beiträge: 628
Registriert: 02.09.2006 11:28
Wohnort: daheim
Kontaktdaten:

Beitrag von Ambience »

keiner eine antwort? :-(
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Beitrag von gn#36 »

Leider kenne ich mich mit den Dateifunktionen von PHP nicht so aus, allerdings mit denen von anderen Programmiersprachen und da gibt es die Möglichkeit zum exklusiven Öffnen einer Datei, d.h. niemand anderes kann zugreifen, gibt es diese Möglichkeit evtl. hier auch? Dann müsste man das Skript nur noch in eine Warteschleife versetzen wenn noch kein Zugriff möglich ist.
Vielleicht wäre es auch sinnvoll das System auf mehrere Dateien auszuweiten wobei dann die neuen Einträge in eine Datei (vielleicht sogar jeder User eine andere) kommen und dann von einem anderen Skript in eine andere Datei verschoben werden welches als einziges auf die andere Datei zugreift. Dieses kann dann bei zu vielen Einträgen in der anderen Datei diese entgültig entfernen, angezeigt werden immer nur die Einträge in der anderen Datei, es muss natürlich gewährleistet sein, dass das Verschiebungsskript auch häufig genug aufgerufen wird. Außerdem sind natürlich bei vielen Usern auch viele Dateien nötig, die Zugriffe machen das System vermutlich langsam.
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Jensemann
Ehemaliges Teammitglied
Beiträge: 2549
Registriert: 25.02.2002 01:00

Beitrag von Jensemann »

Dateien zu locken (exklusives öffnen, etc...) ist in PHP etwas problematisch und sollte zugunsten der Portabilität (z.B. wechsel des Webhosters) nicht verwendet werden.

Da ich allerdings nicht weiss worum es hier genau geht (die Beschreibung zum Sinn des Codes oben ist doch etwas "dürftig", um nicht zu sagen nicht-existent) kann ich hier keine Alternativen vorschlagen.

@Ambience:

Sag uns doch erstmal was du genau bezwecken willst, dann fällt mir auch ganz sicher eine Lösung ein die Race-Conditions ausschliesst und trotzdem sauber implementierbar ist.
Benutzeravatar
Ambience
Mitglied
Beiträge: 628
Registriert: 02.09.2006 11:28
Wohnort: daheim
Kontaktdaten:

Beitrag von Ambience »

ich sitze gerade daran einen chatmod für phpbb zu basteln. der außerdem einen bot hat, mitdem man chatten kann, und wenn einer spamt, kickt ihn der bot automatisch..


nun bisher hatte ich es so, das wenn man chattet, wird jede sekunde die zeilen ab 20 gelöscht. sodass die dateien nicht zu groß werden, da der chat mit datenbank richtig abkackte... nun verschluckt der chat aber abungzu eine nachricht, weil er genau dann eine zeile löscht wenn man gerade antwortet und somit wird diese überschrieben.

edit: sowas wie sperrvariablen und datei locken, mit lock_ini_ odersowas das geht, habe ich gelesen, nur habe ich keine ahnung wie man das benutzt, da ich denke das es für eine andere sprache als für php ist.
Antworten

Zurück zu „Coding & Technik“