Frage bezüglich Vererbung

saebelzahntiger

Grünschnabel
Hallo,
ich versuche mich etwas in die OOP einzuarbeiten, hänge aber bereits am Anfang fest. Ich habe die beiden folgenden Dateien
PHP:
<?php

class DB {
   
   private $dbserver = "localhost";
   private $dbuser = "root";
   private $dbpass = "";
   private $dbname = "testdb";

   public static function connectDB() {
     
     @$db = connect($dbserver, $dbuser, $dbpass, $dbname);
     
     if (mysqli_connect_errno())
     {
       exit();
     }
     
     mysqli_query($db,"SET NAMES utf8");
     mysqli_set_charset($db,"utf8");
     
     return $db;
   }

}
?>
und
PHP:
<?php
require('DB.php');

class Fahrzeug extends DB {

   public function getFahrzeuge() {

     $db = parent::connectDB();
     
     $query = "SELECT * FROM fahrzeuge";
     $erg = mysqli_query($db,$query);
     
     $array = array();
     while ($row = mysqli_fetch_assoc($erg)) {
       $array[] = $row;
     }
     
     return $array;
   }
}
?>
und versuche nun den folgenden Aufruf:

PHP:
<?php

require('Fahrzeug.php');

$fahrzeug = new Fahrzeug();
$fahrzeuge = $fahrzeug->getFahrzeuge();

echo "<pre>",print_r($fahrzeuge,true),"</pre>";

?>
Leider bringt mir der Code keine Ausgabe. Es wird weder ein Fehler noch das gewünschte Ergebnis angezeigt. Wenn ich die DB-Klasse entferne und die DB-Verbindung in die Methode getFahrzeuge integriere funktioniert alles wunderbar. Auch wenn ich die Vererbung weglasse und das require in dei Methode einfüge erscheint kein Ergebnis.

Was mache ich falsch?

Viele Grüße
 
Es gibt mehrere Probleme.

1. nicht static Variablen werden erst gefüllt sobald die Klasse Instanziert ist.
2. die Zeile
PHP:
connect($dbserver,$dbuser,$dbpass,$dbname);
nutzt Variablen die nicht innerhalb der Methode definiert wurden.

Fehlermeldungen werden bei dem Verbindungsaufbau unterdrückt, deshalb kommt auch keine Meldung ala "access denied".

PHP:
<?php

class DB {
  
   private static $dbserver = "localhost";
   private static $dbuser = "root";
   private static $dbpass = "";
   private static $dbname = "testdb";

   public static function connectDB() {
    
     @$db = connect(self::$dbserver, self::$dbuser, self::$dbpass, self::$dbname);
    
     if(mysqli_connect_errno()) {
      echo "Es konnte keine Datenbankverbindung aufgebaut werden!";
       exit();
     }
    
     mysqli_query($db,"SET NAMES utf8");
     mysqli_set_charset($db,"utf8");
    
     return $db;
   }

}
?>
 
Hallo,
vielen dank, du hast mir sehr geholfen. Das problem war die Zeile
PHP:
@$db = mysqli_connect(self::$dbserver, self::$dbuser, self::$dbpass, self::$dbname);
Erstens habe ich das self nicht gehabt und ich habe nicht die falsche Methode zurm Aufbau der datenbankverbindung aufgerufen.
Als letztes habe ich noch eine grundsätzliche Frage. Ich habe es jetzt so gelöst:
PHP:
<?php

class Datenbank {
   
   private static $dbserver = "localhost";
   private static $dbuser = "root";
   private static $dbpass = "";
   private static $dbname = "testdb";

   public static function connectDB() {
     
     @$db = mysqli_connect(self::$dbserver, self::$dbuser, self::$dbpass, self::$dbname);
     
     if (mysqli_connect_errno())
     {
       exit();
     }
     
     mysqli_query($db,"SET NAMES utf8");
     mysqli_set_charset($db,"utf8");
     
     return $db;
   }

}
?>
und
PHP:
<?php
class Fahrzeug {

   public function getFahrzeuge() {

     $query = "SELECT * FROM fahrzeuge";
     $erg = mysqli_query($db,$query);
     
     $array = array();
     while ($row = mysqli_fetch_assoc($erg)) {
       $array[] = $row;
     }
     
     return $array;
   }
}
?>
Die Abfrage dann mit
PHP:
<!DOCTYPE html>
<html>
<head>
<title>Fahrzeuge</title>
<meta charset="utf-8">
</head>
<body>

<?php
require('DB.php');
require('Fahrzeug.php');

$db = Datenbank::connectDB();

$fahrzeug = new Fahrzeug();
$fahrzeuge = $fahrzeug->getFahrzeuge();

echo "<pre>",print_r($fahrzeuge,true),"</pre>";

?>
</body>
</html>

Ist das so ein gutes Vorgehen oder sollte man die Datenbankverbindung von der lesenden Methode trennen? Ich hätte sie nur ungerne in der HTML-Datei.

Viele Grüße
 
Ist aktuell nicht mehr so, aber mach nie so was:

PHP:
class Fahrzeug extends DB { /* ... */ }

Vererbung ist eine „ist ein“-Beziehung. Ein Fahrzeug ist aber keine Datenbank. Nutze bei Bedarf Komposition/Dependency Injection:

PHP:
class Fahrzeug
{
    private $db;

    public function __construct(DB $db)
    {
        $this->db = $db;
    }
}

Es ist übrigens durchaus oft so, dass überhaupt keine Vererbung benötigt wird. „Ich mache OOP, also muss ich Dinge vererben“ ist kein produktiver Ansatz.

Wenn du eine sehr umfangreiche Besprechung von dem, was du da so grob machst, lesen möchtest, kann ich diesen Thread empfehlen:

- http://phpforum.de/forum/showthread.php?t=283107

Der geht aber sehr ins Detail und ist nicht unbedingt Einsteiger-Niveau.

Zu dem Code aus deinem letzten Post:

Die Datenbank-Klasse benötigst du in der Form nicht. Sie hat keinen Mehrwert. Du kannst auch einfach bei einer mysqli-Instanz bleiben.

Ein Fahrzeug mit einer getFahrzeuge-Methode ergibt nicht so ganz viel Sinn, weil Fahrzeug-Instanzen das sind, was eine getFahrzeuge-Methode liefern sollte, also das Ergebnis und nicht der Ausgangspunkt, wenn man so will. Du gehst auch nicht zu einer Tüte Milch, wenn du eine Tüte Milch haben möchtest, sondern du gehst <strike>zu einer Kuh</strike> in einen Laden.

An der Stelle verweise ich wieder auf den eben verlinkten Thread. Die Klasse, die die Fahrzeug-Instanzen liefert, sollte zum Beispiel FahrzeugRepository heißen.
 
Die Datenbank-Klasse benötigst du in der Form nicht. Sie hat keinen Mehrwert. Du kannst auch einfach bei einer mysqli-Instanz bleiben.

Das würde ich nicht unbedingt so unterschreiben.
Wer weiß welche Datenbanken-Funktionen/Klassen aus PHP verbannt werden (aktuelles Beispiel sind ja die mysql_* Funktionen).

Bei Größeren Projekten ist es einfacher das nur innerhalb der Datenbankklasse zu ändern anstelle in allen Skripten.
 
Die Datenbank-Klasse macht aktuell aber nichts, außer eine mysqli-Instanz zu erzeugen und diese zu liefern.

Prinzipiell widerspreche ich dir ansonsten nicht. Wobei das halt dann immer so die Frage ist, wie kompliziert man es machen will. Kannst dir dazu auch mal den von mir verlinkten phpforum.de-Thread ansehen. Da ist ein Beispiel, wie man das konkrete Datenbanksystem/die Persistenzschicht sehr stark über Interfaces und Factories entkoppelt. Das führt nur andererseits auch sehr weit und ist eine Menge Aufwand, der sich nicht wirklich immer lohnt.
 
Zurück