I can think of two ways of doing that. If you want to keep your instance variables you can just iterate through the array passed to the constructor and set the instance variable dynamically:? Php class Foo { private $_type = 'default_type'; private $_width = 100; private $_interactive = true; function __construct($args){ foreach($args as $key => $val) { $name = '_' .
$key; if(isset($this->{$name})) { $this->{$name} = $val; } } } }? When using the array approach you don't really have to abandon documentation. Just use the @property annotations in the class body:?
Php /** * @property string $type * @property integer $width * @property boolean $interactive */ class Foo { private $_instance_params = array( 'type' => 'default_type', 'width' => 100, 'interactive' => true ); function __construct($args){ $this->_instance_params = array_merge_recursive($this->_instance_params, $args); } public function __get($name) { return $this->_instance_params$name; } public function __set($name, $value) { $this->_instance_params$name = $value; } }? That said, a class with 50 member variables is either only used for configuration (which can be split up) or it is just doing too much and you might want to think about refactoring it.
I can think of two ways of doing that. If you want to keep your instance variables you can just iterate through the array passed to the constructor and set the instance variable dynamically: $val) { $name = '_' . $key; if(isset($this->{$name})) { $this->{$name} = $val; } } } }?
> When using the array approach you don't really have to abandon documentation. Just use the @property annotations in the class body: 'default_type', 'width' => 100, 'interactive' => true ); function __construct($args){ $this->_instance_params = array_merge_recursive($this->_instance_params, $args); } public function __get($name) { return $this->_instance_params$name; } public function __set($name, $value) { $this->_instance_params$name = $value; } }? > That said, a class with 50 member variables is either only used for configuration (which can be split up) or it is just doing too much and you might want to think about refactoring it.
I like both of your approaches, and hadn't really thought through that I would be accessing the member variables using $this and so could programatically access them. Does isset() return true if the variable is declared but not assigned a value (I'm not even sure if that makes sense in PHP). I'm just thinking - what if I don't have a default for a certain value (e.g. : private $_foo;)?
– Tom Auger May 11 at 17:25 I would assign null to these. That way you can check for if(isset($this->{$name}) || $this->{$name} === null)... – Daff May 11 at 17:41 Just to be clear then, if I were to implement your method 1 above, I must assign some kind of value when declaring the class properties? Ie: private $foo = null; and must avoid private $foo;?
I thought isset() returned false if the value were null, and I thought declaring a member variable without assigning it a value assigned it null? – Tom Auger May 11 at 19:45 2 private $foo = null; and private $foo; is exactly the same and isset will return false. Use property_exists if you want to check if you defined the property in your class at all.
– Daff May 11 at 20:31 Thanks for all the great info Daff – Tom Auger May 117 at 14:34.
Another approach is to instantiate the class with a FooOptions object, acting solely as an options container: _options = $options; } } class FooOptions { private $_type = 'default_type'; private $_width = 100; private $_interactive = true; public function setType($type); public function getType(); public function setWidth($width); public function getWidth(); // ... } Your options are well documented and you have an easy way to set/retrieve them. This even facilitates your testing, as you can create and set different options objects. I don't remember the exact name of this pattern, but I think it's Builder or Option pattern.
This actually sounds more like a Model pattern. I'm not sure your suggestion actually works well unless you define an interface (can PHP do that? ) IFooOptions and then have the API user implement that interface in a MyOptions class, or extend that class (eg: MyFooOptions extends FooOptions) and pass an instance of that to the Foo constructor.
This could work if the user is only instantiating Foo a handful of times. In situations where the user is creating many many instances of this class, and the parameters may need to be dynamically set, it becomes very awkward. – Tom Auger May 11 at 17:48 Yeah, PHP can define interfaces in the same way as classes: interface IFooInterface.
Surely this method has its weaknesses and makes users life harder, but you get a well-defined API with your class options. Maybe for your case this is not the best option... :) – Luiz Damim May 11 at 19:26.
You also could make a parent class. In that class you only define the variables. Protected function _SetVarName( $arg ){ $this->varName=$arg; } Then extend that class into a new file and in that file you create all your processes.So you get classname.vars.
Php classname. Php classname extends classnameVars { } Because most will be on default you only have to Set/Reset the ones you need. $cn=new classname(); $cn->setVar($arg); //do your functions..
Just to follow up with how I implemented this, based on one of Daff's solutions: function __construct($args = array()){ // build all args into their corresponding class properties foreach($args as $key => $val) { // only accept keys that have explicitly been defined as class member variables if(property_exists($this, $key)) { $this->{$key} = $val; } } } Improvement suggestions welcomed!
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.