【问题标题】:Properly using classes in other classes in php?正确使用 php 中其他类中的类?
【发布时间】:2010-01-07 02:50:42
【问题描述】:

应该很久以前就问过这个人了。

在另一个类中使用其他类的最佳方式是什么?

例如,假设我有一个应用程序类:

class Application
{
    public function displayVar() {
        echo 'hello world';
    }
}

还有一个数据库类

class Database
{
    // connects to db on construct
    public function query() {
        // queries db
    }
}

现在,我想向我的应用程序类添加一个函数,该函数使用 db 类中的函数

class Application
{
    public function displayVar() {
        echo 'hello world';
    }
    public function getVar() {
        global $db;
        $sql = foo;
        $db->query($sql);
    }
}

所以我有

$db = new Database();
$app = new Application();
$app->getVar('var');

有没有更好的方法来做到这一点?我真正在寻找的是标准的操作方式,而不是另一种操纵方式。

【问题讨论】:

  • 是的,这个问题正在深入研究。你可能想看看 Citizen。
  • 呐,这里的答案正是我想要的。

标签: php mysql database class


【解决方案1】:

有几种方法可以做到这一点。全局变量当然是一种方式,也是最被忽视的方式。你可以创建一个Singleton,所有其他需要数据库访问的类都会调用这个单例。

final class Database {
    private static $connection;

    public static function getInstance() {
        if(self::$connection == NULL) {
            self::$connection = // init your database connection
        }
        return self::$connection;
    }
}

并在任何需要它的类中使用这个数据库连接对象。

class Application {
    public function displayVar() {
        echo 'hello world';
    }
    public function getVar() {
        $db = Database::getInstance();
        $sql = foo;
        $db->query($sql);
    }
}

这是一个很好的开始,也是超越使用全局变量的重要一步,但您可以使用Dependency Injection 做得更好。依赖注入是一个简单的概念,如果一个类有任何外部依赖,例如您的示例中的数据库连接,您可以在其构造函数或方法中显式地将这些传递给需要的类。所以新代码看起来像 Jonathan 的解决方案。使用依赖注入的一个主要优点是在单元测试中,您可以轻松地将这个实际的数据库对象替换为模拟对象并将其传递给任何需要它的人。

class Application {
    private $db;

    public function __construct(Database $db) {
        $this->db = $db;
    }

    public function displayVar() {
        echo 'hello world';
    }

    public function getVar() {
        $sql = foo;
        $this->db->query($sql);
    }
}

对于较小的项目,您可以轻松地自己完成。对于大型项目,有各种DI frameworks available for PHP

【讨论】:

  • 您可能希望更加强调您的第二个解决方案,因为单例方法确实容易产生大量麻烦。它通常被认为是一件坏事(但遗憾的是仍然被广泛使用)。
【解决方案2】:

$db 可能是您的 Application 类的属性。从Application 的实例中对它的任何引用都将通过$this - $this->db 完成

class Application {

  private $db = null;

  public function setDB($name) {
    $this->db = new Database($name);
  }

}

【讨论】:

  • 是的,我明白了,但是其他课程呢?就像如果我有一个 user.class.php 或一个 admin.class.php,我仍然必须全球化这个类才能使用它。
【解决方案3】:

在需要相关类的每个 PHP 文件中包含类文件(或设置自动包含)。然后根据需要实例化它。

如果你需要一个对象的“通用”实例,你可以看看 Singleton 和 Factory 模式:

Singleton Pattern Factory Pattern

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2012-11-05
    • 2012-07-20
    • 1970-01-01
    • 2014-12-21
    • 2015-08-15
    相关资源
    最近更新 更多