tags:

views:

41

answers:

1

Hey, everyone. I couldn't find anything Googling this problem, and I've found really good answers to some questions on SO before, so I'm taking this excuse to join the community.

I'm creating a hierarchy of classes for a PHP project I'm working on, and I'd like to have some variables in the classes initialized within the constructor function without explicitly writing the initialization code. Specifically I want to have the interpreter assume that some of the variables are actually pointers to a certain class. If I could do something like C structs, that would be pretty close to what I want.

So far, the only thing I came up with is to explicitly state the variable type within its own name and have the class call an initializing function on each, like;

class A{
  ...
}

class B{
  var $x_A;

  function initVar($var){
    list($varname, $vartype) = split('_',$var);
    $this->$var = new $vartype();
  }

}

And B's constructor calls initVar on all of its get_class_vars(get_class($this)), so anything that inherits from it will do initialization in the same way; obviously including a check on the variable name, a check that the class exists, and a better separation scheme than a single underscore. I just cannot help but think that there is a better way to do this that isn't hardcoding the initialization into the construction function.

If anyone knows of a better way to do this, your help would be much appreciated.

A: 

Your method there would probably work, however it could get very tiresome to actually use it. For example, imagine having to reference those variables all the time:

$myObject->account_ServiceAccountType

If you really wanted to go with something like this, perhaps a mapping variable might be useful:

class B {
    public $x, $account;

    private $map = array(
        'x' => 'A',
        'account' => 'ServiceAccountType'
    );

    public function __construct() {
        foreach ($this->map as $var => $class) {
            $this->$var = new $class;
        }
    }
}

You could also try this method out. It uses PHP's magic __get function.

class B {
    private $map = array(
        'x' => 'A',
        'account' => 'ServiceAccountType'
    );
    private $vars;
    public function __construct() {
        $this->vars = array();
        foreach ($this->map as $var => $class) {
            $this->vars[$var] = new $class;
        }
    }

    public function __get($v) {
        return $this->vars[$v];
    }
}

Notice that you don't need to define the class members twice using this method.

nickf
Thank you for your response! I think mapping might be a good solution, but I can't think of how to do it without redefining the map for every derived class; but in that case, why not just add `$x = new A()` and `$account = new ServiceAccountType()` in the constructor itself?
Loyal Tingley
@Loyal - well yeah, those are exactly my thoughts. I have another idea which may help though... see the forthcoming edit.
nickf
I like magic __get for this, too, I think I'll go along those lines. Thanks :)
Loyal Tingley