Stefan
Stefan

Reputation: 259

Classes and constructors

For getting some default options, there is the following class:

class settings { 
    function __construct() {
        $this->companyName = "Company x"; /* retrieving information from the database */
    }
    function getCompanyName() { return $this->companyName; }
}

Of course, this class has other important functions, but for simplifying this question; this class get the settings from the MySQL database.

Now, there is another class for sendings some mails.

class mailing extends settings {
    function __construct() { /* Default options for mailing */ }
    function sendMail() {
        echo "Send mail to ".$this-> getCompanyName();
    }
}

I would like to get the settings from the class settings, but without calling parent::__construct() in this class since the information is already retrieved from the database in the settings class. I call the systems as following:

$settings = new settings();
$mailing = new mailing();
$mailing->sendMail();

Unfortunately, I didn't get the company name.

Upvotes: 0

Views: 84

Answers (7)

Daniel Alonso
Daniel Alonso

Reputation: 60

Extending a class would not help you achieve what you are trying to do, and i am not sure if this is the best design. However if you want to have an object with all the settings and then have a mailing class that uses this options, you should do it by adding a property "settings" to the mailing class:

//your settings class:

class settings { 
    function __construct() {
        $this->companyName = "Company x"; /* retrieving information from the database */
    }
    function getCompanyName() { return $this->companyName; }
}

//new mailing class, constructors takes a settings object

class mailing {

    private $settings;

    function __construct(settings $settings) { 
        $this->settings=$settings;
    }

    function sendMail() {
        echo "Send mail to ".$this->settings->getCompanyName();
    }
}

//initialize the settings from DB

$settings = new settings();

//create new class with initialized settings

$mailing = new mailing($settings);
$mailing->sendMail();

This will output "Send mail to Company x" and you can reuse the settings object where you may need it.

Upvotes: 0

Halcyon
Halcyon

Reputation: 57709

Conceptually it seems very strange to me that mailing is an instanceof settings.

I think this makes more sense:

$settings = new Settings();
$mailer = new Mailer($settings);
$mailer->sendMail();

Then you can either have the Mailer copy all the values from the Settings class or keep the Settings class as a store for your values:

class Mailer {
    public function __construct(Settings $settings) {
        $this->companyName = $settings->get("companyName");
    }
    public function sendMail() {
        echo "Send mail to: " . $this->companyName;
    }
}

or

class Mailer {
    public function __construct(Settings $settings) {
        $this->settings = $settings;
    }
    public function sendMail() {
        echo "Send mail to: " . $this->settings->get("companyName");
    }
}

This approach allows you to put some validation in the constructor of Mailer to check if it has received all the Settings (by means of $settings->has("X")).

Upvotes: 2

ponciste
ponciste

Reputation: 2229

whether you're NOT doing anything in the mailing construct you can even miss it. Otherwise you have to call parent construct first and then write your code.

Example:

function __construct() {
    parent::_construct(); 

    // some code here
}

Upvotes: 0

Samy Massoud
Samy Massoud

Reputation: 4385

if you want to do it this way then you have to find a method to set company name at mail class , for example

class mailing extends settings {
function __construct($company_name) { $this->companyName = $company_name; }
function sendMail() {
    echo "Send mail to ".$this->companyName;
}
}

and this part of code should be

$settings = new settings();
$mailing = new mailing($settings->getCompanyName ());
$mailing->sendMail();

Upvotes: 0

Uriziel
Uriziel

Reputation: 177

You can just perform a simple trick with if statement in the constructor and constructor parameter stating if the script should load the data from DB or the data is already there and there is no need for that.

Upvotes: 0

MSadura
MSadura

Reputation: 1042

In your example $settings and $mailing are different instances so there is nor relation between them. If you don't want to call parent construct you can do something like this:

$settings = new settings();
$mailing = new mailing();
$mailing->companyName= $settings->companyName;
$mailing->sendMail();

Upvotes: 0

nxu
nxu

Reputation: 2272

You have to call parent::_construct(), otherwise the statements in the constructor of the settings class will not be run.

Constructor of the mailing class should look like this:

function __construct() {
    parent::_construct(); // General settings set by settings constructor
    // Mailing specific settings like already done in the current constructor
}

Upvotes: 0

Related Questions