How do i deal with multiple contructor arguments or class variables?


How do I know what to load in a constructor and what to set using the set methods later on?

For example, I have a question class which most of the time will call the following vars:

protected $question; protected $content; protected $creator; protected $date_added; protected $id; protected $category;

At the moment I have it so only the bare essentials $id, $question, and $content are set in the constructor so I don't start building up a huge list of constructor arguments. This however, means that when I make a new question object elsewhere, I have to set the other properties of that object straight after meaning 'setter code' getting duplicated all over the place.

Should I just pass them all into the constructor right away, do it the way I'm doing it already, or is there a better solution that I'm missing? Thanks.


Depending on the language you can have multiple constructors for any one class.


You could use an array as the parameter to the constructor or setter method.

Just example:

public function __construct($attributes = array()) { $this->setAttributes($attributes); } public function setAttributes($attributes = array()) { foreach ($attributes as $key => $value) { $this->{$key} = $value; } }


PHP doesn't support traditional constructor overloading (as other OO languages do). An option is to pass an array of arguments into the constructor:

public function __construct($params) { } // calling it $arr = array( 'question' => 'some question', 'content' => ' some content' ... ); $q = new Question($arr);

Using that, you're free to pass a variable number of arguments and there is no dependency on the order of arguments. Also within the constructor, you can set defaults so if a variable is not present, use the default instead.


I would pass an array to the constructor with the values I want to set.

public function __construct(array $values = null) { if (is_array($values)) { $this->setValues($values); } }

Then you need a method setValues to dynamicly set the values.

public function setValues(array $values) { $methods = get_class_methods($this); foreach ($values as $key => $value) { $method = 'set' . ucfirst($key); if (in_array($method, $methods)) { $this->$method($value); } } return $this; }

For this to work you need setter methods for your properties like setQuestion($value) etc.


A fluent interface is another solution.

class Foo { protected $question; protected $content; protected $creator; ... public function setQuestion($value) { $this->question = $value; return $this; } public function setContent($value) { $this->content = $value; return $this; } public function setCreator($value) { $this->creator = $value; return $this; } ... } $bar = new Foo(); $bar ->setQuestion('something') ->setContent('something else') ->setCreator('someone');

Or use inheritance...

class Foo { protected $stuff; public function __construct($stuff) { $this->stuff = $stuff; } ... } class bar extends Foo { protected $moreStuff; public function __construct($stuff, $moreStuff) { parent::__construct($stuff); $this->moreStuff = $moreStuff; } ... }

Or use optional parameters...

class Foo { protected $stuff; protected $moreStuff; public function __construct($stuff, $moreStuff = null) { $this->stuff = $stuff; $this->moreStuff = $moreStuff; } ... }

In any case, there are many good solutions. Please dont use a single array as params or func_get_args or _<em>get/</em>_set/__call magic, unless you have a really good reason to do so, and have exhausted all other options.


  • In WPF,MVVM should ViewModel be involved in opening a window, e.g. About-window?
  • declaring device constant in terms of another constant
  • Objective C difference between self.variable and variable assignments
  • How to add an object in my collection by only using add method? [closed]
  • Why is new Number(8) not exactly equal to 8?
  • Validity Method for Reference Classes
  • Using an enum contained in a Cloud Endpoint model on a Android client
  • Validation fired but Red Border does not appear with User Control in Silverlight 4
  • custom string delimiters stringtemplate-4
  • What's wrong with my datatrigger binding?
  • NUnit 3.0 TestCase const custom object arguments
  • What does 'Language neutral' mean with regard to MAKELANGID?
  • jQuery ready not fired after rails link_to is clicked
  • Android activity accessing service's static reference before the service is ready
  • Do I need to reset a Perl hash index?
  • Yii2: Config params vs. const/define
  • Switching to Release Build causes runtime error in Web Reference
  • Algorithm for a smudge tool?
  • How to access EntityManager inside Entity class in EJB3
  • Repeat a vertical line on every page in Report Builder / SSRS
  • Android screen density dpi vs ppi
  • Bug in WPF DataGrid
  • Excel - Autoshape get it's name from cell (value)
  • Check if a string to interpolate provides expected placeholders
  • Rearranging Cells in UITableView Bug & Saving Changes
  • RestKit - RKRequestDelegate does not exist
  • Traverse Array and Display in markup
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • log4net write single file for each call to log.info
  • Benchmarking RAM performance - UWP and C#
  • Acquiring multiple attributes from .xml file in c#
  • Angular 2 constructor injection vs direct access
  • Why joiner is not used after Sequence generator or Update statergy
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • File not found error Google Drive API
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • How can I remove ASP.NET Designer.cs files?
  • Is it possible to post an object from jquery to bottle.py?
  • java string with new operator and a literal