2014-07-14 77 views
0

突然之間,一段時間內工作正常的腳本停止了,沒有錯誤。我已將它固定到__contruct方法,但無法理解它爲何發生。代碼的簡化版本....PHP5 __construct沒有調用,沒有錯誤

<?php 
class ex1 { 
    protected $dbh; 
    function __construct(){ 
     $this->dbh = new PDO('mysql:host=localhost;dbname=db', 'user', 'pw', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING)); 
    } 
} 
?> 


<?php 
include('ex1.class.php'); 
class ex2 extends ex1 { 
    somefunc(){ 
     is_object($this->dbh); // = FALSE 
    } 
} 
?> 

PDO構造獨立工作,其實沒什麼,我把在EX1構造似乎運行,並在日誌中沒有錯誤(設爲E_ALL & E_STRICT)。

任何想法?

+1

類'ex1()'沒有被它的子類'ex2()'實例化,也沒有調用父類的構造,因此不調用ex1()構造函數 –

+0

如果你快樂,你知道它...語法錯誤 –

回答

2

如果您ex2類有它自己的構造函數,你應該從它調用父類的一個:

class ex2 extends ex1 { 

    function __contruct() { 
     /* ex2::__construct() code here */ 
     parent::__construct(); 
    } 

    function somefunc() { 
     is_object($this->dbh); 
    } 
} 

而且你有一個錯字:

somefunc() {} 

應該是:

function somefunc() {} 
+3

一個空的構造函數,只是調用父構造函數是多餘的。如果構造函數沒有被覆蓋,那麼父構造函數仍然被調用 –

+2

@Elias Van Ootegem你是對的。但是我們不知道他是否在ex2類中有構造函數,因爲這是他的代碼的「簡化版」 – Phantom

+0

我編輯了這個答案以反映@EliasVanOotegem的註釋。 – Narf

4

繼承的簡單規則(就構造函數而言)如下:

  • 如果子類沒有自己的構造,然後父構造函數用於
  • 如果子類確實有自己的構造,父構造函數必須顯式調用
  • 合同在父母和孩子之間的類適用於構造,太

基本上,這意味着,應用到你的代碼中,父類的構造應該被稱爲AUT omatically。你說的構造函數沒有被調用,所以你可能定義在子類的構造函數,在這種情況下,簡單的添加此聲明:

parent::__construct(); 

幾個例子

class Foo 
{ 
    protected $val = null; 
    public function __construct() 
    { 
     $this->val = 123; 
    } 
} 
class Bar extends Foo 
{ 
    public function test() 
    { 
     return $this->val; 
    } 
} 
$b = new Bar(); 
echo $b->test(); 

這將呼應123,因爲Foo::__construct()被自動調用。然而,如果我們改變Bar了一下,然後更改的行爲:

class Bar extends Foo 
{ 
    protected $another = null; 
    public function __construct() 
    { 
     $this->another = __METHOD__; 
    } 
    public function test() 
    { 
     return $this->val; 
    } 
} 
$b = new Bar(); 
var_dump($b->test());//null 

所以val屬性未被設置。一個簡單的修正,但:

class Bar extends Foo 
{ 
    protected $another = null; 
    public function __construct() 
    { 
     $this->another = __METHOD__; 
     parent::__construct();//call here, explicitly 
    } 
    public function test() 
    { 
     return $this->val; 
    } 
    public function getMethod() 
    { 
     return $this->another; 
    } 
} 
$b = new Bar(); 
var_dump($b->test());//123 
echo $b->getMethod();//echoes Bar::__construct 

總而言之,設置屬性的PDO實例不被認爲是最好的想法。檢查出依賴注入,控制的谷歌倒置和所有這些buzz詞。

另一種方法是使用延遲加載干將:

class Foo 
{ 
    $this->db = null; 
    protected function getDb() 
    { 
     if ($this->db === null) 
      $this->db = new PDO();//create when needed 
     return $this->db; 
    } 
} 

這樣,DB連接將在最後一刻,當依靠該連接上的代碼調用getDb方法創建...

+0

很好的答案。 Upvote :) – Phantom