了解OOP - 如何在其他类中使用PDO连接

时间:2017-04-26 09:54:39

标签: 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;
    }
}

所以在这个课程中,我创建了一个数据库连接并返回连接(对象?)

然后我有第二堂课,着名的用户班(实际上我没有使用自动加载,但我知道它):

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

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

我的意思是,在user.php的构造函数中我有一个$this->conn = new Database(),因为新数据库会从DB类返回连接对象,我真的不知道为什么有这个成为第二个conn->

如果有人能够更好地解释我,我会非常感激。我知道变量的可见性,并且我已经阅读了很多相关信息,但我认为我现在还没有理解它,否则我不会遇到这个问题。

感谢每一位建议! :)

1 个答案:

答案 0 :(得分:13)

  • 你现在的班级很无用。鉴于其当前的代码,最好使用vanilla PDO。
  • 从vanilla 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 get_users() {
        return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
    }
}

app.php

include 'database.php';
$user = new User($pdo);
$list = $user->get_users();

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

输出:

username_foo
username_bar
username_baz

查看我的(The only proper) PDO tutorial了解更多PDO详情。