Heim  >  Fragen und Antworten  >  Hauptteil

Wie verwende ich eine PDO-Verbindung in einer anderen Klasse?

Ich glaube, ich habe ein Problem damit, zu verstehen, wie OOP funktioniert. Ich habe den Code geändert, damit er funktioniert, aber meiner Meinung nach ist das nicht der richtige Weg. Das folgende Szenario (nein, ich erstelle die Benutzeranmeldung nicht selbst, sie dient eigentlich nur dazu, dass lokale Entwickler OOP besser verstehen):

Ich habe eine Datenbank.php-Datei:

class Database {

    /* Properties */
    private $conn;
    private $dsn = 'mysql:dbname=test;host=127.0.0.1';
    private $user = 'root';
    private $password = '';

    /* Creates database connection */
    public function __construct() {
        try {
            $this->conn = new PDO($this->dsn, $this->user, $this->password);
        } catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "";
            die();
        }
        return $this->conn;
    }
}

In diesem Kurs erstelle ich also eine Datenbankverbindung und gebe diese Verbindung (Objekt?) zurück

Dann habe ich die zweite Klasse, die berühmte User-Klasse (eigentlich verwende ich kein Autoloading, aber ich weiß davon):

include "database.php";

class User {
    /* Properties */
    private $conn;

    /* Get database access */
    public function __construct() {
        $this->conn = new Database();
    }

    /* Login a user */
    public function login() {
        $stmt = $this->conn->prepare("SELECT username, usermail FROM user");
        if($stmt->execute()) {
            while($rows = $stmt->fetch()) {
                $fetch[] = $rows;
            }
            return $fetch;
        }
        else {
            return false;
        }
    }
}

Das sind meine beiden Kurse. Wie Sie sehen, keine große Sache. Lassen Sie sich jetzt nicht durch den Funktionsnamen verwirren login – eigentlich versuche ich nur, einige Benutzernamen und Benutzermails aus der Datenbank auszuwählen und anzuzeigen. Dies versuche ich zu erreichen durch:

$user = new User();
$list = $user->login();

foreach($list as $test) {
    echo $test["username"];
}

Hier kommt das Problem. Wenn ich diesen Code ausführe, erhalte ich die folgende Fehlermeldung:

Unabgefangener Fehler: Aufruf der undefinierten Methode Database::prepare()

Und ich bin mir nicht sicher, ob ich wirklich verstehe, was diesen Fehler verursacht.

Der Code läuft einwandfrei, wenn ich Folgendes ändere:

Ändern $conn in der Datei „database.php“ zu „öffentlich“ statt „privat“ (ich finde das schlecht...? Aber wenn es privat ist, kann ich nur Abfragen innerhalb der Datenbankklasse durchführen, habe ich recht? Also sollte ich alle diese Abfragen in die Datenbank stellen Klasse? Ich finde das schlecht, denn bei einem großen Projekt wird es sehr groß..)

Die zweite Änderung, die ich vornehmen möchte, ist: Ändern Sie $this->conn->prepare修改为$this->conn->conn->prepare in der Datei user.php. Hier weiß ich wirklich nicht warum.

Ich meine, in user.php 的构造函数中,我有一个 $this->conn = new Database() ,并且由于 new Database 将从 DB 类返回我的连接对象,我真的不知道为什么必须有第二个 conn->

P粉548512637P粉548512637332 Tage vor630

Antworte allen(1)Ich werde antworten

  • P粉268284930

    P粉2682849302023-10-24 09:06:16

    • 不要创建诸如 Database 类之类的类,因为它毫无用处。如果数据库包装器向 PDO 添加一些额外的功能,那么创建数据库包装器就很有意义。但鉴于其当前代码,最好使用普通 PDO。
    • 从普通 PDO 或数据库类创建一个单个 $db 实例。
    • 将其作为构造函数参数传递给每个需要数据库连接的类

    数据库.php:

     \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
        \PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $pdo = new \PDO($dsn, $user, $pass, $opt);

    用户.php

    conn = $pdo;
        }
    
        /* List all users */
        public function getUsers() {
            return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
        }
    }

    app.php

    include 'database.php';
    $user = new User($pdo);
    $list = $user->getUsers();
    
    foreach($list as $test) {
        echo $test["username"],"\n";
    }

    输出:

    username_foo
    username_bar
    username_baz

    查看我的(唯一正确的)PDO 教程,了解更多 PDO 详细信息。

    Antwort
    0
  • StornierenAntwort