Seite 1 von 2

anstatt löschen wird datei immer größer

Verfasst: 05.10.2006 19:15
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;
  }

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

Verfasst: 05.10.2006 19:38
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;
  }

Verfasst: 05.10.2006 19:53
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

Verfasst: 05.10.2006 23:19
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...

Verfasst: 10.10.2006 19:00
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=

Verfasst: 03.11.2006 00:25
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

Verfasst: 04.11.2006 10:57
von Ambience
keiner eine antwort? :-(

Verfasst: 04.11.2006 19:31
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.

Verfasst: 04.11.2006 19:42
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.

Verfasst: 04.11.2006 20:14
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.