0

This should be easy.. can someone explain the syntax for me?

I have a controller which instantiates a bootstrap class (new keyword) which instantiates the config class.

the controller then instantiates a startpage class which extends the bootstrap class. In the startpage class I'm trying to access the config object in the bootstrap (parent) class.

Can this even be done? Or does startpage have to instantiate bootstrap directly? Does instantiating startpage that extends bootstrap, overwrite bootstrap? or is my syntax just wrong?

Controller (index page)

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:

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

Startpage class:

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
  • Are you seeing the exception Configuration class is missing? Commented Jan 14, 2013 at 0:07
  • tried that. $charset = parent::$config->getCharset(); ... same error. Commented Jan 14, 2013 at 0:08
  • @Jamie Nope. Error I get: Fatal error: Call to a member function getCharset() on a non-object in .. Commented Jan 14, 2013 at 0:09
  • Strange thing is.. in the constructor of StartPage I use $this->paths['uri'] and it doesn't give me an error at all. The problem I think is accessing a class object through a class object in another class object? Commented Jan 14, 2013 at 0:11

3 Answers 3

2

As soon as you give StartPage its own __construct() method, you effectively "hide" the one in Bootstrap, over-riding it completely. So $foo = new StartPage() only runs the __construct() code from the StartPage class.

In order to also run the __construct() code in the Bootstrap parent class, you have to add an explicit call to it, using parent::__construct().

In case you wonder why PHP doesn't do this for you, here are three things you couldn't do if it were automatic:

  1. Run code both before and after the parent constructor, by choosing when to call parent::__construct().
  2. Replace the entire constructor logic with something else while still inheriting the rest of the class.
  3. Pass values into the parent constructor which are always the same / can be chosen automatically by the child class, but which would need to be provided explicitly to the parent class.

EDIT: To summarise the further clarifications below, creating a particular instance of the parent (Bootstrap) class will not make any difference to later creations of other instances of the same class or its child class (StartPage); each is a separate object and will call __construct independently.

If you want multiple StartPage objects to refer to one particular instance of the Bootstrap class, then inheritance is not the right mechanism. Instead, you will need to pass the created Bootstrap instance into each StartPage instance via some form of Dependency Injection.

Sign up to request clarification or add additional context in comments.

12 Comments

But I am already calling Bootstrap from the controller. I have edited the original post to show this.
So, the constructor for the bootstrap can be called twice from two different places? I'm confused by this..
@obmon I think you are confusing Classes and Objects. When you create a new StartPage object, it doesn't know anything about any other objects which have been created, of class Bootstrap or StartPage. What you need to do is initialise the data in that specific StartPage object, and only StartPage::__construct() can do that.
Yes, sorry, I'm still in the OOP learning curve... but StartPage extends Bootstrap.. so it should already "know" about the BootStrap object that should already be instantiated...
@obmon Yes, if you want multiple objects to refer to a particular instance of the Bootstrap class, then inheritance is not the right mechanism.
|
0

Try implementing the constructor of the Child Class and explicitly call the constructor of the parent.

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

2 Comments

But wouldn't that overwrite the previous instantiation of the class from the controller? Seems kinda hackish too..
Not really, the object of a class is instantiated only once anyway. You are just making sure any constructors are called in the super class as well when the child class is called.
0

In StartPage:

protected $config;

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

Or, following xelber's answer, use parent::__construct();

2 Comments

We want to inherit the existing instantiation, not copy-and-paste it.
The above variable declaration will work. Not sure who this mythical 'we' is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.