Scream: [PHP] Hilfe bei Prepared Statements und Singleton

Ich bekomme immer einen Fehler und weiß nicht an was das liegen könnte.
Habe schon über 3 stunden herumgetestet bin aber auf nichts gekommen.

Hier meine config.php
[PHP]<?php
class Connection {

// Speichert die Instanz der Klasse
    private static $instance = null;

// Ein private Konstruktor; verhindert die direkte Erzeugung des Objektes
    private function __construct()
 {
  $dbname = "mysql:dbname=cdcol;host=localhost";
  $user = "root";
  $password = "";

try
  {
   $this->instance = new PDO($dbname, $user, $password);
  }

catch (PDOException $e)
  {
   echo 'Fehler beim Öffnen der Datenbank: ' . $e->getMessage();
  }

}

// Die Singleton Funktion
    public static function getInstance()
    {
        if (self::$instance == null) {
            self::$instance = new Connection();
        }

return self::$instance;
    }

// Halte Benutzer vom Klonen der Instanz ab
    public function __clone()
    {
        trigger_error('Klonen ist nicht erlaubt.', E_USER_ERROR);
    }

}[/PHP]

Hier meine funktion.php:
[PHP]<?php
require("config/config.php");

class DB {

public $instance;

public function __construct()
 {
  $this->instance = Connection::getInstance();
 }

public function holeBenutzerId($benutzername)
{
    $sql = "SELECT benutzerid FROM benutzer WHERE benutzername = :benutzername";
 $stmt = $this->instance->quote->prepare($sql);
 $stmt->bindParam( ':benutzername', $benutzername);
 $result = $stmt->execute();
 echo var_dump($result);
 if(!$result) {echo "FEHLER BEI ABFRAGE (benutzerid)<br";}
 else {}

$data = $stmt->fetch(PDO::FETCH_OBJ);

return $data->benutzerid;
}

}
?>[/PHP]

[QUOTE]Fatal error: Call to a member function prepare() on a non-object in C:\xampplite\htdocs\test\funktionen.php on line 18[/QUOTE]

Eigentlich müsste doch alles passen!?

  1. echo $begrüßung;

    Ich bekomme immer einen Fehler und weiß nicht an was das liegen könnte.
    Habe schon über 3 stunden herumgetestet bin aber auf nichts gekommen.

    Schön, aber völlig uninteressant.

    Fatal error: Call to a member function prepare() on a non-object in C:\xampplite\htdocs\test\funktionen.php on line 18
    Eigentlich müsste doch alles passen!?

    Schalte beim Entwickeln das error_reporting auf E_ALL (und display_errors auf on), damit du alle Meldungen zu Gesicht bekommst, mit denen PHP dich auf mögliche Probleme hinweisen will. Da du mit OOP hantierst, ist auch noch E_STRICT empfehlenswert (E_ALL | E_STRICT), aber für dein Problem nicht relevant. Dann ist auch noch das wichtigste Debugging-Hilfsmittel aufklärend: Kontrollausgaben. Du greifst auf irgend etwas zu, das offensichtlich nicht so ist, wie du dir das vorstellst. Frage ab, was es nun konkret ist. Dazu eignet sich am besten var_dump(). Das gibt die genauesten Informationen zum befragten Objekt (im allgemeinen, nicht nur OOP-Sinn).

    echo "$verabschiedung $name";

    1. danke aber errors hab ich schon alle an

      public function __construct()
      {
       $this->instance = Connection::getInstance();
       echo var_dump($instance);
      }

      Hier bekomme ich Null.

      Wenn ich nur $instance = Connection::getInstance(); schreibe bekomme ich object(Connection)#2 (1) { ["instance:private"]=>  object(PDO)#3 (0) { } }

      Aber das hilft mir auch nicht wirklich!

      1. Hi,

        public function __construct()
        {
        $this->instance = Connection::getInstance();
        echo var_dump($instance);
        }

        Hier bekomme ich Null.

        Natuerlich, $instance ist ja auch != $this->instance.

        Die Stelle waere zum Debuggen vielleicht mal interessanter gewesen:

        public function holeBenutzerId($benutzername)
        {
            $sql = "SELECT benutzerid FROM benutzer WHERE benutzername = :benutzername";
        $stmt = $this->instance->quote->prepare($sql);

        (Wobei, wo du diese Funktion ueberhaupt aufrufst, zeigst du uns ja auch nicht ...)

        MfG ChrisB

        1. Stimmt ;)
          Die Funktion rufe ich auf meiner Startseite auf:

          $pagename = 'startseite';
            $ANGEMELDET = angemeldet();
            $RECHTE = new DB;
            $userid = $RECHTE->holeBenutzerId($_SESSION['benutzername']);

      2. echo $begrüßung;

        danke aber errors hab ich schon alle an

        Und da bist du ganz sicher, dass du nicht schon beim Zugriff auf $this->instance->quote einen Zugriffsfehler angezeigt bekommst? Ein PDO-Objekt hat keine Eigenschaft namens quote. Außerdem hast du in dem Fall gar kein PDO-Objekt vorliegen. Im Konstruktor von Connection legst du eine Eigenschaft instance an, die ein PDO-Objekt enthält. Dein Connection::getInstance() liefert dir ein Connection-Objekt zurück. Das legst du in einer ebenfalls instance genannten Eigenschaft ab. $this->instance (wenn $this ein Objekt der Klasse DB ist) ist kein PDO-Objekt sondern ein Connection-Objekt mit einer Eigenschaft instance. Willst du das PDO-Objekt ansprechen, musst du nochmal instance angeben, also $this->instance->instance. Dein $this->instance->quote versucht nun also auf eine Eigenschaft quote deines Connection-Objekts zuzugreifen, die ist laut deinerm angegebenen Quelltext aber gar nicht vorhanden, also muss das eine Notice-Meldung geben.

        echo "$verabschiedung $name";

        1. ok danke für deine hilfe
          nur ist das problem dass $instance aus meiner Connection-Klasse ja private ist:

          "Fatal error: Cannot access private property Connection::$instance in C:\xampplite\htdocs\test\funktionen.php on line 19"

          Kann es sein dass singleton und PDO zusammen gar nicht funktioniert?
          sollte ich lieber mysqli verwenden?

          1. echo $begrüßung;

            Kann es sein dass singleton und PDO zusammen gar nicht funktioniert?

            Doch, das geht schon, ist aber teilweise sinnlos. Der Konstruktor von PDO ist public, den kannst du trotz deiner Singleton-Versuche immer direkt aufrufen. Wenn du dich aber soweit disziplinierst, auf die direkte Instantiierung von PDO zu verzichten, reicht folgende Kurzform (Fehlerbehandlung mal weggelassen)

            class Connection {  
              private static $instance = null;  
              
              public static function getInstance() {  
                if (self::$instance === null)  
                  self::$instance = new PDO('mysql:host=localhost;dbname=test', 'test', 'test');  
                return self::$instance;  
              }  
            }
            

            Da braucht kein Konstruktor versteckt zu werden, weil diese Klasse nichts weiter enthält als die statische Methode. Auch das Klonen zu verhindern ist witzlos, PDO ist ja weiterhin direkt erreichbar, und einen anderen Nutzen außer dem Singleton hast du der Klasse nicht gegeben, zumindest nicht in dem zitierten Code. Man braucht noch nicht mal eine Klasse dafür, eine einfache Funktion reicht aus:

            function getInstance() {  
              static $instance = null;  
              if ($instance === null)  
                $instance = new PDO('mysql:host=localhost;dbname=test', 'test', 'test');  
              return $instance;  
            }
            

            Connection::getInstance() bzw. getInstance() geben beide direkt ein PDO-Objekt zurück, dessen Eigenschaften und Methoden du ohne weitere Kopfstände son ansprechen kannst, als hättest du ein PDO-Objekt direkt instantiiert.

            sollte ich lieber mysqli verwenden?

            In Bezug auf das oben erwähnte Singleton-Problem nimmt sich mysqli nichts. Ansonsten kann ich dir diese Entscheidung nicht abnehmen. Du musst schon selbst mal mit beiden Systemen arbeiten, um zu entscheiden, welches von ihnen dir mehr zusagt.

            echo "$verabschiedung $name";

        2. Ahh ok wenn ich $instance aus meiner connection-klasse public mache funktioniert es
          was habe ich für ne möglichkeit damit ich es auch verwenden kann wenn es private ist?