douyun3022 2014-10-09 21:36
浏览 18

为什么父代的构造只为第一个实例调用?

I have this code which might or might not be well written :). I'm trying to understand why when I create a new instance of one ojbect it doesn't run the parent construct even if I unset it.

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
    }

}

The following code will only log "database connection called" once.

1

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

2

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

3

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

The reason why I want the database to be called every time I create a new instance is because this is a cli script that could run for hours inside a while loop and if the wait_timeout from MySQL is exceeded $site->save_to_db() just won't do anything because "MySQL server has gone away". So how does it work? Why wouldn't the parent's construct be called for new instance or when I unset and start it again?

  • 写回答

2条回答 默认 最新

  • duanbi8089 2014-10-09 21:40
    关注

    This is a tricky one, you are extending what looks like a singleton.

    As you are setting a constructor in the child class, the constructor of the parent class is never called.

    But in the same constructor of the child class, you are initializing your singleton, so when you call:

     self::$instance=new $object;
    

    You call the constructor of the core class directly. And as it is set up as a singleton, that will only happen once.

    I would not recommend doing it like that, singletons are global variables in disguise (make testing a pain...) and if you decide to use it like that, you should not extend it, but call your static singleton db instance where you need it (like you are actually doing in the constructor of the child class...).

    You would be better off instantiating a database object and pass that around to the constructor of the objects that need it (dependency injection).

    By the way, should you ever want to call the constructor of a parent's class in the child class, then you would need to use parent::__construct(); in the child's constructor.

    评论

报告相同问题?

悬赏问题

  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口