在其他类中使用PDO连接的方法
P粉293550575
P粉293550575 2023-08-24 15:10:58
[MySQL讨论组]

我觉得我在理解面向对象编程(OOP)的工作原理方面有问题。我已经改变了代码,使其能够工作,但我认为这不是正确的方式。以下是一个场景(不,我不是自己创建用户登录,这只是为了更好地理解OOP):

我有一个database.php文件:

class Database {

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

    /* 创建数据库连接 */
    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 {
    /* 属性 */
    private $conn;

    /* 获取数据库访问 */
    public function __construct() {
        $this->conn = new Database();
    }

    /* 登录用户 */
    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从private改为public(我认为这是不好的...?但当它是private时,我只能在Database类内部执行查询,对吗?那么我应该将所有这些查询放在Database类中吗?我认为这是不好的,因为在一个大项目中,它将变得非常庞大...)

第二个改变是:

将user.php文件中的$this->conn->prepare改为$this->conn->conn->prepare。对此我真的没有想法。

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

P粉293550575
P粉293550575

全部回复(1)
P粉451614834
  • 不要创建像Database这样的类,因为它没有什么用。如果它能为PDO添加一些额外的功能,那么创建一个数据库封装类是有意义的。但是考虑到它当前的代码,最好使用原始的PDO。
  • 从原始的PDO或者你的数据库类中创建一个单一的 $db 实例。
  • 将它作为构造函数参数传递给每个需要数据库连接的类。

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";
}

output:

username_foo
username_bar
username_baz

查看我的(唯一正确的)PDO教程以获取更多PDO的详细信息。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号