oop Grunsatzprobleme

luchs3

Erfahrenes Mitglied
Hi,
Ich versuch mich gerade in OOP und scheitere bereits am Anfang.
Ich wollte die Klasse sport erstellen.
Die Funktion show soll mir eine Datenbankabfrage machen. Ein Objekt in einer Klasse öffnen sozusagen.
Aber das scheint ihm nicht zu gefallen.
Hat ihr eine Idee?
Kann ich überhaupt ein Objekt (z.B.: PDO) in einer Klasse öffnen und arbeiten lassen?

PHP:
class sport {

    public function show() {
        $user = 'user';
        $pass = 'pw';
        
        // Datenbank Verbindung
        try {
            $dbh = new PDO('mysql:host=localhost; dbname', $user, $pass);
            $dbh2 = new PDO('mysql:host=localhost; dbname', $user, $pass);
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
        
        $stmt = $dbh->prepare('SELECT * FROM sportkat ORDER BY spkat_name ASC');
        $stmt->fetch();

        $stmt2 = $dbh2->prepare('SELECT sp_name FROM sports WHERE sp_kat = :kat ORDER BY sp_name ASC');
        $stmt->execute();    
        foreach ($stmt as $row) {
            echo '<div><div style="width:150px; border-bottom:solid 1px; text-align:center;"><b>'.$row[1].'</b></div>
            <span>';
            $stmt2->bindParam(':kat', $row[0]);
            $stmt2->execute();
            foreach ($stmt2 as $row2) {
                print_r($row2[0]); echo '<br></span>';
            }
        echo '</div><br>';
        }
        unset($dhb);
        unset($dbh2);
    }
}
Danke im vorraus
Niko
 
Wie sieht denn die Fehlermeldung aus?

Zu deinem Code:
Also ich würde die Datenbankklasse außerhalb der "sport"-Klasse instanzieren und ihr diese dann im Konstruktor übergeben.
Zudem solltest du in deiner Klasse die Exceptions nur werfen und nicht gleich abfangen.
So z.B.:
PHP:
try {

    $db = new DBClass();
    $sport = new sport($db);

} catch(Exception $ex) {

    echo $ex->getMessage();

}
// ...
class sport {

    private $_db = null;

    public function __construct($db) {
        
        if(!is_object($db) {
            
            throw new Exception('Invalid argument');

        }

        $this->_db = $db;

    }

    // ...

}
(Nur als Beispiel)
 
Naja ich würde gerne die Ganze Aufgabe in einer Klasse unterbringen.

Wie gesagt ich stehe noch ziemlich am Anfang der oop Denkweise aber ich hab versucht die db klasse dem Konstruktor zu überlassen aber dann hat er in der show() Funktion irgendwie nicht mehr darauf zugreifen können.

Die Fehlermeldung nach dem oberen Beispiel:
Fatal error: Call to a member function fetch() on a non-object in /var/www/... on line 56
Wenn ich die DB Klasse in den Konstruktor schreibe...
PHP:
class sport {
    public function sport() {
        $user = 'user';
        $pass = 'pw ';
        
        // Datenbank Verbindung
        try {
            $dbh = new PDO('mysql:host=localhost; dbname', $user, $pass);
            $dbh2 = new PDO('mysql:host=localhost; dbname', $user, $pass);
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
    public function show() {        
        $stmt = $dbh->prepare('SELECT * FROM sportkat ORDER BY spkat_name ASC');
        $stmt->fetch();

        $stmt2 = $dbh2->prepare('SELECT sp_name FROM sports WHERE sp_kat = :kat ORDER BY sp_name ASC');
        $stmt->execute();    
        foreach ($stmt as $row) {
            echo '<div><div style="width:150px; border-bottom:solid 1px; text-align:center;"><b>'.$row[1].'</b></div>
            <span>';
            $stmt2->bindParam(':kat', $row[0]);
            $stmt2->execute();
            foreach ($stmt2 as $row2) {
                print_r($row2[0]); echo '<br></span>';
            }
        echo '</div><br>';
        }
        unset($dhb);
        unset($dbh2);
    }
}
...gibt er mir den Error schon bei Prepare:
Fatal error: Call to a member function prepare() on a non-object in /var/www/... on line 53

Das mit den Exceptions ist eine gute Idee, bisher hab ich halt mehr mit copy & paste aus Foren u. Tutorials gearbeitet und meinen Senf adaptiert.
 
Zuletzt bearbeitet:
legst Du das Objekt den korrekt an?
Hast Du irgendwo
PHP:
...
$sport= new sport();
...
stehen?
Ausserdem solltest du die Datenbankverbindung als Klassenvariable deklarieren damit die anderen Methoden darauf zugreifen könnnen!

PHP:
class sport {
    $dbh;
    $dbh2;
    public function sport() {
        $user = 'user';
        $pass = 'pw ';
        
        // Datenbank Verbindung
        try {
            $dbh = new PDO('mysql:host=localhost; dbname', $user, $pass);
            $dbh2 = new PDO('mysql:host=localhost; dbname', $user, $pass);
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
    public function show() {        
        $stmt = $dbh->prepare('SELECT * FROM sportkat ORDER BY spkat_name ASC');
        $stmt->fetch();

        $stmt2 = $dbh2->prepare('SELECT sp_name FROM sports WHERE sp_kat = :kat ORDER BY sp_name ASC');
        $stmt->execute();    
        foreach ($stmt as $row) {
            echo '<div><div style="width:150px; border-bottom:solid 1px; text-align:center;"><b>'.$row[1].'</b></div>
            <span>';
            $stmt2->bindParam(':kat', $row[0]);
            $stmt2->execute();
            foreach ($stmt2 as $row2) {
                print_r($row2[0]); echo '<br></span>';
            }
        echo '</div><br>';
        }
        unset($dhb);
        unset($dbh2);
    }
}

Das fangen von Ausnahmen in dieser Klasse ist legitim, da man hier eine alternative Verbindung benutzen könnte oder alternativ eine ander Datenbank-Klasse.
 
Ich hab jetzt noch eine Kontrolle eingebaut (if ($dbh)...) und anscheinend kann ich in der Methode show nicht auf das $dbh Objekt zugreifen, da connected nicht ausgegeben wird.
Die Klasse hab ich natürlich aufgerufen.

PHP:
class sport {
    public function sport() {
        $user = 'user';
        $pass = 'pw ';
        
        // Datenbank Verbindung
        try {
            $dbh = new PDO('mysql:host=localhost; dbname', $user, $pass);
            $dbh2 = new PDO('mysql:host=localhost; dbname', $user, $pass);
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
    public function show() {
        if ($dbh) {
            echo 'connected';
        }
        $stmt = $dbh->prepare('SELECT * FROM sportkat ORDER BY spkat_name ASC');
        $stmt->fetch();

        $stmt2 = $dbh2->prepare('SELECT sp_name FROM sports WHERE sp_kat = :kat ORDER BY sp_name ASC');
        $stmt->execute();    
        foreach ($stmt as $row) {
            echo '<div><div style="width:150px; border-bottom:solid 1px; text-align:center;"><b>'.$row[1].'</b></div>
            <span>';
            $stmt2->bindParam(':kat', $row[0]);
            $stmt2->execute();
            foreach ($stmt2 as $row2) {
                print_r($row2[0]); echo '<br></span>';
            }
        echo '</div><br>';
        }
        unset($dhb);
        unset($dbh2);
    }
}
 
NomadSoul hat dir doch schon einen Hinweis gegeben... Du musst die Instanz der PDO Klasse einer Klassenvariable zuweisen, damit alle Methoden von sport darauf zugreifen können.
PHP:
<?php>
class sport {
		private $dbh = array();	
		
    public function sport($user, $pass) {        
        // Datenbank Verbindung
        try {
            $this->dbh[1] = new PDO('mysql:host=localhost; dbname', $user, $pass);
            $this->dbh[2] = new PDO('mysql:host=localhost; dbname', $user, $pass);
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
    public function show() {
        if (isset($this->dbh[1], $this->dbh[2])) {
            echo 'connected';
        }
        $stmt = $this->dbh[1]->prepare('SELECT * FROM sportkat ORDER BY spkat_name ASC');
        $stmt->fetch();

        $stmt2 = $this->dbh[2]->prepare('SELECT sp_name FROM sports WHERE sp_kat = :kat ORDER BY sp_name ASC');
        $stmt->execute();    
        foreach ($stmt as $row) {
            echo '<div><div style="width:150px; border-bottom:solid 1px; text-align:center;"><b>'.$row[1].'</b></div>
            <span>';
            $stmt2->bindParam(':kat', $row[0]);
            $stmt2->execute();
            foreach ($stmt2 as $row2) {
                print_r($row2[0]); echo '<br></span>';
            }
        echo '</div><br>';
        }
        unset($this->dbh);
    }
}  
?>
 
Zuletzt bearbeitet:
Okay ich versuchs nochmal.
Ein Objekt besteht aus Methoden, und Attributen einige davon öffentlich einige davon privat. (vereinfacht gesagt).

Innerhalb von Objekten, gibt es gewissen Sichtbarkeitsbereiche.(gilt auch für andere Programmierkonstrukte)

Beginnen wir mit der Sichtbarkeit über die ganze Klasse
PHP:
class Beispiel {
              //<zugriffsspezifizierer> <Attributname>;
              private Beispielattribut; //ich bin innerhalb der ganzen Klasse sichtbar (in allen Methoden allerdings nicht nach aussenhin weil private
              //<zugriffsspezifizierer><Methodenname>(<parameter1>,...,<parametern>){...}
             public show($parameter){ //Ich bin überall sichtbar auch ausserhlab der Klasse weil public
                      $lokal; // ich bin nur eine lokale Variable und nur innerhalb der Methode show sichtbar
             }
        
}
Hoffe das bringt Licht ins dunkle.
 
  • Gefällt mir
Reaktionen: mAu
Hab ich verstanden und auch so gemacht aber er gibt mir
Fatal error: Cannot access empty property in ...
aus.
Und zwar bei der Zeile in der Ich in der show function die $dbh überprüfe
PHP:
class sport {
    private $dbh = array();
    
    public function user() {
        $user = 'user';
        $pass = 'pw ';
        
        // Datenbank Verbindung
        try {
            $dbh[1] = new PDO('mysql:host=localhost; dbname', $user, $pass);
            $dbh[2] = new PDO('mysql:host=localhost; dbname', $user, $pass);
            echo 'connected';
        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
    public function show() {
        if ($this->$dbh[1]) {
            echo 'connected2';
        }

        $stmt = $this->$dbh[1]->prepare('SELECT * FROM sportkat ORDER BY spkat_name ASC');
        $stmt->fetch();

        $stmt2 = $this->$dbh[2]->prepare('SELECT sp_name FROM sports WHERE sp_kat = :kat ORDER BY sp_name ASC');
        $stmt->execute();    
        foreach ($stmt as $row) {
            echo '<div><div style="width:150px; border-bottom:solid 1px; text-align:center;"><b>'.$row[1].'</b></div>
            <span>';
            $stmt2->bindParam(':kat', $row[0]);
            $stmt2->execute();
            foreach ($stmt2 as $row2) {
                print_r($row2[0]); echo '<br></span>';
            }
        echo '</div><br>';
        }
        unset($this->$dhb);
    }
}
 
Probiers mal mit [phpf]isset[/phpf] in der if-Abfrage. Hab meinen Quelltext oben entsprechend geändert.
 
macht keinen Unterschied irgendwie scheint $dbh nicht in die show funktion überzugehen

bin weiter, hab deinen Code nicht richtig gelesen
 
Zuletzt bearbeitet:
Zurück