0251 / 590 837 15
info@a-coding-project.de
;

Datenbankklasse Teil 3 (CMS)

Nach dem Durcharbeiten dieses Artikels wird das selbst erstellte CMS erstmal unbenutzbar sein. Wir werden nämlich heute den alten Datenbankzugriff z.T. entfernen. Außerdem wird die Datenbankklasse auf mysqli umgestellt und bei 2 Klassen bauen wir bereits den neuen Datenbankzugriff ein.

Fangen wir an mit mysqli. Leider hatte ich mich zuvor noch nicht damit beschäftigt, so dass ich die Klasse /system/classes/mysql.php erst einmal auf dem veralteten MySQL-Zugriff ansteuerte. Heute gibts das Update auf mysqli. Evtl. werde ich in Kürze einen oder auch mehrere Beiträge (außerhalb der CMS Aktion) über MySQLi veröffentlichen.

Nun gehts aber zur Klasse. MySQLi ist objektorientiert. Die Änderungen die ich gemacht habe werde ich an dieser Stelle nicht weiter erläutern. Wenn das MySQLi Tutorial fertig ist, setz ich an dieser Stelle einen Link dazu.

Hier ist der Code:

<?PHP
  class MySQL extends DataBase{
    private $connection;

    public function Execute($sql){
      return $this->connection->query(str_replace("{'dbprefix'}",$this->Prefix,$sql));
    } 
    
    public function GetTables(){
      $res =  $this->connection->query("SHOW TABLES");
      while($row = $res->fetch_row()){
        $tables[] = $row[0];
      }
      sort($tables);
      return $tables;
    }
      
    public function GetColumns($table){
      $mysqlres = $this->Execute("SHOW COLUMNS FROM ".$table);
      while($row = $mysqlres->fetch_object()){
        $res[] = $row;
      }
      return $res;
    }
      
    public function ReadField($sql){
      $res = $this->Execute($sql);
      $row = $res->fetch_row();
      return $row[0];
    }
      
    public function ReadRow($sql){
      $res = $this->Execute($sql);
      return $res->fetch_object();
    }
      
    public function ReadRows($sql){
      $mysqlRes = $this->Execute($sql);
      while($row = $mysqlRes->fetch_object()){
        $res[] = $row;
      }
      return $res;
    }
    
    public function EscapeString($text){
      return $this->connection->real_escape_string($text);
    }
      
    public function Connect(){
      $this->connection = new mysqli($this->Host,$this->User,$this->Password,$this->Name);
    }
      
    public function Disconnect(){
      $this->connection->close();
    }
  }
?>

Nun kommen wir zum „schlimmen“ Teil für heute: Bitte löscht die Datei /system/dbconnect.php!

Wenn ihr nun eure Startseite besucht, bekommt ihr wahrscheinlich ein paar schöne Fehlermeldungen. Da mein Testsystem online ist habe ich dort den PHP-Code auskommentiert und eine Fehlermeldung erstellt:

<html>
  <head>
    <title>Vorschau nicht verfügbar</title>
  </head>
  <body>
    <h1>Vorschau zur Zeit nicht verfügbar</h1>
    <p>Durch die Derzeitigen Arbeiten an der Datenbank des CMS<br />
       ist die Vorschau zur Zeit nicht verfügbar.</p>
    <p>Keine Angst, dass schafst Du auch ohne!<br />
       Wenn nicht wird dir im <a href='http://www.contentlion.de/beratung/'>Forum</a> geholfen.</p>
  </body>
</html>
<?PHP
/*
  function __autoload($class_name){
      require_once "system/classes/".strtolower($class_name).".php";
  }
  include("system/settings.php");
  include("system/filterfilename.php");
  include("system/sys.php");
  $currentpage = new Page();
  $currentpage->loadProperties(mysql_real_escape_string($_GET['include']));
  if(!$_GET['skin']){
    include(SkinController::getCurrentSkinPath()."/index.php");
  }
  else{
    include('system/skins/'.$_GET['skin']."/index.php");
  }
  */
?>

Mit der Umstellung fangen wir nämllich im Admin-Bereich an. Dort können wir ruhig Fehlermeldungen haben, die Besucher so nicht sehen werden. Mit den ersten Änderungen fangen wir jetzt an, damit auch beim Login nichts zu sehen ist.

Zunächst muss der include für die dbconnect.php entfernt werden. Zum anderen muss die Verbindung zur Datenank aufgebaut werden. Das geht so (/admin/index.php):

<?PHP
  session_start();
  function __autoload($class_name){
      require_once "../system/classes/".strtolower($class_name).".php";
  }
  include("../system/settings.php");
  include("../system/filterfilename.php");
  include("../system/sys.php");
  $db = new MySQL('../system/dbsettings.php');
  $db->Connect();
?>

Weiter gehts mit der Klasse /system/classes/customcss.php. Hier wird die Methode getStylePath umgestellt:

    function getStylePath($id){
      $id = $GLOBALS['db']->EscapeString($id);
      return $GLOBALS['db']->ReadField("SELECT stylePath FROM {'dbprefix'}custom_css
                                        WHERE id = '".$id."'");
    }

Hier seht ihr auch schon die Vorteile der Klasse: Für das Select brauchen wir nur noch eine einzige Zeile!

Da man auch als Nicht-Admin versuchen kann sich einzuloggen müssen wir auch die Klasse /system/classes/user.php bearbeiten:

<?PHP
class User{
  var $name;

  function login($name,$password){
    global $dbpraefix;
    $password = $GLOBALS['db']->EscapeString(trim($password));
    $this->name = $GLOBALS['db']->EscapeString(trim($name));
    if($this->checkPassword($password)){
      return true;
    }
    else{
      return false;
    }
  }

  function checkPassword($password){
    global $dbpraefix;
    $password =$GLOBALS['db']->EscapeString(trim($password));
    $name = $GLOBALS['db']->EscapeString(trim($this->name));
    $count = $GLOBALS['db']->ReadField("SELECT COUNT(*) FROM ".$dbpraefix."user WHERE 
                        name='".$name."' AND password = '".md5($password)."'");
    return $count == 1;
  }
  
  function logout(){
     session_destroy();
  }
}
?>

Das wars auch schon für heute. Wie oben beschrieben werden wir uns als nächstes den Admin-Bereich vorknüpfen. Dieser wird dann auf das neue DB-System umgestellt. Wenn der fertig ist gehen wir systematisch alle Dateien durch und suchen veraltete mysql-Zugriffe. Danach kann dann der Besucher-Bereich wieder online gehen.

Kommentare

Daniel schrieb am 09.03.2010:

Statt fünf Zeilen nur eine. Bringt das System nur Sicherheitsvorteile oder ist das auch in der Ausführung schneller?

Stefan Wienströer schrieb am 09.03.2010:

Tendenziell würde ich vermuten, dass es so langsamer ist. Aus dem einfachen Grund, dass da jetzt noch eine Klasse zwischensitzt, deren funktionen bei jedem Zugriff aufgerufen werden. Ob mysqli nun schneller ist als normales mysql kann ich leider nicht sagen.

Daniel schrieb am 10.03.2010:

Habe dazu was gefunden: http://www.traum-projekt.com/forum/73-workshops-und-tutorials/107262-tutorial-einf-hrung-mysqli-erweiterung.html

Dieter schrieb am 23.09.2010:

Hallo Stefan, ich weiß, bin immer noch Monate hinterher. Wäre aber trotzdem nett, wenn Du noch mal einen Blick auf diesen Beitrag werfen könntest. Bei der Änderung der Tabelle custom_css hast Du die globale $dbpraefix herausgenommen und durch {'dbprefix'}custom_css ersetzt. Bei der Tabelle user arbeitest Du auch nach der Änderung noch mit global $dbpraefix; und in der Ausführung mit ".$dbpraefix."user anstatt mit {'dbprefix'}user. Hat das einen tieferen Sinn der mir irgendwo entgangen ist oder ist es nur ein Versehen? Dieter

Stefan Wienströer schrieb am 24.09.2010:

Das war nur ein versehen. Ist mitlerweile schon geändert worden.

Dieter schrieb am 24.09.2010:

Hallo Stefan, hab's jetzt beim weiterlesen gefunden, habe jetzt aber beim Einloggen das Problem daß ich einen Fatalerror: Trying to clone an uncloneable object of class mysqli in C:wampwwwsystemclassesmysql.php on line 50 Verweist auf: $this-&gt;connection = new mysqli(......); Meine Testumgebung ist ein Windows PC xp pro II mit wamp Server. Ich hab auch schon in den PHP Erweiterungen und in der php.ini nachgeschaut, - alles aktiviert. Noch vorhandene Session_variablen hatte ich auch schon gelöscht. Wenn Du da noch irgend eine Idee hast, würde ich mich sehr freuen. Danke Dieter

Stefan Wienströer schrieb am 24.09.2010:

Ich würd mir das gern mal über TeamViewer o.Ä. ansehen. Hast du irgen nen Instant-Messager, damit ich dich mal anschreiben kann, wenn wir beide online sind?

Dieter schrieb am 25.09.2010:

Bin hin und wieder auf Skype. Meine E-mail müßtest Du ja haben. Schick mir einfach eine Kontaktemail so daß ich Dir meine Skype addresse mailen kann. Dieter

Dieter schrieb am 25.09.2010:

Hallo Stefan, ich habe noch ein bisschen probiert und um irgendwelche Fehler in meinem Code auszuschließen, hab ich mir den Eistiegspunkt "Installer Update" von Dir heruntergeladen und versucht zu installieren. Die installation läuft auch ohne Probleme durch bis auf den automatischen Aufruf der Loginseite. Bei meiner Testkonfiguration wie vorher beschrieben kommt dann nach dem löschen der Cookies der Fatalerror wie ebenfalls bereits beschrieben. Nach dem check mit dem Liveserver, habe ich das ganze da ausprobiert und bekomme nach der Installation, die anscheinend problemlos läuft anstatt der Loginseite nur eine blanke Seite angezeigt. Nach weiterer Überprüfung, hat sich da schon wieder ein Fehler eingeschlichen. Auf dem Liveserver werden die Tabellen und dazugehörigen Daten überhaupt nicht eingetragen. Die dateien "install.php" und /installer/installer.php sowie der Logo file wurden wieder ordnungsgemäß gelöscht. online configuration: Server APACHE 2.2.11(UNIX) MySQL 5.0.32 PHP 5.2.13 Ich hoffe Dir damit erst einmal noch ein bisschen geholfen zu haben. Wie gesagt, wenn ich von Dir eine e-mail Addresse bekomme. schicke ich Dir auch gerne Auszüge aus meinen Konfigurationsdateien etc. Wenn nicht inzwischen schon geschehen, könnte man vielleicht in den Installer noch eine kleine Routine einbauen, die einfach checkt ob wirklich alles installiert wurde bevor die Installationsdateien gelöscht werden. Jetzt aber erst mal noch mal ein großes Dankeschön fürs Helfen. Dieter