PHP class 中对数据库的 OOP 调用
PHP OOP call to database inside a class
我真的很困惑从 class 内部连接数据库的正确方法是什么,我知道我在下面做错了,但我仍然希望它能工作至少?
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
所以我基本上要问的是,从 class 连接到数据库的好方法是什么,其中与数据库的连接位于一个位置?
感谢您的帮助!
你应该看看@leneya 在 his/her 中的回答,这几乎是正确的选择。
但是,如果您不只是为了学习而这样做,我鼓励您使用 Doctrine2 ORM。
现在回答您的具体问题...
您应该将连接注入 class。最简单的形式:
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
更改为 return 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 来访问完整用户对象的属性,并 运行 查询特定内容。
对于数据库连接,我建议将数据库访问从 class 中分离出来。您的用户 class 应该只处理作为用户的身份,它不应该知道它的数据来自哪里。
我建议针对不同的职责使用不同的 classes。
例如,
存储库
应该处理从您的数据库中检索全部 对象。他们将从数据库中 return 一组(或仅一个)对象,并使用数据库中的持久数据填充他们的信息。
实体或模型
应该只处理业务逻辑。这意味着您不是调用数据库来获取用户的电子邮件,而是从数据库中加载整个用户对象数据,然后将其设置在此处显示的用户对象上。我这样做的方式(不使用 Doctrine or Propel 之类的 ORM 或 MVC 框架附带的任何其他 ORM)是在您的对象上创建一个名为“setByArray”的函数,它将采用一个键控数组将根据您从数据库中找到的结果在您的对象上设置所有数据。
所以说真的,您的数据库访问应该从您的实际 class 中抽象出来。通过在 class 中使用数据库,您违反了 SOLID OOP 原则的 single responsibility principle。您的用户 class 应该只关心成为用户。与如何访问它的数据无关。
编辑
抱歉,我想念你试图让它“正常工作”的尝试。您确定您的“config/db.php”实际上是一个路径,其中包含一个名为 $db 的变量吗?您确定 $db 实际上是具有查询功能的对象吗?据我所见,$db 不是一个对象。
我真的很困惑从 class 内部连接数据库的正确方法是什么,我知道我在下面做错了,但我仍然希望它能工作至少?
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
所以我基本上要问的是,从 class 连接到数据库的好方法是什么,其中与数据库的连接位于一个位置?
感谢您的帮助!
你应该看看@leneya 在 his/her 中的回答,这几乎是正确的选择。
但是,如果您不只是为了学习而这样做,我鼓励您使用 Doctrine2 ORM。
现在回答您的具体问题...
您应该将连接注入 class。最简单的形式:
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
更改为 return 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 来访问完整用户对象的属性,并 运行 查询特定内容。
对于数据库连接,我建议将数据库访问从 class 中分离出来。您的用户 class 应该只处理作为用户的身份,它不应该知道它的数据来自哪里。
我建议针对不同的职责使用不同的 classes。
例如,
存储库
应该处理从您的数据库中检索全部 对象。他们将从数据库中 return 一组(或仅一个)对象,并使用数据库中的持久数据填充他们的信息。
实体或模型
应该只处理业务逻辑。这意味着您不是调用数据库来获取用户的电子邮件,而是从数据库中加载整个用户对象数据,然后将其设置在此处显示的用户对象上。我这样做的方式(不使用 Doctrine or Propel 之类的 ORM 或 MVC 框架附带的任何其他 ORM)是在您的对象上创建一个名为“setByArray”的函数,它将采用一个键控数组将根据您从数据库中找到的结果在您的对象上设置所有数据。
所以说真的,您的数据库访问应该从您的实际 class 中抽象出来。通过在 class 中使用数据库,您违反了 SOLID OOP 原则的 single responsibility principle。您的用户 class 应该只关心成为用户。与如何访问它的数据无关。
编辑
抱歉,我想念你试图让它“正常工作”的尝试。您确定您的“config/db.php”实际上是一个路径,其中包含一个名为 $db 的变量吗?您确定 $db 实际上是具有查询功能的对象吗?据我所见,$db 不是一个对象。