【问题标题】:PHP OOP call to database inside a classPHP OOP调用类内的数据库
【发布时间】:2015-01-11 02:25:14
【问题描述】:

我真的很困惑从类内部与数据库交互的正确方法是什么,我知道我在下面做错了,但我仍然希望它至少可以工作?

class User{


    public function user_email($user_id){

        require_once("config/db.php");

        $finduser = $db->query("SELECT email FROM `user` WHERE user_id = '".$user_id."' ");

        $user_data = $finduser->fetch_assoc();

        return $user_data["email"];

    }

}

然后我使用下面的代码在另一个页面上显示结果,第一个实例工作正常,但第二个引发错误。

<?php echo $user->user_email($user_id); ?>
<?php echo $user->user_email($user_id); ?>

Notice: Undefined variable: db on line 89
Fatal error: Call to a member function query() on a non-object on line 89

所以我基本上要问的是,从一个与数据库的连接位于一个位置的类中连接到数据库的好方法是什么?

感谢您的帮助!

【问题讨论】:

  • 它不起作用的原因是require_once,它只需要一次。将 require_once 更改为 require 并且脚本将始终由方法 user_email 的任何后续调用加载。

标签: php oop mysqli


【解决方案1】:

对于数据库连接,我建议将数据库访问从你的类中分离出来。你的 User 类应该只处理作为一个用户,它不应该知道它的数据来自哪里。

我建议为不同的职责使用不同的类。

例如,

存储库

应该处理从您的数据库中检索 完整 对象。它们将从数据库中返回一组(或仅一个)对象,并使用数据库中的持久数据填充它们的信息。

实体或模型

应该只处理业务逻辑。这意味着您无需调用数据库来获取用户的电子邮件,而是从数据库中加载整个用户对象数据,然后将其设置在您在此处显示的用户对象上。我这样做的方式(不使用像DoctrinePropel 这样的ORM 或MVC 框架附带的任何其他ORM)是在你的对象上创建一个名为“setByArray”的函数,它需要一个键控数组,它将根据您从数据库中找到的结果设置对象上的所有数据。

所以说真的,你的数据库访问应该从你的实际类中抽象出来。通过在课堂上使用数据库,您违反了 SOLID OOP 原则的single responsibility principle。您的 User 类应该只关心成为用户。与如何访问它的数据无关。

编辑

对不起,我想念你试图让它“正常工作”。您确定您的“config/db.php”实际上是一个路径,其中包含一个名为 $db 的变量吗?您确定 $db 实际上是具有查询功能的对象吗?从我所见,$db 不是一个对象。

【讨论】:

    【解决方案2】:

    您应该看看@leneya 在他/她的回答中的内容,这几乎是要走的路。

    但是,如果您不只是为了学习而这样做,我鼓励您使用Doctrine2 ORM

    现在谈谈您的具体问题...


    您应该将连接注入到类中。最简单的形式:

    class User {
       protected $conn;
    
       public function __construct(mysqli $conn) {
         $this->conn = $conn;
      }
    
      public function getConnection() {
         return $this->conn;
      }
    
      public function user_email($user_id){
    
    
        $finduser = $this->getConnection()->query("SELECT email FROM `user` WHERE user_id = '".$user_id."' ");
    
        $user_data = $finduser->fetch_assoc();
    
        return $user_data["email"];
    
      }
    }
    

    然后用法如下:

    require 'connection.php';
    $user = new User($db);
    $email = $user->user_email($userid);
    

    我还将更改 connection.php 以返回 mysqli 对象,这样您就不会在单独的文件中声明 var:

    // connection.php
    
    // vars and stuff for the connection
    // and then we return the instance
    return new Mysqli($host, $user, $pass, $dbname); 
    

    现在当你使用它时,你可以做到

    $db = require('connection.php');
    $user = new User($db);
    $email = $user->user_email($userid);
    

    话虽如此,这是一个非常奇怪的设计。通常,您会使用 getter 访问完整用户对象的属性并针对特定事物运行查询。

    【讨论】:

    • 我也强烈推荐 Doctrine2 ORM。它将节省大量时间并自动为您完成所有这些工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-13
    • 2015-03-27
    • 2011-09-14
    • 2014-01-11
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多