如何在其他类中使用

如何在其他类中使用

本文介绍了如何在其他类中使用 PDO 连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我在理解 OOP 的工作原理方面遇到了问题.我已经更改了它的工作代码,但这不是我认为的正确方式.以下场景(不,我不是自己创建用户登录,它真的只是为了让本地开发人员更好地理解 OOP):

I think I've a problem in understanding how OOP works. I already changed the code that it works, but it isn't the propper way I think. Following scenario (No, I'm not creating a userlogin by myself, its really just for local dev. to understand OOP better):

我有一个 database.php 文件:

I've a database.php file:

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

所以在这个类中我正在创建一个数据库连接并返回连接(对象?)

So in this class I'm creating a database connection and I return the connection (object?)

然后我有第二个类,著名的 User 类(实际上我没有使用自动加载,但我知道它):

Then I have a second class, the famous User class (actually I'm not using autoload, but I know about it):

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 感到困惑 - 实际上我只是尝试从数据库中选择一些用户名和用户邮件并显示它们.我尝试通过以下方式实现这一目标:

So thatare my two classes. Nothing big, as you see. Now, don't get confued about the function name login - Actually I just try to select some usernames and usermails from database and displaying them. I try to achieve this by:

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

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

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

And here comes the problem. When I execute this code, I get the following error message:

未捕获的错误:调用未定义的方法 Database::prepare()

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

And I'm not sure that I really understand what causes this error.

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

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

Change $conn in database.php to public instead of private (I think thats bad...? But when its private, I can only execute querys inside of the Database class, I'm right? So should I put all these querys in the Database class? I think that's bad, because in a big project it will get become really big..)

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

And the second change I've to do is:Change $this->conn->prepare to $this->conn->conn->prepare in the user.php file. And here I've really no Idea why.

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

I mean, in the constructor of the user.php I've a $this->conn = new Database() and since new Database will return me the connection object from DB class, I really don't know why there have to be a second conn->

推荐答案

  • 您当前的课程毫无用处.如果它为 PDO 添加了一些额外的功能,那么创建一个数据库包装器是有意义的.但鉴于其当前代码,最好改用 vanilla PDO.
  • 无论哪种方式,从 vanilla PDO 或您的数据库类创建一个单个 $db 实例.
  • 将其作为构造函数参数传递到每个需要数据库连接的类中
    • your current class is rather useless. It would make sense to create a database wrapper if it adds some extra functionality to PDO. But given its current code, better to use vanilla PDO instead.
    • Either way, create a single $db instance from either vanilla PDO or your database class.
    • pass it as a constructor parameter into every class that needs a database connection
    • database.php:

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

      输出:

      username_foo
      username_bar
      username_baz
      

      查看我的(唯一合适的)PDO 教程,了解更多 PDO 详细信息.

      Check out my (The only proper) PDO tutorial for more PDO details.

      这篇关于如何在其他类中使用 PDO 连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 08:05