我认为我在理解 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 详细信息。