config = $config ? $config : Setting::get ("config", $name); $this->prefix = (!empty ($this->config['prefix'])) ? ($this->config['prefix']."_") : ""; if (!isset (self::$linkids[$name])) { // neue Verbindung aufbauen if (!function_exists ("mysqli_connect")) { $this->errmsg = "mysql are not supported by the installed php"; $this->err = $this->errorHandler ("db-initialisation", $noerr); return; } // Konfiguration prüfen if (!$this->config) { $this->errmsg = "database configuration missing"; $this->err = $this->errorHandler ("db-config", $noerr); return; } if (!$this->config['database']) { $this->errmsg = "no database name given"; $this->err = $this->errorHandler ("db-config", $noerr); return; } // Verbindung aufbauen $this->linkid = @mysqli_connect ($this->config['hostname'], $this->config['username'], $this->config['password']); if (!$this->linkid) { $this->errmsg = "database connection error"; $this->err = $this->errorHandler ("db-connekt", $noerr); } if ($this->linkid && $this->config['database']!="-") { @mysqli_select_db ($this->linkid, $this->config['database']); $this->err = $this->errorHandler ("db-select", $noerr); } self::$linkids[$name] = $this->linkid; } else { $this->linkid = self::$linkids[$name]; } } /** * Gibt die Werte der Objekt Variablen zurück * * \param name Name der abgefragten Objekt Variable. Definierte namen sind: * - name: Aktuell verwendeter Konfigurations Name * - rowid: Id der letzten Zeile die in der Datenbank eingefügt wurde * - result: Ergebnis der letzten Select abfrage * - alle privaten Objekt Variablen * * \return Wert der abgefragten Objekt Variable */ public function __get ($name) { switch ($name) { case "name": return !empty ($_SESSION['cms']['database']['name']) ? $_SESSION['cms']['database']['name'] : "db"; case "rowid": return @mysqli_insert_id ($this->linkid); case "result": $result = array (); if (@mysqli_data_seek ($this->queryid, 0)) { while ($row = @mysqli_fetch_assoc ($this->queryid)) { $result[] = $row; } } return $result; case "rows": return mysqli_affected_rows ($this->linkid); default: if (isset ($this->$name)) { return $this->$name; } else { Base::error ("Undefined property: Database::\$$name"); } } } /** * Setz den Wert einiger Objekt Variablen * * \param name Name der Objekt Variable die gesetzt werden soll. Definierte namen sind: * - errors: Anzahl der Fehler * - name: Name der Datenbank Konfiguration auswählen */ public function __set ($name, $value) { switch ($name) { case "errors": $this->errors = $value; break; case "name": Base::session_open (); $_SESSION['cms']['database']['name'] = $value; Base::session_close (); break; } } /** * Prüft ob eine Objekt Variable gesetzt ist * * \param name Name der Objekt Variable * * \return true wenn die Objekt Variable gesetzt ist, sonst false */ public function __isset ($name) { return isset ($this->$name); } /** * Löscht eine Objekt Variable * * \param name Name der Objekt Variable */ public function __unset ($name) { unset ($this->$name); } /** * Setzt den den Iterator auf die erste Ergebniszeile */ public function rewind () { $this->key = 0; @mysqli_data_seek ($this->queryid, 0); } /** * Setzt den den Iterator auf eine bestimmte Ergebniszeile * * \param key Schlüssel der Ergebniszeile */ public function seek ($key) { if (@mysqli_data_seek ($this->queryid, $key)) { $this->key = $key; } } /** * Liefert die aktuelle Ergebniszeile * * \return aktuelle Ergebniszeile */ public function current () { return @mysqli_fetch_assoc ($this->queryid); } /** * Liefert den Schlüssel zur aktuellen Ergebniszeile * * \return Schlüssel der aktuellen Ergebniszeile */ public function key () { return $this->key; } /** * Setzt den Iterator auf die nächste Ergebniszeile */ public function next () { $this->key ++; } /** * Prüft ob die Ergebniszeile auf den der Iterator zeigt existiert * * \return true wenn die Ergebniszeile existiert, sonst false */ public function valid () { return $this->key < @mysqli_num_rows ($this->queryid); } /** * Prüft ob ein Feld in der ersten Ergebniszeile gesetzt ist (name ist ein string), oder ob eine Ergebniszeile existiert (name ist ein Integer) \n * Bsp.: if ($database['name']) \n * Bsp.: if ($database[3]) * * \param name Name des Feldes oder id der Zeile * * \return true wenn das Feld (die Zeile) gesetzt ist, sonst false */ public function offsetExists ($key) { if (is_int ($key)) { return $key < mysqli_num_rows ($this->queryid); } else { return @mysqli_result ($this->queryid, 0, $key) !== false; } } /** * Liefert den Wert eines Feldes in der ersten Ergebniszeile (name ist ein string), oder eine Ergebniszeile (name ist ein Integer) \n * Bsp.: $text = $database['name'] * Bsp.: $text = $database[3] * * \param name Name des Elementes * * \return Wert des Elementes */ public function offsetGet ($key) { if (is_int ($key)) { if (@mysqli_data_seek ($this->queryid, $key)) { return mysqli_fetch_assoc ($this->queryid); } else { return false; } } else { if (@mysqli_data_seek ($this->queryid, 0)) { $row = mysqli_fetch_assoc ($this->queryid); return $row[$key]; } else { return false; } } } /** * Keine Funktion */ public function offsetSet ($key, $entry) { } /** * Keine Funktion */ public function offsetUnset ($key) { } /** * Anzahl der Ergebniszeilen * * \return Anzahl der Ergebniszeilen */ public function count () { return mysqli_num_rows ($this->queryid); } /** * Prüft ob die Datenbank verfügbar ist * * \return false wenn alles ok ist, andernfalls den Fehlertext als String */ public static function check () { $db = new Database ("", null, true); if ($db->err) { return $db->errmsg; } return false; } //*************************** // TOOLS //*************************** /** * Verwirft alle offenen Verbindungen zur DB */ public static function resetConnections () { self::$linkids = array (); } /** * Führt eine Datenbank Abfrage durch * * \param query Abfrage die durchgeführt werden soll * \param noerr wenn true dann wird ein eventuell auftretender Fehler ignoriert (auch nicht geloggt) * * \return true wenn Abfrage erfolgreich, sonst false */ public function query ($query, $noerr=false) { if (!$this->linkid) { return false; } $this->query = str_replace ("{prefix}", $this->prefix, $query); $this->queryid = mysqli_query ($this->linkid, $this->query); $this->err = $this->errorHandler ($this->query, $noerr); return $this->err ? false : (preg_match ("/^(SELECT|INSERT|UPDATE|DELETE)/i", $query) ? mysqli_affected_rows ($this->linkid) : $this->queryid!==false); } // escapeString (auch für Arrays) /** * Escapet einen String damit er in einer Datenbankabfrage als String übergeben werden kann * * \param data Zu escapener Wert * \param stripslashes wenn true dann werden bereits escapte Zeichen nicht noch einmal escapet * * \return escapte Wert */ public static function escape ($data, $stripslashes=true) { if (function_exists ("mysqli_escape_string") && reset(self::$linkids)) { if (is_array ($data)) { foreach ($data as $key => $value) { $data[$key] = self::escape ($value, $stripslashes); } } else { $data = mysqli_escape_string (reset(self::$linkids), ($stripslashes) ? stripslashes ($data) : $data); } } return $data; } /** * Fehlerbehandlung / Logdatei schreiben * * \param action Durchgeführte Aktion * \param noerr wenn true dann werden aufgetretene Fehler nicht geloggt * * \return true wenn ein Fehler aufgetreten ist, sonst false */ private function errorHandler ($action, $noerr=false) { if (!$this->linkid) { // keine Verbindung zur Datenbank } else if (mysqli_errno ($this->linkid)) { // ein Fehler ist aufgetreten $this->errmsg = mysqli_error ($this->linkid); $this->errnum = mysqli_errno ($this->linkid); } else { // kein Fehler aufgetreten return false; } if (!$noerr) { // den aufgetretenen Fehler loggen/ausgeben $this->errors++; $e = new Exception (); $t = $e->getTrace(); $errplace = ((isset ($t[2]['class']) && $t[2]['class']) ? "{$t[2]['class']}::" : "").((isset ($t[2]['function']) && $t[2]['function']) ? "{$t[2]['function']}()" : "")." in {$t[1]['file']} on line {$t[1]['line']}"; $this->action = $action; $this->err = true; $this->errmsg = str_replace ("; check the manual that corresponds to your MySQL server version for the right syntax to use", "", $this->errmsg); $datum = date ("d.m.y H:i:s"); $action = (strlen ($this->action)>300) ? (substr ($this->action, 0, 200) . " ... " . substr ($this->action, -100)) : $this->action; $errorcont = "time: $datum \nplace: $errplace\naction: $action \nerror number: $this->errnum \nerror description: $this->errmsg \n\n"; if (!empty ($this->config['verbose'])) { Base::error ("Database: ".$this->errmsg, E_USER_WARNING, 2); } if (!empty ($this->config['logfile'])) { $logfile = Setting::get ("config", "documentRoot") . $this->config['logfile']; if ($fp = @fopen ($logfile, "a+")) { fputs ($fp, $errorcont); fclose ($fp); } else { Base::error ("Can't write Logfile '".Setting::get ("config", "documentRoot") . $this->config['logfile']."'", E_USER_NOTICE, 0); } } } return true; } } ?>