2013-01-14 221 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