Ecco alcune possibili soluzioni alla mia domanda ispirate a questo risposta . Nella sua forma più pigra sembra così:
public function __construct ($propertyArray) {
foreach ($propertyArray as $property) {
$this->$property = $property;
}
}
Quindi si passano tutti gli argomenti come array e quindi il codice diventa uniforme e può essere ereditato da. Devi ancora scrivere manualmente l'elenco delle variabili protette poiché il seguente (purtroppo) non funziona:
foreach ($propertyArray as $property) {
protected $property; // or private $this->property
}
e sembra non esserci un modo semplice per aggirare :(.
Il vero problema qui, molto peggio di poche righe in più da digitare, è la conseguenza di errori di stampa, che possono portare alla creazione di proprietà private errate, mentre le proprietà corrette dell'array diventano pubbliche contro l'intenzione di dev.
Lo stesso problema colpisce in realtà anche il modo tradizionale originale.
Una soluzione parziale è usare il trucco ispirato alla risposta citata:
public function __construct ($propertyArray) {
foreach ($propertyArray as $property) {
$prefixedProperty = 'prefix' . ucfirst(strtolower($property));
$this->$prefixedProperty = $property;
}
}
Quindi nascondi la proprietà aggiungendo 'prefix'
al suo nome, la cosiddetta sicurezza per oscurità :). Ora la proprietà è ancora pubblica in caso di errore di stampa, ma speri di non colpirlo così facilmente. Ancora non al 100% a prova di proiettile.
Ora ecco la soluzione migliore che ho trovato:
class BulletProof {
protected $myProperty = '';
public function __construct ($propertyArray) {
foreach ($propertyArray as $property) {
if (! isset($this->$property) ) {
throw new exception("Careful, buddy! You either forgot or mistyped your declaration of $property!";
}
$this->$property = $property;
}
}
}
Quindi se hai fatto un errore di digitazione o hai dimenticato di dichiarare la variabile, il compilatore ti avvisa con un'eccezione! Per farlo funzionare, devi inizializzare tutte le tue variabili con qualcosa di diverso da null
, che non è troppo oneroso, dato che sono state sovrascritte dal costruttore.
Se qualcuno conosce un modo più elegante, sarei felice di imparare.
In un'altra nota sono grato a Yannis Rizos per i suoi suggerimenti nella chat privata, che implicano l'uso metodi magici __set
e __get
, sempre con la conseguenza che le proprietà diventano pubbliche.