Beta-Version meiner MySQLi-Klasse

Im Rahmen meines Frameworks entwickle ich zur Zeit eine Klasse für die Verwaltung meiner Datenbanken.
Hier ist der Code für Interessierte:

class FW_MySQL
{
  protected static $instances = array();
  protected $connection = null;
  protected $log_queries = false;
  protected $log_file    = null;
  protected $dbname      = "";

  protected function __construct($dbName)
  {
    $dbName = strtolower($dbName);
    $dbconfini = FW_Config::getInstance()->get("dbconf");
    if(file_exists($dbconfini))
    {
      $dbconf = parse_ini_file($dbconfini, true);
    }

    if(!isset($dbconf[$dbName]))
    {
      throw new FW_Exception("Keine Konfigurationsdaten für ".$dbName);
    }

    $dbconf = $dbconf[$dbName];  //die anderen array-schlüssel sind für diese Instanz uninteressant.
    $this->dbname = $dbName;

    $username = $dbconf["username"];
    $password = $dbconf["password"];
    $host     = $dbconf["host"];

    $this->connection = new mysqli($host, $username, $password, $dbName);
    if(mysqli_connect_errno())
    {
      $this->connection = null;
      echo "Verbindunsaufbau zu ".$dbName." fehlgeschlagen: ".mysqli_connect_error()."(#".mysqli_connect_errno().")";
    }

    //logging true/false
    if(isset($dbconf["log_queries"]) && $dbconf["log_queries"] == "1")
    {
      $this->log_queries = true;
      if(!isset($dbconf["log_file"]))
      {
        die("Logfile nicht angegeben");
      }
      else
      {
        $this->log_file = $dbconf["log_file"];
      }
    }

    //charset
    if(isset($dbconf["charset"]))
    {
      $this->connection->set_charset($dbconf["charset"]);
    }

  }

  public function countRows($table, $field = null)
  {
    if($this->connectionExists())
    {
      $querystring = "SELECT COUNT(".(($field !== null) ? "`".$field."`" : "*" ).") AS __row_amount FROM ".$this->escape($table);
      $result = $this->query($querystring);
      if(!$result) //Falls die Abfrage nicht erfolgreich war
      {
        throw new FW_Exception("Fehler bei Query: ".$querystring);
      }
      $result = $result->fetch_assoc();
      $amount = $result["__row_amount"];
      return $amount;
    }
    else
    {
      throw new FW_Exception("Keine Verbindung vorhanden");
    }
  }

  public function updateTable($table, array $fields, $where = null)
  {
    $sql = "UPDATE `".$this->escape($table)."` SET ";

    $sum = count($fields);
    $i = 1;
    foreach($fields as $name => $value)
    {
      $sql .= "`".$this->escape($name)."` = ".((is_int($value)) ? $value : "'".$this->escape($value)."'");
      if($sum != $i)
      {
        $sql .= ", ";
      }

      $i++;
    }

    if($where !== null)
    {
      $sql .= " WHERE ".$where;
    }

    $sql .= ";";
    $this->query($sql);
    return $this;
  }

  public function clearTable($table, $reset_all = false)
  {
    if($reset_all === true)
    {
      $this->query("TRUNCATE TABLE `".$this->escape($table)."`;");
    }
    else
    {
      $this->deleteFromTable($table);
    }
    return $this;
  }

  public function deleteFromTable($table, $where = null)
  {
    $this->query("DELETE FROM `".$table."`".(($where !== null) ? " WHERE ".$where.";" : ";"));
    return $this;
  }

  public function escape($string)
  {
    return $this->connection->real_escape_string($string);
  }

  public function connectionExists()
  {
    return ($this->connection !== null) ? true : false;
  }

  public function query($query)
  {
    if($this->connectionExists())
    {
      if($this->log_queries === true)
      {
        $handle = fopen($this->log_file,'a');
        if($handle)
        {
          try
          {
            $string = date("d.m.Y - H:i:s")." | ";
            $string .= $_SERVER["REMOTE_ADDR"]." | ";
            $string .= $query;
      		  FW_Tools::addStringToFile($this->log_file, $string, "", "\r\n");
    		  }
          catch(FW_Exception $e)
          {
            throw new FW_Exception($e->getMessage());
          }
    		}
    		else
    		{
          throw new FW_Exception("Logfile-Error");
        }
      }

      $result = $this->connection->query($query);

      if(!$result)
      {
        if($this->log_queries === true)
        {
          try
          {
            $string  = "---------------\n";
            $string .= "Letzte Abfrage war fehlerhaft (#".$this->connection->errno.": ".$this->connection->error.")";
            $string .= "\n---------------";
            FW_Tools::addStringToFile($this->log_file, $string, "\r\n", "\r\n");
          }
          catch(FW_Exception $e)
          {
            throw new FW_Exception($e->getMessage());
          }
        }
        throw new FW_Exception("Fehlerhafte Abfrage: ".$query);
      }
      return $result;
    }
    else
    {
      throw new FW_Exception("geht nicht ohne verbindung");
    }
  }

  public function getAvailableCharsets() //returns an array of all possible charsets
  {
    if($this->connectionExists())
    {
      $result = $this->query("SHOW CHARACTER SET");
      while($row = $result->fetch_array())
      {
        $return[] = array("charset" => $row["Charset"],
                              "maxlen" => $row["Maxlen"],
                              "description" => $row["Description"],
                              "default_collation" => $row["Default collation"]);
      }
      return $return;
    }
    else
    {
      throw new FW_Exception("Keine Verbindung vorhanden");
    }
  }

  public function getTableNames($prefix = null)
  {
    if($this->connectionExists())
    {
      $result = $this->query("SHOW TABLES FROM ".$this->dbname);
      $return = array();

      while($row = $result->fetch_row())
      {
        if($prefix === null ||
           substr($row[0], 0, strlen($prefix)) == $prefix)
        {
          $return[] = $row[0];
        }
      }

      return $return;
    }
    else
    {
      throw new FW_Exception("Keine Verbindung zur Datenbank vorhanden");
    }
  }

  public function close()
  {
    if($this->connectionExists())
    {
      $this->connection->close();
      $this->connection = null;
    }
    return $this;
  }

  public static function getInstance($dbName)
  {
    if(!isset(self::$instances[strtolower($dbName)]))
    {
      self::$instances[strtolower($dbName)] = new FW_MySQL($dbName);
    }
    return self::$instances[strtolower($dbName)];
  }

  private function __clone() {}

  public function __destruct()
  {
    $this->close();
  }
}
?>

Die Besonderheit an der Klasse ist, dass es möglich ist, mehrere Datenbanken anzusprechen. Es ist eine Art „gelockertes Singleton“, weil es mehrere Instanzen der Klasse geben kann, von denen aber immer nur eine Instanz pro Datenbank existiert.

1 Star2 Stars3 Stars4 Stars5 Stars (1 Stimme, durchschnittlich 5,00 / 5)
Loading...


18 Kommentare zu “Beta-Version meiner MySQLi-Klasse”

  1. Hi Simon,

    schaut doch gut aus… Nix abgeschnitten und alles schön gehighlighted…

    Viele Grüße

    Tim

  2. Hi,
    auf den ersten Blick ja…
    aber diese Zeile hier wird abgeschnitten:
    $dbconf = $dbconf[$dbName]; //die anderen array-schlüssel sind für diese In (und hier fehlt dann der rest des kommentars)

    auch manche andere zeilen werden nicht vollständig angezeigt.

    Ansonsten sieht es schon gut aus 😉

  3. Auf meinem Blog zeigt er bei zu langen Zeilen eine Scrollbar an… Ich schätze mal, es liegt an einer Stylesheet-Definition bei Dir… Hoffe der Tipp, hilft!

  4. also irgendwie zeigt der IE die ganze Seite hier falsch an.
    Sieht das bei dir (PHP Blogger) auch so aus?

    Das Menü sieht ziemlich kaputt aus

  5. Keine Ahnung, bin mit meinem Mac unterwegs…

  6. ok, nachdem ich meinen cache geleert habe, ging es….
    IE zeigt hier keine Scrollbar an…

  7. @PHP Blogger:
    Danke 🙂
    Ich schau mal, ob ich da was machen kann.

    @ibehs: Bei mir gehts im IE (version 6)

  8. Bei dir im Blog werden auch die Zeilennummern angezeigt.
    Ich glaube, ich habe die falsche CSS-Datei eingebunden.

    Kann das sein?

  9. Naja die Zeilennummern sind wieder was anderes und haben nix mit dem Plugin zu tun – das ist eine reine CSS Geschichte…

  10. Hmm…. keine Ahnung, an was das liegt.
    Evtl. überschreibt mein Theme irgendeine eigenschaft von < pre > – Elementen.
    Ich muss mal schauen

  11. Habe das Problem gefunden.
    Und zwar musste ich einfach overflow auf auto setzen.
    Keine Ahnung, warum das nicht schon fest von diesem Plugin so definiert wird…

    Jedenfalls passt jetzt alles 🙂
    Echt ne gute Sache, dieses Plugin.

    Ich schreibe darüber noch einen Artikel und verlinke natürlich auf deinen Blog 🙂

    Jetzt muss ich aber erst Lernen, morgen Klassenarbeit *kotz*

  12. Alles klar, danke sehr 😉

  13. Gern geschehen 😉
    Hier ist der Artikel: http://www.net-developers.de/2008/12/02/syntaxhighlighter-fur-wordpress-plugin-star-light/

    Muss ggf. noch überarbeitet werden, aber heute nicht mehr

  14. […] war auch die Erweitern des Frameworks notwendig. Insbesondere wurden Models eingeführt. Auch die MySQL-Klasse kann sich sehen […]

  15. Ich finde die Umsetzung gut,nur eine Sache finde ich sicherheitstechnisch seltsam, ich hätte die Informationen über den DBZugriff in einem PHP anstatt in einem Ini File abgelegt, die Ini kann man ja einfach downloaden, oder gibt es da einen Schutz vor??

  16. Hi,

    die Ini-Dateien liegen normalerweise außerhalb des Document-Roots, sind also nicht über das Internet abrufbar.
    Wenn man die Konfiguration trotzdem im WWW-Root haben möchte, nennt man sie einfach config.php statt config.ini… 🙂 Müsste klappen.

    Simon

  17. Dann allerdings schon^^

    Wenn das ganze außerhalb des WWWRoots liegt geht das ja.

  18. Die aktuellste Version meines HMVC-Frameworks erhaltet ihr ab sofort immer hier: http://www.net-developers.de/blog/2011/02/13/download-info-shfw-hmvc-framework-in-php/

Hinterlasse einen Kommentar!

Time limit is exhausted. Please reload the CAPTCHA.

»Informationen zum Artikel

Autor: Simon
Datum: 29.11.2008
Zeit: 23:47 Uhr
Kategorien: Mein MVC-Framework
Gelesen: 47150x heute: 4x

Kommentare: RSS 2.0.
Diesen Artikel kommentieren oder einen Trackback senden.

»Meta