Ankündigung

Einklappen
Keine Ankündigung bisher.

PHP Script frisst Speicher und gibt ihn scheinbar nicht wieder frei

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

  • PHP Script frisst Speicher und gibt ihn scheinbar nicht wieder frei

    Ich habe zum Freischalten von Einträgen in einer MySQL Datenbank ein Script geschrieben.

    Und es funktioniert auch ohne Fehler, aber es gibt ein großes Problem. Immer wenn man einen Eintrag freigeschaltet hat, also in die andere Tabelle geschrieben und aus der alten Tabelle gelöscht hat. Ist die komplette Webseite extrem langsam und ist kurze Zeit nicht mehr erreichbar.

    Wenn man mehrere Einträge hintereinander freischaltet, dann kommt oft die Fehlermeldung "Warning: mysql_connect() [function.mysql-connect]: Too many connections in".

    Ich denke da wiederholt sich ständig eine While-Schleife. Nur leider habe ich nicht genügend Ahnung von PHP, als dass ich den Fehler finden könnte. Daher würde ich mich freuen, wenn ihr mir vielleicht Tipps geben könntet, wie ich den Code entsprechend optimieren kann

    Den Code findet ihr unten.

    Die Datei mysql.php enthält folgenden Code:

    PHP-Code:
    <?php
        $host 
    "localhost"// hostname
        
    $user "bla";        // Nichname 
        
    $pass "blabla";        // Passwort
        
    $database "datenbank";    // Name der Datenbank 
        
    $dz mysql_connect($host$user$pass); // mysql_connect() nimmt Kontakt mit der Datenbank auf und übergeben ihr die Werte 
        
    mysql_select_db($database$dz); 
        
    /*mysql_select_db() mit dieser Funktionen wird der Name 
        der Datenbank und der Datenbankzeiger übergeben.*/
    ?>
    Und das ist die Datei zum Freischalten der Einträge:

    PHP-Code:
    <?
            /* Standardseite, die eingebunden werden soll */
    $ipage = '../mysql.php';
    if (isset($_GET['page']))
    {
        /* Mit basename() wird der Dateiname extrahiert, Beispiel:
           basename('foo/bar') -> 'bar' */
        $page = basename($_GET['page']);
        /* temporäre Variable für den vollen Pfad der Datei */
        $tpage = 'content/' . $page . '.php';
        /* Test ob die Datei lokal existiert */
        if (file_exists($tpage))
        {
            /* $ipage wird nur verändert, wenn alle Bedingungen zutreffen */
            $ipage = $tpage;
        }
    }
    include($ipage);    
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Admin</title>
    </head>

    <body>
    <?
            $save = $_POST['speichern'];
            $senden = $_POST['senden'];
            $ok = false;
            $id = $_GET['id'];
            
            if ($ok !== true) {
            
            $sql = mysql_query("SELECT * FROM `freischalten` WHERE old_id = '".mysql_real_escape_string($id)."'") or die(mysql_error());
            while(list($old_id, $datum, $kategorie, $hits, $text, $tags, $titel, $url, $domains, $email, $aktiv) = mysql_fetch_row($sql)) {
            ?>
                <form method="post" action="">
                
                <input type="text" name="datum" size="30" value="<?=htmlspecialchars($datum)?>" /> Datum<br />
                <input type="text" name="kategorie" size="30" value="<?=htmlspecialchars($kategorie)?>" /> Kategorie<br />
                <input type="text" name="hits" size="10" value="<?=htmlspecialchars($hits)?>" /> Hits<br />
                <input type="text" name="tags" size="65" value="<?=htmlspecialchars($tags)?>" /> Tags<br />
                <textarea name="text" rows="20" cols="40"><?=htmlspecialchars($text)?></textarea><br />
                <input type="text" name="titel" size="60" value="<?=htmlspecialchars($titel)?>" /> Titel<br />
                <input type="text" name="url" size="60" value="<?=htmlspecialchars($url)?>" /> URL<br />
                <input type="text" name="domains" size="50" value="<?=htmlspecialchars($domains)?>" /> Domains<br />
                <input type="text" name="email" size="30" value="<?=htmlspecialchars($email)?>" /> Email<br />
                <input type="text" name="aktiv" size="10" value="<?=htmlspecialchars($aktiv)?>" /> Aktiv<br />
                <input type="hidden" name="speichern" value="speichern" />
                &nbsp;<br />
            
                <input type="submit" name="senden" value="senden" />
          
                </form>
            <?
            }
            mysql_free_result($sql);
            mysql_close($dz);
            }
            
            if (isset($senden)) {
            /* Standardseite, die eingebunden werden soll */
    $ipage = '../mysql.php';
    if (isset($_GET['page']))
    {
        /* Mit basename() wird der Dateiname extrahiert, Beispiel:
           basename('foo/bar') -> 'bar' */
        $page = basename($_GET['page']);
        /* temporäre Variable für den vollen Pfad der Datei */
        $tpage = 'content/' . $page . '.php';
        /* Test ob die Datei lokal existiert */
        if (file_exists($tpage))
        {
            /* $ipage wird nur verändert, wenn alle Bedingungen zutreffen */
            $ipage = $tpage;
        }
    }
    include($ipage);    
                if ($save == "speichern") {
                    $_POST = array_map('stripslashes', $_POST);
                    $datum = $_POST['datum'];
                    $kategorie = $_POST['kategorie'];
                    $hits = $_POST['hits'];
                    $tags = $_POST['tags'];
                    $text = $_POST['text'];
                    $titel = $_POST['titel'];
                    $url = $_POST['url'];
                    $domains = $_POST['domains'];
                    $email = $_POST['email'];
                    $aktiv = $_POST['aktiv'];
                    $rssdate = date("r");
                
                    $query = mysql_query("INSERT INTO `beitraege` (datum, kategorie, hits, text, titel, url, domains, email, aktiv, rssdate) VALUES ('".mysql_real_escape_string($datum)."', '".mysql_real_escape_string($kategorie)."', '".mysql_real_escape_string($hits)."', '".mysql_real_escape_string($text)."', '".mysql_real_escape_string($titel)."', '".mysql_real_escape_string($url)."', '".mysql_real_escape_string($domains)."', '".mysql_real_escape_string($email)."', '".mysql_real_escape_string($aktiv)."', '".mysql_real_escape_string($rssdate)."')") or die(mysql_error());
                    
                    $query = mysql_query("SELECT * FROM `beitraege` WHERE datum = '".mysql_real_escape_string($datum)."'") or die(mysql_error());
                    $ds = mysql_fetch_object($query);
                    $new_id = $ds -> id;
                    
                    /* Ich schreibe meinen Kram mal drüber */
                    $eingegebene_tags = $tags;
                    
                    $beitrag_id=$new_id;

                    // Evtl. willst du die vorher noch mit strtolower alle klein schreiben, 
                    // keine Ahnung

                    // An ",", ";" , " " aufteilen
                    $tags = preg_split("/[,; ]+/", $eingegebene_tags, -1, PREG_SPLIT_NO_EMPTY);

                    // für den DB Kram gleich mal escapen
                    $tags = array_map('mysql_escape_string', $tags);

                    if (count($tags)==0) die("keine Tags");

                    // Nachschauen, welche davon es schon gibt
                    $res = mysql_query("SELECT id, tags FROM tags WHERE LOWER(tags) IN ('" . implode("','", array_map('strtolower', $tags)) . "')") or die(mysql_error());

                    $tag_id=Array();
                    while($d = mysql_fetch_row($res)) 
                        $tag_id[$d[1]] = $d[0];

                    // Nachschauen, welche eingegebenen Tags "neu" sind
                    $tag_neu = array_diff($tags, array_keys($tag_id));

                    // Diese per Schleife in der DB anlegen und die IDs merken
                    foreach($tag_neu as $t) {
                        mysql_query("INSERT INTO tags(tags) VALUES('$t')"); //or die(mysql_error());
                        $tag_id[$t] = mysql_insert_id();
                        }

                    // In $tag_id stehen jetzt _ALLE_ Tags mit passender ID, also rein damit in 
                    // die Beitragstabelle
                    foreach($tag_id as $t) {
                        mysql_query("INSERT INTO tags_beitraege(beitrag_id, tag_id) VALUES ($beitrag_id, $t)") or die(mysql_error());
                        $ok = true;
                        }

                    //
        mysql_free_result($res);            
        mysql_free_result($query);            
        mysql_close($dz);        
                    
            /* Standardseite, die eingebunden werden soll */
    $ipage = '../mysql.php';
    if (isset($_GET['page']))
    {
        /* Mit basename() wird der Dateiname extrahiert, Beispiel:
           basename('foo/bar') -> 'bar' */
        $page = basename($_GET['page']);
        /* temporäre Variable für den vollen Pfad der Datei */
        $tpage = 'content/' . $page . '.php';
        /* Test ob die Datei lokal existiert */
        if (file_exists($tpage))
        {
            /* $ipage wird nur verändert, wenn alle Bedingungen zutreffen */
            $ipage = $tpage;
        }
    }
    include($ipage);
        if ($ok == true) {
        ?>
        <div class="kommentar_richtig" style="font-size:16px;">Der Eintrag wurde freigeschaltet, die Best&auml;tigunsmail wurde verschickt und der Eintrag aus der alten DB entfernt.</div>
        <?
        
        $delete = mysql_query("DELETE FROM `freischalten` WHERE old_id = '".mysql_real_escape_string($id)."' ") or die(mysql_error());
                     
              $mail_titel = "TEST";
              $mail_body ="BLA BLA BLA";
              $header  = "MIME-Version: 1.0" . "\n";
              $header .= "Content-type: text/html; charset=iso-8859-1" . "\n";
              $header .= "From: Admin <mail@domain.tld>" . "\n";
              mail($email,$mail_titel,$mail_body,$header);
        
        }
            //////////// Bestätigunsmail für die Freischaltung ////////////
                }
            
            }
            ?>
    </body>
    </html>
    Ich hoffe ich konnte mein Problem gut genug schildern


  • #2
    Um wie viele Einträge geht's in den Tabellen?
    Ggfls. könnte ein falsch gesetzter Index Probleme machen.

    BTW, falls der Code Copy'N'Paste war solltest du dir einen einheitlicheren Einrückungsstil angewöhnen, so ist das extrem schwer zu lesen.
    Und ShortOpenTags sind NoGo - und werden in den kommenden PHP-Versionen nicht mehr unterstützt.
    actra.development - Zend Certified Engineer for PHP5 - actra-oss @ github

    Kommentar


    • #3
      in der Tabelle "freischalten" sind meistens 0 - 10 Einträge (aktuell aber ca. 70, weil ich nichts mehr freischalten, wegen dem bekannten Problem) und in der Tabelle "beitraege" sind aktuell ca. 800 Einträge.

      Danke für die Hinweis, wegen dem Einrücken und den Shortopentags.

      Kommentar


      • #4
        Mit der Menge der Einträge wird das nichts zu tun haben.
        Ein mysql_connect() innerhalb einer Schleife finde ich so auf Anhieb auch nicht.
        Aber vielleicht befindet sich der Fehler ja auch in der mysql.php?
        Competence-Center -> Enjoy the Informatrix
        PHProcks!Einsteiger freundliche Tutorials

        Kommentar


        • #5
          In der mysql.php ist nur der Teil, der oben publiziert ist. Daran kann es nicht liegen oder?

          Kommentar


          • #6
            PHP-Code:
            if($ok !== true
            Da $ok bei Dir eh ein Boolean ist würde eine dieser Varianten reichen:
            PHP-Code:
            if($ok != true)
            if(!
            $ok
            Aber zu Deinem Problem! Ich versuch das mal in Stichpunkten Worten zu durchlaufen:
            - Du öffnest eine DB-Verbindung (Zeile 18 )
            - NUR wenn $ok == true ist, wird diese geschlossen (Zeile 60)!
            - Wenn $senden übermittelt wurde, öffnest Du eine weitere Verbindung (Zeile 80)
            - Und in Zeile 160 öffnest Du eine weitere!

            Das mag vielleicht nicht unbedingt Dein Problem lösen, aber effizient ist es auch nicht.
            Öffne am Anfang Deines Scriptes eine DB-Connection und schliesse sie am Ende wieder.
            Dann sehen wir weiter, was für Fehler noch auftauchen...
            Competence-Center -> Enjoy the Informatrix
            PHProcks!Einsteiger freundliche Tutorials

            Kommentar


            • #7
              Danke für den Hinweis, ich habe es in der Datei geändert. Leider besteht immer noch das gleiche Problem, wie oben beschrieben.

              Vielleicht könnten folgende Werte interessant sein und weiter helfen:

              Uptime (3836842)
              Threads (3)
              Questions (8665116)
              Slow queries (27219)
              Opens (521979)
              Flush tables (1)
              Open tables (64)
              Queries per second avg (2.258 )
              108860 (memory_get_usage)

              Kommentar

              Lädt...
              X