Como faço para lidar com vários argumentos de construtor ou variables ​​de class?

Como eu sei o que carregar em um construtor e o que definir usando os methods estabelecidos mais tarde?

Por exemplo, eu tenho uma aula de perguntas que na maioria das vezes chamará as seguintes séries:

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

No momento, eu tenho assim que apenas os itens essenciais $id , $question e $content são definidos no construtor para que eu não comece a criar uma enorme lista de argumentos do construtor. Isso, no entanto, significa que quando eu faço um novo object de pergunta em outro lugar, eu tenho que definir as outras propriedades desse object diretamente após o significado de ‘código de setter’ ser duplicado em todo o lugar.

Devo simplesmente passar todos eles no construtor, faça o jeito que eu já estou fazendo, ou há uma solução melhor que eu estou perdendo? Obrigado.

Dependendo do idioma, você pode ter vários construtores para qualquer class.

Você pode usar uma matriz como o parâmetro para o método construtor ou setter.

Apenas exemplo:

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

O PHP não suporta a sobrecarga do construtor tradicional (como fazem outras linguagens OO). Uma opção é passar uma série de argumentos no construtor:

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

Usando isso, você é livre para passar um número variável de argumentos e não há dependência na ordem dos argumentos. Também dentro do construtor, você pode definir padrões, portanto, se uma variável não estiver presente, use o padrão em vez disso.

Eu passaria uma matriz para o construtor com os valores que eu quero definir.

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

Então você precisa de um método setValues para configurar dinamicamente os 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 isso funcione, você precisa de methods de setter para suas propriedades, como setQuestion($value) etc.

Uma interface fluente é outra solução.

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

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

Ou use parâmetros opcionais …

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

De qualquer forma, existem muitas boas soluções. Por favor, não use uma única matriz como params ou func_get_args ou _ get / _set / __ call magic, a menos que você tenha uma ótima razão para fazê-lo e esgotou todas as outras opções.