Du bist nicht angemeldet.

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

1

07.10.2011, 18:47

6. DBManager

Heute wollen wir uns mal mit dem Datenbank-Manager beschäftigen.
Man soll nämlich verschiedene Datenbanken nutzen können. :D

Welche Datenbank genutzt wird, steht in der "config.ini" - Datei, die im Hauptverzeichnis bzw. im Hauptordner des CMSes liegt.
Auch der Host, benutzername, ... sind in dieser Datei gespeichert.

Deßwegen legen wir diese Datei auch gleich mal an :D .

config.ini:

Quellcode

1
2
3
4
5
6
7
[DBManager]
DatabaseDriver=MySqlDatabase
[Database]
host=localhost
user=root
password=Passwort
database=CMS


Nun erstellen wir die Datei "DBManager.php" die in das Verzeichnis "CMS/classes" kommt.

DBManager.php:

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php

class DBManager {

private $is_init false;
private $db_;

public function DBManager () {

        if (file_exists("config.ini")) {
                $config parse_ini_file("config.ini"TRUE);
                $this->is_init true;
        } else {
                $config "";
                throw new Exception("Die config.ini konnte nicht gefunden werden."); // dann Exception werfen
        }

    if ($this->isInit()) {

            require("CMS/databases/" $config['DBManager']['DatabaseDriver'] . ".php");

            $klasse   $config['DBManager']['DatabaseDriver'];
               $this->db_ = new $klasse('.');
               return $this->db_;
        } else {
            $this->db_ false;
        }

}

        public function isInit () {
                return $this->is_init;
        }

        public function getDBDriver () {

                if (isset($this->db_) && !empty($this->db_)) {
                        return $this->db_;
                } else {
                        throw new Exception("db doesn't exists."); // dann Exception werfen
                }

        }

}

?>


Wenn eine Instanz / ein Objekt dieser Klasse erzeugt wird, wird der sog. Konstruktor aufgerufen.
Diese Methode heißt immer genau so, wie die Klasse.
In diesem Fall heißt die Methode DBManager().
Diese Methode liest erst einmal den Datenbank-Treiber aus der "config.ini" und erzeugt dann ein neues Objekt dieser Klasse.

Die Methode getDBDriver() gibt das Objekt des datenbank-Treibers zurück.
Mittels isInit() kann man feststellen, ob die Klasse / der datenbank-Treiber initalisiert wurde.

Nun zur "db.php", die ihr jetzt zu "database.php" umbennent.
Sie sieht jetzt so aus:

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

abstract class Database {

protected $host "localhost";//Host
protected $user "root";//Benutzername
protected $password "Passwort";
protected $database "CMS";
public $db_link;

    public abstract function connect();
    public abstract function query($sql);
    public abstract function escape($string);
    public abstract function fetch_array($db_erg);

    public function loadConfig () {
    if (file_exists("config.ini")) {
        $config parse_ini_file("config.ini"TRUE);
    } else {
    $config "";
    throw new Exception("Es konnte keine Verbindung zur MYSQL-datenbank hergestellt werden."); // dann Exception werfen
    }

    $this->host $config['Database']['host'];
    $this->benutzer $config['Database']['user'];
    $this->password $config['Database']['password'];
    $this->database $config['Database']['database'];
}

}

?>


Wie ihr seht, haben sich die Methoden geändert und es kam auch eine neue hinzu: loadConfig().
Diese Methode liest den Datenbank-User, das Datenbank-Passwort, ... aus.

Auch die Datei "MySqlDatabase.php" im Ordner "CMS/databases" hat sich geändert.
Sie sieht jetzt so aus:

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php

class MySqlDatabase extends Database {

public function connect () {

    $this->loadConfig();
    $this->db_link mysql_connect($this->host$this->user$this->password) or die("Anfrage fehlgeschlagen.");

    mysql_select_db($this->database) or die("Die datenbank konnte nicht ausgew&auml;hlt werden.");

}

public function escape ($string) {
    return mysql_real_escape_string($string);
}

public function query ($sql) {

    $db_erg mysql_query($sql);

    if($db_erg) {
        return $db_erg;
    } else {
        return false;
    }

}

public function fetch_array($db_erg_) {
    if (!isset($db_erg_) or empty($db_erg_)) {
        return false;
    } else {
        return mysql_fetch_array($db_erg_MYSQL_ASSOC);
    }
}

}

?>


Wie ihr seht, ruft die methode connect() jetzt auch die Methode loadConfig() auf, die wir vorhins in der "database.php" hinzugefügt haben.

Kommen wir nun zur "settings.php".
Diese sieht jetzt so aus:

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php

class Settings {

    public static function getSetting($property) {

        global $db;

        $sql "SELECT `value` FROM `cms_settings` WHERE `property` = '" $db->escape($property) . "'; ";
        $db_erg $db->query($sql) or die("Anfrage fehlgeschlagen.");

        $zeile $db->fetch_array($db_erg);

        if (isset($zeile['value'])) {
            return $zeile['value'];
        } else {
            return false;
        }

    }

    public static function setSetting($property$value) {

        global $db;

        $property $db->escape($property);
        $value $db->escape($value);
        $sql "UPDATE `cms_settings` SET `value` = '" $value "' WHERE `property` = '" mysql_real_escape_string(trim($property)) . "'; ";
        $db_erg $db->query($sql) or die("Anfrage fehlgeschlagen.");

    }

}

?>


Und zu letzt in diesem beitrag aktualisieren wir noch die "index.php" im Hauptverzeichnis /im Hauptordner.

index.php:

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

error_reporting(E_ALL);

require("CMS/classes/database.php");//Hinweis: Ihr könnt die Klammern auch weglassen, nähere Infos gibt es bei Simon^^ (http://www.developertalk.de/user/2-simon/)
//require("CMS/databases/MySqlDatabase.php");
require("CMS/classes/settings.php");
require("CMS/classes/DBManager.php");

$DBManager = new DBManager();

if (!$DBManager->isInit() || !$DBManager->getDBDriver()) {
    echo "Ein Fehler ist aufgetreten.";
    exit;
}

$db $DBManager->getDBDriver();
$db->connect();

echo Settings::getSetting("selectedskin");//Zum testen, danach bitte diese zeile entfernen

?>


Wenn ihr alles richtig gemacht habt, müsste jetzt "default" auf dem Bildschrim angezeigt werden.
Im Dateianhang habt ihr wieder den aktuellen Stand.
»JuKu« hat folgende Datei angehängt:
  • Stand_6.zip (3,83 kB - 193 mal heruntergeladen - zuletzt: 09.12.2018, 10:28)
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »JuKu« (07.10.2011, 19:50)


Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

2

07.10.2011, 19:37

Database.php muss groß geschrieben werden :)

Btw, hast du vor, auch prepared Statements bereitzustellen?
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

JuKu (07.10.2011)

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

3

07.10.2011, 19:43

Komisch, kannst du Gedanken lesen? :thumbsup:
Ich bin heute auf das PDO gestoßen und habe mir überlegt, das so etwas eig. auch gut einzubauen wäre.
Allerdings hat mich die Installation etwas verwirrt.
Wozu muss man das installieren? ?(
Ist das nicht in PHP inbegriffen?
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

4

07.10.2011, 19:45

Keine Ahnung... Ich weiß zwar, was PDO ist, aber ich habs noch nicht benutzt...
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

Simon

Profi

Beiträge: 725

Registrierungsdatum: 14.06.2011

Danksagungen: 210

  • Private Nachricht senden

5

07.10.2011, 19:46

Wie ihr seht, haben sich die Methoden geändert und es kam auch eine neue hinzu: loadConfig().

Wieso hast du nicht meinen Ratschlag angenommen und eine Trennung vorgenommen?
Eine Datenbankklasse hat doch nichts mit der Beschaffung der Daten zu tun, diese werden ihr übergeben ?(
Heute wollen wir uns mal mit dem Datenbank-Manager beschäftigen.
public function escape ($string) {
return mysql_real_escape_string(trim($string));
}

Und wofür der trim?
Hier wird ein escape gefordert und kein trim + escape?
Sollte man 5 Leerzeichen am Anfang haben wollen, so dürfen die ja nicht einfach durch das escapen verschwinden, oder? :D

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

JuKu (07.10.2011)

Johannes S.

Fortgeschrittener

Beiträge: 444

Registrierungsdatum: 24.06.2011

Wohnort: Lychen

Danksagungen: 71

  • Private Nachricht senden

6

07.10.2011, 19:50

Naja... ich lese mir das später nochmal alles durch :D (Muss jetzt Essen)
aber eins ist mir schonmal aufgefallen. Es ist möglisch mehrere Exceptions zu erstellen.
Also ich würde dir empfehlen eine Klasse FileNotFoundException und DBNotFoundException zu erstellen, welche von Exception erbene. Das gibt dir später mehr möglichkeiten beim Abfangen von diesen. Natürlich solltest du dann auch diese werfen, und nicht die "Standartexception".
Signatur ?

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

JuKu (07.10.2011)

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

7

07.10.2011, 19:54

Wie ihr seht, haben sich die Methoden geändert und es kam auch eine neue hinzu: loadConfig().

Wieso hast du nicht meinen Ratschlag angenommen und eine Trennung vorgenommen?
Eine Datenbankklasse hat doch nichts mit der Beschaffung der Daten zu tun, diese werden ihr übergeben ?(
Ja, aber so ist es einfach leichter. Man müsste sonst 4 Variablen übergeben.
Die Daten werden in der Klasse Database beschaffen, von der die Klasse MySqlDatabase erbt.
Meiner Meinung nach, ist das gar nicht so schlecht.
Aber ist eine Überlegung wert, für die "Wiederverwertbarkeit"^^.
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

tom

Schüler

Beiträge: 54

Registrierungsdatum: 20.06.2011

Danksagungen: 18

  • Private Nachricht senden

8

07.10.2011, 20:00

Wie wärs mit sowas? Die $config kannste dann in $GLOBALS o.ä packen.

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$config = array(
    'host'     => 'localhost',
    'user'     => 'root',
    'password' => '',
    'database' => 'project_xyz',
    'driver'   => Database::DRIVER_MYSQL
);

$database = new Database($config);
$database->connect();
?>

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

JuKu (07.10.2011)

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

9

07.10.2011, 20:02

Wie wärs mit sowas? Die $config kannste dann in $GLOBALS o.ä packen.

PHP-Quelltext

1
2
3
4
5
6
7
8
9
10
11
$config = array(
    'host'     => 'localhost',
    'user'     => 'root',
    'password' => '',
    'database' => 'project_xyz',
    'driver'   => Database::DRIVER_MYSQL
);

$database = new Database($config);
$database->connect();
?>

Keine schlechte Idee.
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

tom (07.10.2011)

Johannes S.

Fortgeschrittener

Beiträge: 444

Registrierungsdatum: 24.06.2011

Wohnort: Lychen

Danksagungen: 71

  • Private Nachricht senden

10

07.10.2011, 20:27

Mir ist noch was aufgefallen :D

PHP-Quelltext

1
2
3
4
5
6
7
if (file_exists("config.ini")) {
                $config parse_ini_file("config.ini"TRUE);
                $this->is_init true;
} else {
                $config "";
                throw new Exception("Die config.ini konnte nicht gefunden werden."); // dann Exception werfen
}


an dieser Stelle finde ich die Variable is_init unnötig. Sie kann auch aus dem Header der Klasse entfernt werden, genau wie die Methode, welche den Inhalt dieser zurück gibt. Schließlich wirfst du eine Exception, wenn die Datenbank nicht initialisiert werden kann, was bedeutet, das das Programmcode hier sowiso abgebrochen wird. Und wenn das Programm dann nicht abgebrochen werden soll und du meinen Tipp befolgst und die Exception FileNotFoundException nennst, kannst du mit einem try-catch(FileNotFoundException)-Block diese Exception abfangen, aber auch dann wirst du ja durch diese über den Fehler informiert.
Signatur ?

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

JuKu (07.10.2011)

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

11

07.10.2011, 20:47

Das Problem wenn die Datei nicht gefunden wird ist aber nicht, dass eine Datei nciht gefunden wurde, sondern, dass die Inizialisierung fehlschlägt. Die FileNotFoundException müsste eigentlich innerhalb des Konstruktors behandelt werden...
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

Johannes S.

Fortgeschrittener

Beiträge: 444

Registrierungsdatum: 24.06.2011

Wohnort: Lychen

Danksagungen: 71

  • Private Nachricht senden

12

07.10.2011, 20:52

wiso? Das Problem ist die Datei, die Initialisierung schlägt ja fehl, weil die Datei fehlt ;)
Und das schöne an Exceptions ist, das man das auch genau so ansgeben lassen kann. Bei diesen steht nähmlich auch wo die initialisierung war, und auch von welcher Datei die initialsierung ausgefürhrt wurde und so weiter. Die Exceptions sollen ja auch dem Anwender helfen das Problem zu lösen, und wenn du hinter jeder Funktion eine neue Exceptions werfen lässt hilft das weder dem späteren Anwender, noch dir als entwickler, wenn dein Programm aus irgend einem Grund mal nicht geht.
Signatur ?

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

13

07.10.2011, 22:11

Joa okay ist doch nicht so schlecht...
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

Johannes S.

Fortgeschrittener

Beiträge: 444

Registrierungsdatum: 24.06.2011

Wohnort: Lychen

Danksagungen: 71

  • Private Nachricht senden

14

07.10.2011, 23:03

Wobei ich gerade nochmal gegoogelt habem weil PHP hier eine komische Sache macht. Bei Java würde das z.B. gehen, aber PHP spackt da ein bissen. Wenn in PHP eine Exception im Konstruktor geworfen wird, kann sich außen nicht abgefangen werden, sondern wenn schon, nur in dem Konstruktor. Wenn eine Exception in einem Konstruktor nicht abgefangen wird, wird nur der Konstruktor abgebrochen und das Objekt wieder Zerstört. Kein Plan was das soll, aber so ist es. Also man kann es bei der Exception lasse, und dann allerdings nach der Initialisierung müsste man Fragen "if($DBManager)".
Signatur ?

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

15

07.10.2011, 23:43

Ja oder man kricht beim nächsten Befehl n NullPointer und das Script schmiert ab :D
oder?
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

Johannes S.

Fortgeschrittener

Beiträge: 444

Registrierungsdatum: 24.06.2011

Wohnort: Lychen

Danksagungen: 71

  • Private Nachricht senden

16

08.10.2011, 00:30

Ich glaube bei PHP bekommt man kein NullPointer, sondern die Meldung, das eine Methode auf ein "Nicht-Objekt" angewendet wurde und das nicht geht XD
Aber kommt ja aufs selbe raus XD
Signatur ?

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

17

08.10.2011, 00:33

Achja stimmt :D Naja der Effekt ist der selbe...
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

18

08.10.2011, 11:59

Ich glaube bei PHP bekommt man kein NullPointer, sondern die Meldung, das eine Methode auf ein "Nicht-Objekt" angewendet wurde und das nicht geht XD
Aber kommt ja aufs selbe raus XD
Da hast du eig. Recht, aber schau dir mal die Methode "getDBDriver()" an.
Diese übrprüft das schon. :D
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Johannes S. (08.10.2011)

Verwendete Tags

CMS, DBManager, MYSQL, PHP, Programmieren