正确使用php中其他类的类?

时间:2010-01-07 02:50:43

标签: php mysql database class

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

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

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

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');

有更好的方法吗?我真正想要的是标准的做法,而不是另一种操纵它的方式。

3 个答案:

答案 0 :(得分:12)

有几种方法可以做到这一点。全局变量当然是一种方式,也是最容易被忽视的方式。您可以创建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

答案 1 :(得分:3)

$db可能是您Application班级的财产。在Application的实例中对其进行的任何引用都将通过$this - $this->db

完成
class Application {

  private $db = null;

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

}

答案 2 :(得分:1)

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

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

Singleton Pattern Factory Pattern