¿Cómo trato con múltiples argumentos contructor o variables de clase?

¿Cómo sé qué cargar en un constructor y qué establecer usando los métodos set más adelante?

Por ejemplo, tengo una clase de pregunta que la mayoría de las veces llamará a los siguientes valores:

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

Por el momento lo tengo, así que solo los elementos esenciales $id , $question y $content se configuran en el constructor, por lo que no empiezo a crear una lista enorme de argumentos de constructor. Sin embargo, esto significa que cuando hago un nuevo objeto de pregunta en otro lugar, tengo que establecer las otras propiedades de ese objeto inmediatamente después de que el ‘código del setter’ se duplique por todas partes.

¿Debo pasarlos todos al constructor de inmediato, hacerlo de la manera en que lo estoy haciendo ya, o hay una solución mejor que me estoy perdiendo? Gracias.

Dependiendo del idioma, puede tener múltiples constructores para cualquier clase.

Puede usar una matriz como parámetro para el método constructor o setter.

Solo ejemplo:

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

PHP no admite la sobrecarga de constructores tradicional (como lo hacen otros lenguajes OO). Una opción es pasar una matriz de argumentos al constructor:

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

Con eso, puedes pasar una cantidad variable de argumentos y no hay dependencia en el orden de los argumentos. También dentro del constructor, puede establecer los valores predeterminados, de modo que si una variable no está presente, use el valor predeterminado.

Pasaría una matriz al constructor con los valores que quiero establecer.

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

Entonces necesita un método setValues para establecer dinámicamente los valores.

 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; } 

Para que esto funcione, necesitas métodos setter para tus propiedades como setQuestion($value) etc.

Una interfaz fluida es otra solución.

 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'); 

O usa herencia …

 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; } ... } 

O usa parámetros opcionales …

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

En cualquier caso, hay muchas buenas soluciones. Por favor, no utilices una sola matriz como params o func_get_args o _ get / _set / __ call magic, a menos que tengas una buena razón para hacerlo y hayas agotado todas las otras opciones.