我想我在理解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类(其实我没有在使用autoload,但我知道它):
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"];
}
问题来了。当我执行这段代码时,我会得到以下错误消息:
未捕获的错误:调用未定义的方法数据库::Prepare()
而且我不确定我是否真的理解了导致这个错误的原因。
当我更改以下内容时,代码工作得很好:
将Database.php中的$conn
更改为public而不是private(我认为这很糟糕...?但是当它是private时,我只能在Database类内部执行查询,对吗?那么我应该把所有这些查询都放在Database类中吗?我认为这很糟糕,因为在一个大项目中,它会变得非常大...)
我要做的第二个更改是:将user.php文件中的$this->conn->prepare
更改为$this->conn->conn->prepare
。我真的不知道为什么。
我的意思是,在user.php
的构造函数中,我有一个$this->conn=new Database()
并且由于new Database将从DB类返回connection对象,我真的不知道为什么必须有第二个conn->
database.php:
<?php
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new \PDO($dsn, $user, $pass, $opt);
user.php
<?php
class User {
/* Properties */
private $conn;
/* Get database access */
public function __construct(\PDO $pdo) {
$this->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细节。