Reputation: 3953
Assume we have the following class (simplified):
class SuperConfig {
public $mainDir;
public function setDir() {
$this->mainDir = "path/to/dir";
}
}
This class is supposed to be extended in EVERY other class in the project, and I do need the setDir()
function of the parent to be executed. Obviously, I could do it like this:
class A extends SuperConfig() {
public function __construct() {
parent::setDir();
}
// ... other stuff is about to be done ...
}
and I could access the properties in the child class like this:
class A extends SuperConfig {
public function doSomething() {
SuperConfig::mainDir;
}
}
This is a viable solution, but I got multiple hundreds of classes and doing this in every single one seems tedious. So, is there a way to do something like this:
class SuperConfig {
public $mainDir;
public function __extend() {
$this->setDir();
}
public function setDir() {
$this->mainDir = "path/to/dir";
}
}
__extend()
obviously doesn't work like that, but I'm wondering is there is a trick how I could make this work.
Upvotes: 0
Views: 41
Reputation: 2201
Read deceze's answer for an actual solution to your problem.
I would like to point out tho, that you should not extend every class in your project from a Config class. There are several ways how you could improve that.
1.) Create a static config class which you simply can call everywhere without the need of creation
class SuperConfig {
protected static $mainDir = null;
public static function setMainDir($dir) {
self::$mainDir = $dir;
}
}
2.) Create a trait rather then a parenting class.
trait SuperConfig {
protected $mainDir = null;
public function setMainDir($dir) {
$this->mainDir = $dir;
}
}
which you then can use inside your classes:
class XYZ {
use SuperConfig;
public function doSomething() {
$this->setMainDir('path/to/your/dir/');
}
}
Note that you can do that in the constructor too (which is kinda what you want).
Im not saying those two solutions are the best, but I dont like the thought of extending all classes from a config class. Just does not make much sence. Just imagine that you can only extend from one class per time, while you can use as many traits as you wish (and also have as many static classes as you need).
Upvotes: 1
Reputation: 75629
Well, in this particular case you just need:
class SuperConfig {
public $mainDir = "path/to/dir";
}
Upvotes: 0
Reputation: 14862
Put the constructor in the class that is being extended.
class SuperConfig {
public $mainDir;
public function __construct() {
$this->setDir();
}
public function setDir() {
$this->mainDir = "path/to/dir";
}
}
In any class that extends SuperConfig
, if they have a constructor also, be sure to include parent::__construct();
so that setDir
is called.
Upvotes: 1
Reputation: 522005
class SuperConfig {
public $mainDir;
public function __construct() {
$this->setDir(); // consider moving setDir's code here as well,
// unless you have a good reason for it to be a method
}
public function setDir() {
$this->mainDir = "path/to/dir";
}
}
You simply do this, and then you expect all subclasses to call the parent constructor if they're overriding the constructor:
public function __construct() {
parent::__construct();
// more code
}
It's perfectly reasonable to expect children to call their parent constructor, unless they deliberately want to leave the instance in an unknown and potentially broken state.
Upvotes: 2