2016-06-28 5 views
1

Kann man in einer Klasse __construct() magische Methode einen Wert setzen oder definieren, der danach nicht mehr geändert werden kann?Einen Wert im Konstruktor setzen oder definieren, der danach (zur Laufzeit) nicht geändert werden kann

Ich frage mich, ob es besser für die Lesbarkeit ist und im Falle von Skript-Injection-Angriffen, dass einige Werte wie Kundenrolle und db-Credits wie Klassenkonstanten behoben werden können. Nur in diesem Fall werden nach dem Login die Kundenrolle und sogar db-Credits definiert.

Antwort

1

Nein, das ist auf der Sprachstufe nicht möglich. An RFC submitted in late 2014 schlug vor, ein Schlüsselwort readonly hinzuzufügen, um eine Eigenschaft unveränderlich für Verbraucher zu machen. Die RFC hatte folgendes zu sagen:

Es gibt derzeit keine Möglichkeit, eine Eigenschaft lesbar für jedermann und beschreibbar nur auf das enthaltende Objekt zu machen, mit der PHP-Sichtbarkeitsbezeichner alles oder nichts erlaubt: Ein Bereich kann entweder sowohl lesen als auch schreiben oder nicht. Obwohl __get und __set existieren, erlauben diese nicht die Kontrolle der gleichen Eigenschaft, sondern nur die Aufdeckung einer separaten Eigenschaft, und sie sind nur für nicht deklarierte Eigenschaften verwendbar, die nicht reflektiert werden können und nicht performant sind.

Dennoch gibt es Entwicklungsmuster der Effekt, wie beispielsweise die Schaffung eines Wert zu erreichen Objekt verwenden, können die gewünschten Daten, die Daten selbst in private Eigenschaften mit nur „Getter“ Methoden sind zu halten. Beispiel:

class Credentials { 
    public function __construct($credentials) { 
     $this->credentials = $credentials; 
    } 
    public function getCredentials() { 
     return $this->credentials; 
    } 
    private $credentials; 
} 

Another way:

function credentials($initial = null) { 
    static $credentials = null; 
    if (null === $credentials) { 
     if (empty($initial)) { 
      throw new \LogicException('Need to initialize credentials'); 
     } else { 
      $credentials = $initial; 
     } 
    } 
    return $credentials; 
} 
echo credentials('first time'); // sets and returns value 
echo credentials(); // always returns initial set value 
echo credentials('second time'); // still echoes initial value 

Dies ist nicht sehr prüfbar, aber es erreicht das Ziel von "einstellbar nur einmal, nie veränderbar danach".

+0

Das sieht nach einer guten Lösung aus. Wäre es besser, die Klasse als final oder abstrakt zu definieren (und zu erweitern) und die Methoden als endgültig festzulegen? – Nitin

+0

'final' für Klasse oder Methode scheint sinnvoll. – bishop

+0

Diese Lösung löst das Problem nicht, aber es gibt keinen anderen Weg, wie in Ihrer Antwort gezeigt. Das Problem ist, dass die Klasseninstanz in einer Variablen gespeichert werden muss, die noch überschrieben werden kann. – Nitin

Verwandte Themen