为什么家长';s构造仅为第一个实例调用


Why is the parent's construct called only for the first instance?

我有这样的代码,可能写得很好,也可能写得不好:)。我试图理解为什么当我创建一个ojbect的新实例时,即使我取消设置它,它也不会运行父构造。

class core
{
    protected $db;   
    private static $dsn  = 'mysql:host=localhost;dbname=tracking';
    private static $user = 'root';
    private static $pass = 'root';
    private static $instance;
    public function __construct () {
        $this->db = new PDO(self::$dsn,self::$user,self::$pass);
        error_log("database connection called");
    }
    public static function getInstance(){
            if(!isset(self::$instance)){
                $object= __CLASS__;
                self::$instance=new $object;
            }
            return self::$instance;
     }
}
class Site extends core{
    function __construct(){
        global $argc, $argv;
        $this->db_core = core::getInstance();
        $this->pdo = $this->db_core->db;
        $this->track_id = $argv[1];
        error_log("SITE construct called!");
    }
    function save_to_db(){
        //stuff
    }
}

以下代码将只记录一次"调用的数据库连接"。

1

$site  = new Site;
unset($site);
$site  = new Site;

2

$site  = new Site;
$site  = new Site;

3

$site  = new Site;
$site_new  = new Site;

我之所以希望每次创建新实例时都调用数据库,是因为这是一个cli脚本,可以在while循环中运行数小时,如果超过了MySQL的wait_timeout,$site->save_to_db()将不会执行任何操作,因为"MySQL服务器已经离开"。那么它是如何工作的呢?为什么不为新实例调用父对象的构造,或者当我取消设置并重新启动它时?

这是一个棘手的问题,您正在扩展看起来像singleton的东西。

当您在子类中设置构造函数时,父类的构造函数永远不会被调用。

但是在子类的同一个构造函数中,您正在初始化您的singleton,所以当您调用:时

 self::$instance=new $object;

您可以直接调用core类的构造函数。由于它是作为一个单例设置的,所以这种情况只会发生一次。

我不建议这样做,singleton是伪装的全局变量(让测试变得痛苦…),如果你决定这样使用它,你不应该扩展它,而是在你需要的地方调用你的静态singleton db实例(就像你在子类的构造函数中实际做的那样…)。

您最好实例化一个数据库对象,并将其传递给需要它的对象的构造函数(依赖注入)。

顺便说一句,如果您想在子类中调用父类的构造函数,那么您需要在子类的构造函数中使用parent::__construct();

core类就是所谓的"Singleton"。它创建自己的一个实例,并使其全局可用。singleton的全部意义在于它只能有一个实例

当实例化$site、取消设置或再次实例化时,core类的self::$instance属性保持不变。这是因为它是一个静态属性,它们不绑定到实例,而是类成员,是持久的(当脚本运行时)。

顺便说一下,以下代码过于复杂:

$object= __CLASS__;
self::$instance=new $object;

也可以是:

self::$instance = new self();

更短更明显。