• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

OOP, 2 Klassen

Status
Für weitere Antworten geschlossen.

m0sT

Neues Mitglied
Hi,
bin dabei OOP voll und ganz zu lernen,
nun hab ich mir 2 Klassen geschrieben,
eine Datenbankklasse und eine, die Seiteninformationen heißt und
dazu da ist, die Seiteninformationen zu erfassen (Form.) und
in die Datenbank einzutragen.
Nun grob sieht es so aus:

DB-Klasse
Methode: connect(host,user,password,db)

Seiteninformationenklasse
Methode: setInfos($infos)
$db = new DB;
$db->connect(...)
$db->insert("....");


Aber jetzt ist es ja scheiße, dass ich jedes Mal, wenn ich in einer
Klasse eine SQL-Abfrage gestalte, erst eine Instanz der DB-Klasse bilden muss! Außerdem muss ich ja dann $host, $user usw. angeben, das macht
dann die Dynamik kaputt. Sagt mir einer, wie man es richtig macht?
 
eine instanz von DB entspricht einer datenbank. Du willst dich mit einer datenbank verbinden also erstellst du dir auch nur eine instanz von DB und benutzt diese überall wie eine globale variable. Ich verstehe nicht ganz das problem.
 
Es ist wiedermal eine sache der philosophie aber absolut globale variablen gelten in den meisten kreisen als unsauber. Sauberer wäre es die variable in form einer referenz an funktionen und andere objekte weiterzureichen.
 
naja, also wenn ich $db->insert(seiteninformationen) benutzen will, dann muss eine verbindung bestehen, also hab ich jedes mal ein objekt von DB gebildet.
aber das ist doch scheiße, weil es damit undynamisch wird, dann kann ich mir die methode doch gleich sparen und direkt meine verbindungsdaten eintragen, ich wills mehr oder weniger dynamisch haben, sodass ich EINMAL DB instanziere (heißt das so?) und die connection herstelle, dann sollen meine anderen klassen bzw. deren methoden darauf zugreifen können, aber wie?
 
schreib die klasse in eine datei und speicher sie z.B. unter /config/db.php
In dieser Datei steht dann die Klasse und am Ende der Datei bildest du einfach eine Instanz der Klasse. Mach ich genauso.
Was ich außerdem ganz praktisch finde:
#php/QuakeNet Tutorial - PEAR::DB

EDIT: natürlich musst du die Datei dann noch includen
 
Zuletzt bearbeitet von einem Moderator:
Betrachten wir das ganze mal:

Es gibt:
> DB - Klasse für Datenbank zugriffe
> A - Irgendeine Klasse
> B - Irgendeine Klasse

Ziel:
A unf B sollen zugriff auf die Datenbank über ein objekt von DB erhalten. (Ich hoffe das ist was du willst)

Lösung:
Du instanzierst ein Objekt der Klass DB. Nun gibt es zwei möglichkeiten A und B zugriff auf dieses Objekt zu verleihen.
1. Du machst die Instanz von DB global (gilt als unsauber).
2. Du übergibst A und B eine Referenz auf die Instanz von Db damit diese sie intern verwenden können.

Variante 2 würde so aussehen:
PHP:
class DB
{
  private $host;
  private $name;
  private $passwort;

  private $verbindung; // Resource der hergestellten verbindung.

  public function __construct($host, $name, $passwort) // Constructor
  {
    // Anmelden
  }
}

class A
{
  private $db_con; // Datenbank verbindung

  public function __construct(&$db_con) // Constructor
  {
    $this->db_con =& $db_con;
  }
}

class B
{
  private $db_con; // Datenbank verbindung

  public function __construct(&$db_con) // Constructor
  {
    $this->db_con =& $db_con;
  }
}

Nun kann in A und B über ihre interne referenz db_con auf die datenbank zugegriffen werden.
 
es is immo so:

methode select in klasse DB:
...
PHP:
$result = mysql_query($sql, $this->connection_handle);
...

methode getSeiteninformationen in klasse Seiteninformation:
...
PHP:
$result = DB::select_one("SELECT ".$info." FROM _seiteninformationen;",$status);
return $result;
...

keine Klasse, normaler code halt:

PHP:
$db = new DB;
$db->connect("localhost","root","","***");

$site = new Seiteninformationen;
// echo $site->setSeiteninformationen("title,newsticker,footer",1);
echo $site->getSeiteninformationen("title",1);
logischer fehler:

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in C:\Dokumente und Einstellungen\Root\Eigene Dateien\XAMPP\xampplite\htdocs\root\phit_cms\install.php on line 296
 
PHP:
$result = DB::select_one("SELECT ".$info." FROM _seiteninformationen;",$status);
return $result;
Du versuchst hier auf die Klasse DB und nicht deine instanz $db zuzugreifen. Das dort oben wird nur gehen wenn select_one eine statische methode von DB ist. Um das dort oben machen zu können musst du einen meiner lösungsansätzte verwenden und folgendes schreiben:
PHP:
$result = $this->db_con->select_one("SELECT ".$info." FROM _seiteninformationen;",$status);
return $result;
Wobei db_con natürlich durch den namen der Referenz welche auf die instanz von DB zeigt, ersetzt werden muss.

Oder wenn du $db global gemacht hast:
PHP:
$result = $db->select_one("SELECT ".$info." FROM _seiteninformationen;",$status);
return $result;
 
Es ginge auch noch anderes ^^ du könntest einfach die mysql als elternklasse machen und die anderen klassen als kindklassen mit extends dbklasse aufrufen lassen und dann bei __construct() parent::connect("BLABLA"); machen und dann kannste
parent::query("SELECT..."); nutzen hoffe haste verstanden ^^ hab gerade keine Zeit für ein Bsp ^^
 
Welchen sinn hätte es die funktionalität von Db zu vererben? Die beiden kind-klassen haben doch keinerlei logischen bezug zu dieser klasse. Das hätte keinen nutzten.
 
Wie wäre es denn die Instanz der Datenbankklasse als static zu deklarieren? Das funktioniert super und erstellt nur eine einzige Instanz.

Hier mal eine grobe Sturktur:

PHP:
class DB {
     static private $instance = null;

     private function __construct() {
          /*
Hier müssen dann die Verbindungsdaten geholt werden (z.Bsp. aus einer Konfigurationsdate).
Ausserdem muss hier die Verbindung zur Datenbank hergestellt werden.
Die DB -Klasse sollte also Funktionen zur Verbindungsherstellung erhalten.
          */
     }

     public function getInstance() {
          if (self :: $instance == null) {
               self :: $instance = new DB();
          }
          return self :: $instance;
     }
}

Und die Instance erhält man dann durch den Aufruf der Methode getInstance()

PHP:
$my_db = DB :: getInstance();
 
es geht mir ja darum, dass es auch funktioniert wenn es jetzt heißt
$wurst = new DB;

wenn ich schreibe $this->db->...

ist es wieder so unflexibel.. ich versteh nicht, warum es nicht geht..
diese verbindung ist doch hergestellt zu dem zeitpunkt wo die methode von seiteninfo aufgerufen wird..
 
Das macht so wie du es gepostet hast auch keinen sinn. Wenn dann musst du alle Member (Eigenschaften und Methoden) als static deklarieren damit die gesamte klasse statisch ist. Dann ist das eine gute dritte möglichkeit. Allerdings würde das nur ein gute lösung darstellen wenn du auch wirklich immer nur auf eine datenbank zugreifst.

EDIT: Dein problem ist aber das das instanzierte objekt nicht innerhalb der anderen klassen bekannt ist. Warum ist das unflexibel? Wenn du nun eine solche klasse hier definierst:

PHP:
class db_verwender
{
  private $db_con;
  
  public function setDBConnection(DB &$db)
  {
    $this->db_con =& $db; 
  }
  public function &getDBConnection()
  {
    return $this->db_con;
  }
}

Dann ist das doch sehr flexibel...

Oder verstehe ich dich falsch? Was empfindest du den als unflexibeL?
 
Zuletzt bearbeitet:
es ist irgendwie schwierig zu erklären,
wenn ich in der methode getSeiteninfo...
schreibe:
DB::select_one..

dachte ich ginge es, wenn zu dem zeitpunkt wo die methode im programm aufgerufen wird eine verbindung besteht..

also so:

1. db instanzieren
2. connect
3. abfrage (geht nur, wenn verbindung besteht)
 
Das geht nicht weil in der methode getSeiteninfo die instanz von DB nicht bekannt ist! Du musst sie dort irgendwie bekanntmachen. Und genau dazu posten wir hier schon die ganze zeit lösungen!
 
okay, aber keine davon, jedenfalls denke ich das, macht genau das, was ich meine, nämlich:

wenn ich in der methode die verbindung herstelle, heißt das ja, dass die daten bekannt sein müssten, wenn ich dann bei andern datenbank-infos meine klasse verwenden will, dann geht es ja nicht mehr ..

sollte ich es so machen?:

PUBLIC $host
" $user
" $password
" $db



methode:

$db = new DB;
$db->connect($db->host,$db->user,....);

EDIT: ne, das geht ja auch nicht, weil zu dem zeitpunkt das alles nicht bekannt ist..
 
Ich glaube du verfolgst den falschen ansatz. Wenn deine Datenbankverbindung für viele klassen zugänglich sein soll, dann solltest du die verbindung in der klasse aufbauen und dort sichern. Das Objekt (instanz der DB Klasse) welche die verbindung enthält kannst du doch nun ganz einfach an andere klassen weitergeben. So nutzten alle klassen die einmal von dir aufgebaute verbindung und du must sie nicht immer wieder neu aufbauen! Wie du das Objekt deiner DB klasse in allen anderen klassen nutzt haben wir bereits beschrieben.
 
Das konzept von dir ist allerdings etwas unflexibel, da man immer die Instanz weiterreichen muss. Mich würde das beim schreiben tierisch nerven.

Vie gesagt, mit einer statischen instanz gehts ganz einfach.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben