2016-01-08 56 views
0

時,我有一個父類Database如下PHP保持父類的屬性使用一個子類的構造函數

class Database{ 

    /** @var Object Filemaker object across the application*/ 
    protected $fm = null; 
    public function __construct(){ 

     if($this->fm == null){ 
      $this->_openConnection(); 
     } 
    } 

    /** 
    * Function to open connection to FileMaker 
    * @return null 
    */ 
    private function _openConnection(){ 
     $this->fm = new FileMaker(); 
    } 
} 

和我的子類之一是

class Login extends Database{ 

    public function validate(){ 
     // $this->fm is accessed here with no constructors 
     print_r($this->fm); 
    } 
} 

我通過創建對象,

$login = new Login(); 
$login->validate(); 

請注意,在這個Login類中,我沒有任何構造函數。因此,在線$login = new Login();它調用Database類的構造函數,它調用_openConnection()。這是精細

這是我的另一個子類:

class PouleManipulation extends Database{ 
    private $year; 
    public function __construct(){ 
     // $this->fm is only accessed if I call parent class constructor 
     parent::__construct(); 
     $year = '2015'; 
    } 

    public function processQueue(){ 
     $this->fm->perform(); 
    } 
} 

$pm = new PouleManipulation(); 
$pm->processQueue(); 

現在,當我叫$pm = new PouleManipulation();,請注意,我對這個類的構造函數。如果我訪問$this->fm,那麼它會拋出未定義的錯誤。我GOOGLE了,發現,

在這個類的構造函數我需要使用parent::__construct();來訪問父類的屬性。如果我沒有使用parent::__construct();然後父類對象不是當你在兒童類的構造函數現在

訪問,問題是在數據庫類$ fm爲null,並且它再次調用_openConnection( )。我有10個類擴展數據庫類和無論什麼類的構造它調用_openConnection()

我需要$ this-> fm在所有子類中進行訪問,只需要第一次調用_openConnection(),並且需要所有類中的$ this-> fm。你如何做到這一點?

+0

不會使靜態幫助嗎? –

+1

'Login' *不是* __a__'數據庫'。它沒有業務「延伸」它。瞭解依賴注入。實例化一個'Database'一次,並將其傳遞給需要數據庫連接的所有類。 – deceze

+0

@deceze你能稍微解釋一下嗎?這裏的可視性沒有問題。並且我在'Login'類中還有更多的方法以及 –

回答

2

讓我們來澄清一下。屬性設置在對象級別上。這意味着每次你實例化一個類創建一個對象時,這個對象都是新的,並且有自己的屬性不同於你實例化的屬性(它們可能具有相同的值,但是它們存儲在不同的地方並且是獨立的)。

例子:

class Database { 
    public $fm = "Value"; 
} 

class Login extends Database {} 

class PouleManipulation extends Database {} 


$a = new Login(); 
$b = new PouleManipulation(); 
$b->fm = "New Value"; 
echo $a->fm; // prints "Value" 
echo $b->fm; // prints "New Value" 

什麼你要找的是一個靜態屬性,它被設置在一流水平。如果通過靜態方法訪問它會更好。這是一個快速而骯髒的例子,但你最好使用getters和setter。

class Database { 
    public static $fm = "Value"; 
} 

class Login extends Database {} 

class PouleManipulation extends Database {} 

$a = new Login(); 
$b = new PouleManipulation(); 
$b::$fm = "New Value"; 
echo $a::$fm; // prints "New Value" 
echo $b::$fm; // prints "New Value" 

編輯: 我用你提供的用於解釋如何實現你想要的代碼,但我想強調什麼瑞恩文森特在評論中寫道:Login類應使用(不擴展)一Database

+0

Agai'$ b :: $ fm =「New Value」;'。爲什麼? –

+0

這表明,如果你要使用父類的靜態屬性,它是跨類都是從同一個父類繼承的所有對象唯一的例子。 – Aleeeeee

+0

好的。我會試試這個 –

相關問題