php - 如何在其他类中使用PDO连接?

标签 php oop pdo

我想我在理解 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;
        }
    }
}

这就是我的两个类(class)。如您所见,没什么大不了的。现在,不要对函数名称 login 感到困惑 - 实际上我只是尝试从数据库中选择一些用户名和用户邮件并显示它们。我尝试通过以下方式实现这一目标:

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

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

问题来了。当我执行这段代码时,我收到以下错误消息:

Uncaught Error: Call to undefined method Database::prepare()

而且我不确定我是否真的了解导致此错误的原因。

当我更改以下内容时,代码运行良好:

将 database.php 中的 $conn 更改为 public 而不是 private(我认为那很糟糕......?但是当它是私有(private)的时,我只能在 Database 类中执行查询,我是对吗?那么我应该把所有这些查询都放在数据库类中吗?我认为这很糟糕,因为在一个大项目中它会变得非常大..)

我要做的第二个改变是: 将user.php文件中的$this->conn->prepare改为$this->conn->conn->prepare。在这里我真的不知道为什么。

我的意思是,在 user.php 的构造函数中,我有一个 $this->conn = new Database() 并且因为 new Database 会返回给我来自 DB 类的连接对象,我真的不知道为什么必须有第二个 conn->

最佳答案

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

数据库.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);

用户.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();
    }
}

应用.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

查看我的 (The only proper) PDO tutorial获取更多 PDO 详细信息。

关于php - 如何在其他类中使用PDO连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43630810/

相关文章:

php - 如何使用 <td> 和 rowspan 对数据库中的值进行分组?

php - 如果 FTP 服务器无效,如何收到错误消息?

c++ - 对象成员变量还是继承?

java - 容器对象中的通用 getter

php - 动态创建MySQL表可以吗?

php - 在哪里设置 PHP $_SERVER ['DOCUMENT_ROOT' ] Trailing Slash?

objective-c - 静态/类方法存储在 objective-c 中的位置

php - MYSQL PHP PDO - 即时添加 WHERE PlaceHolder 子句

php - 如何使用 PHP 从两个表生成动态内容

PHP PDO 未正确绑定(bind)