2013-01-14 173 views
0

這應該很容易..有人可以解釋我的語法嗎?PHP在父類中訪問類對象

我有一個控制器實例化一個引導類(新關鍵字),它實例化配置類。

然後控制器實例化一個擴展引導類的起始頁類。在startpage類中,我試圖訪問bootstrap(父類)類中的配置對象。

這可以完成嗎?或者startpage是否必須直接實例化bootstrap?是否實例化擴展引導程序的首頁,覆蓋引導程序?或者我的語法錯了?

控制器(索引頁)

try { 
    if (!include($paths['root'] . $paths['framework'] . '/core/AutoLoader.php')) { 
     throw new Exception ('<b>Error - AutoLoader is missing</b>'); 
    } 
    $loader = new AutoLoader($paths); 
    $appStack = new BootStrap($paths); 
    $app  = new StartPage(); 
    $app->start(); 
} catch (Exception $e) { 
    echo 
     '<p><b>EXCEPTION</b><br />Message: ' 
     . $e->getMessage() 
     . '<br />File: ' 
     . $e->getFile() 
     . '<br />Line: ' 
     . $e->getLine() 
     . '</p>'; 
} 

Bootstrap類:

class BootStrap { 
    protected $config; 

    /** 
    * -------------------------------------------------------------------------- 
    ** GETTERS 
    * -------------------------------------------------------------------------- 
    * 
    */ 
    public function getConfig() { return $this->config; } 

    /** 
    * -------------------------------------------------------------------------- 
    * __construct() 
    * PUBLIC method 
    * = Starts a new session, loads stylesheets, loads classes 
    * -------------------------------------------------------------------------- 
    * 
    */ 
    public function __construct($paths) { 

     /** 
     * -------------------------------------------------------------------------- 
     * load Config class 
     * -------------------------------------------------------------------------- 
     * 
     */ 
     try { 
      if (!class_exists('Config')) { 
       throw new Exception ('<b>Error - Configuration class is missing</b>'); 
      } 
      $this->config  = new Config(); 
     } catch (Exception $e) { 
      echo 
       '<p><b>EXCEPTION</b><br />Message: ' 
       . $e->getMessage() 
       . '<br />File: ' 
       . $e->getFile() 
       . '<br />Line: ' 
       . $e->getLine() 
       . '</p>'; 
     } 
    } 
} 

首頁中國類:

class StartPage extends BootStrap { 

    /** 
    * -------------------------------------------------------------------------- 
    * __construct() 
    * PUBLIC method 
    * = Starts a new session, loads stylesheets, loads classes 
    * -------------------------------------------------------------------------- 
    * 
    */ 
    public function __construct() { 
    } 

    /** 
    * -------------------------------------------------------------------------- 
    * Start() 
    * PUBLIC method 
    * = loads the web page 
    * -------------------------------------------------------------------------- 
    * 
    */ 
    public function Start() { 

     // path to includes 
     $inc_path = $this->paths['root'] . $this->paths['medium']; 

     // instantiate page, html header 
     $charset  = $this->config->getCharset(); 
     $title  = $this->config->getTitle(); 
     $description = $this->config->getDescription(); 
    } 
} 
+0

'parrent :: obj' .. – Davit

+0

你是否看到'配置類缺失'異常? – hohner

+0

試過。 ** $ charset = parent :: $ config-> getCharset(); ** ...同樣的錯誤。 – obmon

回答

2

只要你給StartPage自己的__construct()方法,您可以有效地 「隱藏」 了一個在Bootstrap,完全超越它。所以$foo = new StartPage()只有運行StartPage類的__construct()代碼。

爲了也運行Bootstrap父類中的__construct()代碼,您必須使用parent::__construct()向其添加明確的調用。

如果你想知道爲什麼PHP不適合你做到這一點,這裏有三件事情你不能做,如果它是自動的:

  1. 運行的代碼都之前和父後構造函數,通過選擇何時調用parent::__construct()
  2. 在繼承其他類的同時,用其他東西替換整個構造器邏輯。
  3. 將值傳遞給父構造函數總是相同/可以由子類自動選擇,但需要明確提供給父類。

編輯:總結下面的進一步澄清,創建父的特定實例(Bootstrap)類不會對同一類或它的子類的其他實例以後的創作有什麼區別(StartPage) ;每個都是一個獨立的對象,將獨立地調用__construct

如果您希望多個StartPage對象引用Bootstrap類的一個特定實例,則繼承不是正確的機制。相反,您需要通過某種形式的依賴注入將創建的Bootstrap實例傳遞給每個StartPage實例。

+0

但我已經從控制器調用Bootstrap。我編輯了原帖以顯示此內容。 – obmon

+0

那麼,bootstrap的構造函數可以從兩個不同的地方調用兩次?我很困惑這.. – obmon

+0

@obmon我覺得你是困惑類和對象。當你創建一個新的'StartPage'對象時,它不知道任何已經創建的其他對象,或類'Bootstrap'或'StartPage'。你需要做的是初始化特定的'StartPage'對象中的數據,並且只有'StartPage :: __ construct()'可以做到這一點。 – IMSoP

0

嘗試執行子類的構造函數,並明確調用構造函數父母。

public function __construct() { 
    parent::__construct(); 
} 
+0

但是這不會覆蓋控制器的類的以前的實例嗎?似乎有點hackish太.. – obmon

+1

不是真的,一個類的對象只實例化一次無論如何。你只需確保任何構造函數在超類中被調用,以及在調用子類時。 – xelber

0

在起始頁:

protected $config; 

public function __construct() 
{ 
    $this->config = $this->getConfig(); 
} 

或者,下面xelber的回答,請parent::__construct();

+1

我們想要繼承現有的實例,而不是複製並粘貼它。 – IMSoP

+0

上面的變量聲明將起作用。不知道這個神話中的「我們」是誰。 – hohner