0

这应该很容易..有人可以为我解释一下语法吗?

我有一个控制器,它实例化一个引导类(新关键字),它实例化配置类。

然后控制器实例化一个扩展引导类的起始页类。在起始页类中,我试图访问引导(父)类中的配置对象。

这甚至可以做到吗?还是 startpage 必须直接实例化引导程序?实例化扩展引导程序的起始页是否覆盖引导程序?还是我的语法错了?

控制器(索引页)

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>';
}

引导类:

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();
    }
}
4

3 回答 3

2

一旦你给出StartPage了它自己的__construct()方法,你就有效地“隐藏”了Bootstrap它,完全覆盖了它。所以$foo = new StartPage() 运行类中的__construct()代码StartPage

为了同时__construct()在父类中运行代码Bootstrap,您必须添加一个显式调用,使用parent::__construct().

如果您想知道为什么 PHP 不为您执行此操作,如果它是自动的,以下是您无法执行的三件事:

  1. 通过选择何时调用来在父构造函数之前之后运行代码parent::__construct()
  2. 用其他东西替换整个构造函数逻辑,同时仍然继承类的其余部分。
  3. 将始终相同的值传递给父构造函数/可以由子类自动选择,但需要显式提供给父类。

编辑:总结下面的进一步说明,创建父 ( Bootstrap) 类的特定实例不会对以后创建同一类或其子类 ( StartPage) 的其他实例产生任何影响;每个都是一个单独的对象,将__construct独立调用。

如果您希望多个StartPage对象引用Bootstrap该类的一个特定实例,那么继承不是正确的机制。相反,您需要通过某种形式的依赖注入将创建的Bootstrap实例传递给每个实例。StartPage

于 2013-01-14T00:13:21.120 回答
0

尝试实现子类的构造函数并显式调用父类的构造函数。

public function __construct() {
    parent::__construct();
}
于 2013-01-14T00:11:04.450 回答
0

在起始页中:

protected $config;

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

或者,按照 xelber 的回答,使用parent::__construct();

于 2013-01-14T00:13:08.253 回答