我認為我在理解 OOP 的工作原理方面有問題。我已經更改了它可以工作的程式碼,但這不是我認為正確的方式。以下場景(不,我不是自己創建用戶登錄,它實際上只是為了本地開發人員更好地理解 OOP):
我有一個database.php檔:
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; } }
所以在這個類別中我建立一個資料庫連線並傳回該連線(物件?)
然後我有第二個類,著名的 User 類(實際上我沒有使用自動加載,但我知道它):
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; } } }
這就是我的兩門課。正如你所看到的,沒什麼大不了的。現在,不要對函數名稱 login
感到困惑 - 實際上我只是嘗試從資料庫中選擇一些使用者名稱和使用者郵件並顯示它們。我嘗試透過以下方式實現這一目標:
$user = new User(); $list = $user->login(); foreach($list as $test) { echo $test["username"]; }
問題來了。當我執行此程式碼時,我收到以下錯誤訊息:
未捕獲錯誤:呼叫未定義的方法 Database::prepare()
而且我不確定我是否真正理解導致此錯誤的原因。
當我更改以下內容時,程式碼運作良好:
#將database.php中的$conn
更改為公共而不是私有(我認為這很糟糕......?但是當它是私有的時,我只能在資料庫類內部執行查詢,我是對的?所以我應該把所有這些查詢都在資料庫類別中?我認為這很糟糕,因為在一個大專案中它會變得非常大..)
我要做的第二個改變是:
將user.php檔案中的$this->conn->prepare
修改為$this->conn->conn->prepare
#。在這裡我真的不知道為什麼。
我的意思是,在user.php
的建構子中,我有一個$this->conn = new Database()
,並且由於new Database 將從DB 類別傳回我的連接對象,我真的不知道為什麼必須有第二個conn->
Database
類之類的類,因為它毫無用處。如果資料庫包裝器為 PDO 添加一些額外的功能,那麼建立資料庫包裝器就很有意義。但鑑於其當前代碼,最好使用普通 PDO。資料庫.php:
用戶.php
app.php
輸出:
查看我的(唯一正確的)PDO 教學,以了解更多 PDO 詳細資訊。