Ankündigung

Einklappen
Keine Ankündigung bisher.

Speicherbproblem beim E-Mails abrufen mit PHP

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Speicherbproblem beim E-Mails abrufen mit PHP

    Servus!

    Ich habe ein Problem mit meinem PHP Code. Ich habe ihn mal stark vereinfacht unten reinkopiert.

    Und zwar geht es darum, dass ich ein Skript laufen habe, welches alle 10 Minuten ein Mailpostfach prüft. Wenn eine E-Mail mit bestimmten Kriterien gefunden wird (Absender, Betreff, und gültiges XML im Body), dann wird die Mail weiterverarbeitet danach gelöscht. Ansonsten wird die Mail nur als gelesen markiert und danach irgendwann manuell gelöscht. (Das hat einfach den Grund, dass man alle paar Tage überprüfen kann, ob nicht doch eine E-Mail durchs Raster gerutscht ist...)

    Die Weiterverarbeitung der Mail besteht aus dem Auslesen eines XML-Strings, und dem Speichern in einer Datenbank.


    So.
    Das Skript tut was es soll - es erkennt bestimmte E-Mails und speichert die gewünschten Daten in eine Datenbank. Das funktioniert auch richtig gut. Bis auf einen Haken:
    Nach JEDEM Skriptaufruf wächst der Speicherbedarf des Windows-Apache um einige MB. Irgendwann ist kein Arbeitsspeicher mehr da, und der Apache schmiert ab (Startet i.d.R. aber wieder automatisch neu).

    Warum ist das so? Was frisst hier so viel Speicher?
    Ich schließe die Verbindung zum E-Mail Server doch jedes mal wieder ( mittels imap_close($mailbox); ).

    Kann jemand in diesem (stark vereinfachten und gekürztem) Code einen Denkfehler finden? Oder hat sonst einer eine Idee woran das liegen könnte, dass das Skript immer mehr Speicher frisst und nicht mehr freigibt?



    PHP-Code:
    $mailbox imap_open("{mail.server.de:143/novalidate-cert}INBOX","mail@adresse.de","passwort")
        or die(
    "Can't connect: " imap_last_error());
    $mails imap_fetch_overview($mailbox,"1:*"FT_UID); 
    $size=count($mails); 
    for(
    $i=$size-1;$i>=0;$i--){ 
            
    $cmsg++;
            
    $value $mails[$i];
            
        
            
    $empfaenger_adresse $value->to;
            
    $absender_adresse $value->from;  
            
    $mail_datum $value->udate;
            
    $mail_subject $value->subject;
        
            
            
            
    $mail imap_body($mailbox$value->uid,FT_UID);
            
    $structure   imap_fetchstructure($mailbox$value->uid,FT_UID);  
        
            
            
    $ausgabe_log .= "Lese E-Mail ".$value->uid" ... Empfaenger: $empfaenger_adresse Betreff: $mail_subject \r\n";    
            if(
    $structure->encoding == 3) {
               
    $mail imap_base64($mail);
               
    $ausgabe_log .= "Codierung base64 ... \r\n";    
            }
            else if(
    $structure->encoding == 4) {
               
    $ausgabe_log .= "Codierung Quoted Print ... \r\n";    
               
    $mail imap_qprint($mail);
            }
            
            
    //Hier weitere Bearbeitungen
    //XML ermitteln und in DB Speichern, usw...
                

            
    imap_delete($mailbox$value->uidFT_UID);

           }

           
    imap_expunge($mailbox);   
    imap_close($mailbox); 

    Vielen Dank und viele Grüße!


  • #2
    Schwerwiegende Fehler erkenne ich darin nicht, aber ein paar Kleinigkeiten zur Anmerkung hätte ich:
    PHP-Code:
    $size=count($mails); 
    for(
    $i=$size-1;$i>=0;$i--){ 
    for ist in den meisten Fällen zwar schneller, aber ich würde hier aus Bequemlichkeit einfach foreach nehmen.
    Eingeschlossen der Tatsache, daß Du auf die Eigenschaften des Mail-Objektes ($value) auch dirket zugreifen kannst, sähe das ganze dann so aus:
    PHP-Code:
    $mailbox imap_open'{mail.server.de:143/novalidate-cert}INBOX''mail@example.com''passwort' ) or die( 'Can´t connect: ' imap_last_error() );
    $mails imap_fetch_overview$mailbox'1:*'FT_UID ); 


    foreach ( 
    $mails as $oMailProperties ) {

        
    $cmsg++; // Gesamter Zähler???
        
        
    $mail imap_body$mailbox$oMailProperties->uidFT_UID );
        
    $structure imap_fetchstructure$mailbox$oMailProperties->uidFT_UID );

        
    $ausgabe_log .= 'Lese E-Mail ' $oMailProperties->uid ' ... Empfaenger: ' $oMailProperties->to ' Betreff: ' $oMailProperties->subject PHP_EOL;

        switch ( 
    $structure->encoding ) {
            case 
    3:
                
    $ausgabe_log .= 'Codierung base64 ...' PHP_EOL;
                
    $mail imap_base64$mail );
                break;
            case 
    4:
                
    $ausgabe_log .= 'Codierung Quoted Print ...' PHP_EOL;
                
    $mail imap_qprint$mail );
                break;
            default:
                break;
        }
        
        
    //Hier weitere Bearbeitungen
        //XML ermitteln und in DB Speichern, usw...
        
        
    imap_delete$mailbox$oMailProperties->uidFT_UID );

    }

           
    imap_expunge$mailbox );
    imap_close$mailbox );

    // exit; 
    , denn dieser Part ist eigentlich überflüssig:
    PHP-Code:
    $empfaenger_adresse $oMailProperties->to;
    $absender_adresse $oMailProperties->from;
    $mail_datum $oMailProperties->udate;
    $mail_subject $oMailProperties->subject
    Zusätzlich würde ich das Script an geeigneter Stelle noch explizit beenden mit exit;.
    Ob das Ende Deines geposteten Scriptes nun aber auch das tatsächliche Ende darstellt, weiß ich nicht, daher habe ich es oben in Comments gelegt...

    Die Problematik der Apache-Speicher Auslastung wird das vermutlich nicht beheben, aber Vorschläge sind ja an sich nie verkehrt...
    Competence-Center -> Enjoy the Informatrix
    PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

    Kommentar


    • #3
      Zitat von Arne Drews Beitrag anzeigen
      ...

      Zusätzlich würde ich das Script an geeigneter Stelle noch explizit beenden mit exit;.
      Ob das Ende Deines geposteten Scriptes nun aber auch das tatsächliche Ende darstellt, weiß ich nicht, daher habe ich es oben in Comments gelegt...

      Die Problematik der Apache-Speicher Auslastung wird das vermutlich nicht beheben, aber Vorschläge sind ja an sich nie verkehrt...
      Danke Dir! Bin für Vorschläge immer offen und bin für jeden Tipp dankbar!

      Kommentar


      • #4
        Läuft das per Cornjob oder hast Du im Script ne Wartezeit reingefummelt?
        Competence-Center -> Enjoy the Informatrix
        PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

        Kommentar


        • #5
          Läuft alle 10 Minuten über die "Geplanten Aufgaben" vom Windows Server 2008

          Kommentar


          • #6
            Achso, ne dann wüsste ich ausser dem exit nicht mehr, was evtl. noch Speicherauslastung unterbinden könnte.
            Competence-Center -> Enjoy the Informatrix
            PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

            Kommentar


            • #7
              Ok, ich glaube ich habe das Problem gefunden...
              https://bugs.php.net/bug.php?id=47940

              Weil genau diese Version muss ja auf dem Server laufen, wo mein Script läuft... (Ein Upgrade von 5.2.9 ist aus vielerlei Gründen nicht möglich)
              Ich hoffe ich finde da einen Workaround...

              Kommentar

              Lädt...
              X