如何在不使用DI

时间:2018-03-15 12:55:03

标签: php singleton

我正在尝试一个MVC概念,其中数据库的主要模型源于或脱离其他模型。我希望有一个主数据库类型的模型来完成连接和查询。然后,构建其他模型以支持控制器。即,产品模型可以从主数据库模型扩展,然后查询而不是使用依赖注入。

我目前的主流数据库模型的意识形态和尝试看起来像这样:

namespace Portfolio\Application;

abstract class DriverModel {

    private static  $driver;
    private         $entity;

    private function __construct() {
        // Connection to the PDO will be done in here
    }

    private function __clone() {}

    public static function getInstance() {
        if(self::$driver)
            return self::$driver;

        self::$driver = new self();
        return self::$driver;
    }

    protected function q($sql, $values = []) {
        $stmt = $this->entity->Prepare($sql);
        $stmt->execute($values);
        return $stmt;
    }
}

然后我的示例配置文件控制器看起来像这样(使用主数据库运行查询的方法):

class ProfileModel extends DriverModel {
    public function doSomeQ() {
        $this->q('SELECT fname FROM users WHERE id = ?', [(int)1]);
    }
}

然而,当我执行这行代码时:

print_r(ProfileModel::getInstance()->doSomeQ());

我留下了这个错误:(这是有道理的。)

  

未捕获错误:无法实例化抽象类。

然后我从类(class DriverModel)中删除了抽象属性,但是现在,我收到的实例是来自父类的实例,这意味着我在{{1}上执行print_r()方法getInstance(),没有ProfileModel方法。

任何有关实现此方法的帮助都会有所帮助。

1 个答案:

答案 0 :(得分:2)

您必须使用get_called_class()方法而不是new self(); http://php.net/manual/en/function.get-called-class.php

附上您可以找到显示您预期行为的样本

class Main {
    public static function getInstance() {
        $class = get_called_class();
        return new $class();
    }
}
class Foo extends Main{

}

var_dump(Foo::getInstance()); // Output Foo object