PHP OOP~多个类需要相同的类

PHP OOP~多个类需要相同的类,php,database,oop,class,object,Php,Database,Oop,Class,Object,我目前有多个类,它们都依赖于一个类,数据库类。每个类都需要数据库类的一个实例来运行,对此,我有点担心 在将所有过程代码转换为面向对象代码之前,我需要弄清楚这一点。我目前有一个数据库连接用于整个程序。然而,据我所知,当我将代码转换为OOP时,我将在同一个程序中拥有多个具有开放数据库连接的类。(所有这些类都将包含在主程序文件中) 如何正确地实现这一点?我假设在同一个程序中有5个打开的数据库连接肯定不是正确的方法。您可以通过将数据库连接作为参数提供给构造函数,在多个不同的对象之间共享数据库连接,或者您

我目前有多个类,它们都依赖于一个类,数据库类。每个类都需要数据库类的一个实例来运行,对此,我有点担心

在将所有过程代码转换为面向对象代码之前,我需要弄清楚这一点。我目前有一个数据库连接用于整个程序。然而,据我所知,当我将代码转换为OOP时,我将在同一个程序中拥有多个具有开放数据库连接的类。(所有这些类都将包含在主程序文件中)


如何正确地实现这一点?我假设在同一个程序中有5个打开的数据库连接肯定不是正确的方法。

您可以通过将数据库连接作为参数提供给构造函数,在多个不同的对象之间共享数据库连接,或者您可以创建一个单例来使用数据库连接为其他类提供服务

将数据库连接传递给构造函数

class Foo {

    private $database = null;

    public function __construct(&$database) {
        $this->database = $database;
    }
}
$connection = mysql_connect(..);
$bar = new Foo($connection);
单身人士

class DatabaseConnection {

    private static $instance = null;

    private function __construct() {
    }

    public static function &getInstance() {
        if (DatabaseConnection::$instance == null) {
            DatabaseConnection::$instance = new DatabaseConnection();
        }
        return DatabaseConnection::$instance;
    }
}

$mysql_query("...", DatabaseConnection::getInstance());

&表示通过引用传递,因此即使在几个不同的文件、类或函数中使用数据库对象,也只有一个实例。有关更多信息,请参阅

雅各布关于使用Singleton+聚合的建议是合理的。 除此之外,我还要添加ORM/DBAL


通过在“Foo”类中使用对象,避免将单例实例直接耦合到对象,而是将单例实例传递给构造函数。通过这种方式,您可以实现更多的解耦,从而获得更多的自由。

如果您有依赖于数据库抽象的类,那么依赖注入是一种方法

class PDOProvider extends PDO
{
    public function __construct()
    {
        try { 

          parent::__construct(...); 
          $this->setAttribute(....);

        } catch(PDOException $e){
            die($e->getMessage());
        }
    }
    // ...
}

class Users
{
    private $provider; 

    public function __construct(PDOProvider $provider) // <- Injecting class dependency
    {
       $this->provider = $provider;
    }

    public function insert(array $stuff)
    {
       try {

        $this->provider->prepare("INSERT ...");
        $this->provider->execute(array(..));

       } catch(PDOException $e){
          //...
       }
    }
}
类PDO提供程序扩展了PDO { 公共函数构造() { 试试{ 父项::_构造(…); $this->setAttribute(..); }捕获(PDO$e){ 死亡($e->getMessage()); } } // ... } 类用户 { 私人供应商; 公共函数u_构造(PDOProvider$provider)//provider=$provider; } 公共函数插入(数组$stuff) { 试一试{ $this->provider->prepare(“插入…”); $this->provider->execute(数组(..); }捕获(PDO$e){ //... } } }
这肯定回答了我的问题。后者是我所期望的。然而,它似乎是如此不干净。必须使用静态变量来保存类的实例。哦,好吧。非常感谢。Singleton设计模式是众所周知的,尽管很多人不喜欢它,因为正如您所说,它太不干净了。@SteffanLong如果您复制了代码,getInstance()方法中有一个错误的感叹号,尽管它现在已被修复。@Jakobbogulis第一个选项(将它传递给构造函数)更好,因为它可以让您轻松地模拟,并通过传递一个“假”数据库连接来测试您的程序,该连接将允许您稍后隔离问题。-1:singleton是一种反模式,它在应用程序中引入全局状态。另外,由于PHP5.0,通过引用传递对象是有害的。谢谢你的建议。不客气。metal_fan:的答案也很好,依赖项注入是您应该使用的,但是您可能需要将应用程序依赖项存储在应用程序的注册表中-我会将EntityManager或DB句柄存储在那里,然后实现某种应用程序->getInstance()->getDependency(“DB”)。或者,如果您决定使用MVC,您可以始终将DB句柄传递给“在sceen后面”的控制器。顺便说一句,如果您有使用PHP5.3的特权,请使用后期静态绑定:很可能是这样,但仅仅说“单例永远不是好建议”也不是。如果你提出这样的主张,至少要支持它。我对单身汉的看法是,应该避免这种情况——有时这是一种必要的罪恶。我的观点是务实的。此外,在我的建议中,我还提出了脱钩和条令……我对你的帖子投了更高的票。我不知道为什么会被否决。在这种情况下,使用依赖注入(如您所演示的)是非常好的。但是,让模型了解数据库并不是件好事。。。它应该被视为一个服务层,并与模型解耦。如果要将模型服务层更改为其他层,该怎么办?那你就有麻烦了!以下是一些需要考虑的想法:您可能会发现此主题与此相关: