DB-Abfrage führt zu Verbindungsabbruch bzw. Apache-Crash

Irgendwelche Probleme mit XAMPP für Windows? Dann ist hier genau der richtige Ort um nachzufragen.

DB-Abfrage führt zu Verbindungsabbruch bzw. Apache-Crash

Postby jrooster » 26. June 2014 11:09

Hallo Community.

Ich habe ein sehr "wildes" Verhalten meiner MySQL-Datenbank und PHP unter Xampp auf WIn7 64 Bit (unter einem Linux-System laufen die gleichen Skripte und Daten einwandfrei).

Kurz formuliert:
Bei der Abfrage mancher (aber immer der gleichen) Datenbanktabellen via PHP bricht der Browser (hier FF) mit einer Fehlermeldung "Fehler: Verbindung unterbrochen. Die Verbindung wurde zurückgesetzt, während die Seite geladen wurde." ab.

Lang formuliert:
Innerhalb einer eigenen Datenbankklasse frage ich mit Hilfe dieser beiden Methoden einen Datensatz ab ("SELECT * FROM drecks_tabelle"). Die Tabelle beinhaltet nur einen einzigen Eintrag.

Code: Select all
// Methode: abfragen   
public function query($query) {

   $this->dbLastError = '';
   $this->dbLastErrorNr = 0;

   $this->connect();

   // Zeichensatz ausgewählt?
   if ($this->useCharset) {
      mysqli_query($this->connection, "SET NAMES '".$this->useCharset."'");
   }

   $dbResult = mysqli_query($this->connection, $query);

   if (!mysqli_error($this->connection)) {
      if (!$dbResult || empty ($dbResult)) {
         mysqli_free_result($dbResult);
      } else {
         $this->dbResult = $dbResult;
      }
      $this->dbLastError = '';
      $this->dbLastErrorNr = 0;
   } else {
      $this->dbLastError = mysqli_error($this->connection);
      $this->dbLastErrorNr = mysqli_errno($this->connection);
            
   }
   $this->lastinsertedid = mysqli_insert_id($this->connection);
   return $this->dbLastErrorNr;
}

// Methode: lesen (liefert standarmäßig ein assoziatives Array
public function get($keyType = MYSQL_ASSOC) {

   if ($this->dbResult) {
      $r = mysqli_fetch_array($this->dbResult, $keyType);

      if (is_array($r)) {
         return $r;
      } else {
         return array();
      }
   } else {
      return array();
   }
}


Sobald man nun auf den gelesenen Datensatz zugreift, passiert der Verbindungsfehler. Z.B. wenn man dieses hier tut:

Code: Select all
$db->query ("SELECT * FROM drecks_tabelle LIMIT 1");
$r = $db->get();

$crash = array_shift($r);

// oder:
foreach ($r as $key => $value) {
   //crash
}


Der Fehler passiert auch nicht bei allen Tabellen in der Datenbank, sondern nur bei einigen, und auch nur dann, wenn diese Tabellen nicht leer sind, also Daten gelesen werden. Ich kann allerdings nichts außergewöhnliches an diesen Crash-Tabellen erkennen:
Engine: mal InnoDB, mal MyISAM
Kollation: utf8_unicode_ci
Größe: 1-100 Datensätze
Keine Fehler (analyze und repair tun nichts weiter als "alles ok" sagen).

Interessanterweise tritt das Problem in phpMyAdmin nicht auf. Das heißt, damit kann ich "drecks_tabelle" problemlos lesen und die Inhalte bearbeitenn.

Das o.g. Skript und "drecks_tabelle" sind Teil eines Webprojektes. Dieses Webprojekt habe ich versuchsweise auf mehreren Systemen laufen lassen - mit folgenden, unerschiedlichen Ergebnissen:

1. Xampp 1.8.3, Win7 64-Bit
Skript läuft ca. 30 Sekunden und crasht mit dem Verbindungsfehler. Im Xampp-Control-Center wechselt der Status des Apache zweimal kurz von grün nach gelb während das Abfrageskript läuft. In den Log-Files sieht es so aus, als ob der Apache zweimal neu startet.

2. Xampp 1.8.2, Win7 64-Bit
Gleiches Verhalten wie 1. Allerdings scheint diese Version etwas Fehler toleranter zu sein. Die Abbrüche treten an einer anderen Stelle im Datenbakskript auf.

3. Wamp (PHP 5.5.12, MySQL 5.6.17), Win7 64-Bit
Gleiches Verhalten wie 1.

4. Lampp, Apache/2.2.22, MySQL-Client-Version: 5.5.28, anderer Rechner als 1-3
Keine Probleme, gesamte Website und alle Skripte laufen einwandfrei!

Weiß vielleicht jeamand Rat oder hat ein ähnliches Problem schonmal gehabt? Ich bin mit meinem Latein nach mehreren Xampp- (und Wamp-) Neuinstallationen etwas am Ende.

Vielen Dnak für eure Hilfe schon jetzt. Grüße, Joe
jrooster
 
Posts: 2
Joined: 26. June 2014 10:15
Operating System: win7

Re: DB-Abfrage führt zu Verbindungsabbruch bzw. Apache-Crash

Postby Nobbie » 26. June 2014 13:14

Bau mal ein paar echo ein, wo Du Fehlerfälle behandelst. in der Methode query() setzt Du zwar alle möglichen Werte, aber abfragen tust Du sie nirgends, den return-Wert berücksichtigst Du im Script auch nicht. Also da gibt es massiven Nachholbedarf, ob Du irgendeinen Fehlerfall übersiehst.

Und dann sieht dieses Konstrukt saugefährlich aus:

if (!$dbResult || empty ($dbResult)) {
mysqli_free_result($dbResult);


Da machst einen free auf einen NULL Wert? Das wundert mich gar nicht, wenn das knallt. Das dürfte auch sehr vom System abhängig sein, ob da interner Speicherplatz zerstört wird. Diese ganzen free-Aufrufe halte ich alle grundsätzlich für Quatsch, der Speicher wird vom System sowieso zum Scriptende freigegeben, nimm das so oder so heraus.

Möglicherweise liegt es schon daran. Sonst wie gesagt, unbedingt mehr Fehlerbehandlung einbauen.

P.S.: Der nächste Fehler passiert, wenn mysqli_error() einen gültigen Wert zurückgibt (wenn also irgendein Fehler aufgetreten ist), dann bekommt $this->dbresult KEINEN WERT zugewiesen, aber im nachfolgenden db->get() gibst Du $this-dbresult() an einen fetch(). Das wird wahrscheinlich zu einem leeren Array führen (oder irgendeinen invaliden Wert), darauf führst einen array_shift() aus, das könnte auch knallen. Also das ganze Ding ist ultra unsauber programmiert, da fehlen Fehlerabbrüche und alles.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: DB-Abfrage führt zu Verbindungsabbruch bzw. Apache-Crash

Postby jrooster » 26. June 2014 14:01

Hi Nobbie.

Vielen Dank für deine Antwort. Das free_result Statement habe ich entfernt. Das hatte leider keine Auswirkungen auf das Problem. Apache crasht weiterhin. Das Problem mit den echos ist, dass diese nicht mehr im Browser angezeigt werden, wenn der Fehler mal passiert ist, weil ja die Verbindung abgebrochen wird, wie ich geschrieben habe. Außer dieser Browser-Fehlermeldung steht dann da nix mehr. Auch nichts, was zuvor per echo ausgegeben wurde. Zudem habe ich mich an die Commmunity gewandt, nachdem ich mir schon etliche Werte ausgeechot hatte und selbst nicht mehr weiter weiß.

Die zwei Methoden stammen aus einer Klasse und sollten nur zur Veranschaulichung einer Abfrage dienen. Deshalb stehen da noch Werte drin, die halt anderswo in der Klasse genutzt werden.

Der nächste Fehler passiert, wenn mysqli_error() einen gültigen Wert zurückgibt (wenn also irgendein Fehler aufgetreten ist), dann bekommt $this->dbresult KEINEN WERT zugewiesen, aber im nachfolgenden db->get() gibst Du $this-dbresult() an einen fetch().

Nein, das passiert nicht, da ja in der Methode get() folgendes steht:
Code: Select all
if ($this->dbResult) {
      $r = mysqli_fetch_array($this->dbResult, $keyType);
      [...]
}


Das wird wahrscheinlich zu einem leeren Array führen (oder irgendeinen invaliden Wert), darauf führst einen array_shift() aus, das könnte auch knallen.

Nein, das knallt nicht. PHP gibt einfach nichts zurück, wenn man das erste Element eines leeren Arrays holt. Die Methode get() gibt darüber hinaus in jedem Fall ein Array zurück, auch wenn das Ergebnis des fetch einen anderen leeren Wert hat.

Und auch hier: das Code-Schnippsel sollte nur zur Veranschaulichung dienen und kommt so nicht in meiner Klasse vor.

Grüße, Joe
jrooster
 
Posts: 2
Joined: 26. June 2014 10:15
Operating System: win7

Re: DB-Abfrage führt zu Verbindungsabbruch bzw. Apache-Crash

Postby Nobbie » 26. June 2014 15:48

jrooster wrote:Nein, das passiert nicht, da ja in der Methode get() folgendes steht:
Code: Select all
if ($this->dbResult) {
      $r = mysqli_fetch_array($this->dbResult, $keyType);
      [...]
}


Aber gerade das ist doch Schrott - ich kann den Konstruktor nicht sehen und wenn $dbresult nicht intialisiert ist, steht da irgendein Speicherschrott drin.

jrooster wrote:Und auch hier: das Code-Schnippsel sollte nur zur Veranschaulichung dienen und kommt so nicht in meiner Klasse vor.


Das heißt für mich in jedem Fall: Ende. Ich debugge doch keinen Schnipselcode, wie er gar nicht zum Einsatz kommt. Mit absoluter Sicherheit zerballerst Du irgendwelche internen Speicherstrukturen, aber das kann man nur durch geeignetes debuggen herausfinden. Mit Pseudocode erreicht man lediglich, dass die eigentliche Ursache verschleiert wird (das ist in 99,99% aller Probleme der Fall, stelle ich immer wieder fest). Es ist markant, dass das in phpmyadmin nicht abstürzt, es liegt also nicht am MySQL, sondern ist liegt irgendwo in Deinem PHP Code.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04


Return to XAMPP für Windows

Who is online

Users browsing this forum: No registered users and 11 guests