Ich arbeite an einem Framework, das ich versuche so stark wie möglich zu schreiben. (Ich arbeite mit PHP und nehme einige der Ideen, die ich von C# mag, und versuche, sie in diesem Rahmen zu verwenden.) Ich erstelle eine Collection-Klasse, die eine Sammlung von Domain-Objekten/-Objekten ist. Es ist irgendwie nach dem List<T>
Objekt in .Net modelliert.PHP 'instanceof' schlägt mit der Klassenkonstante fehl
Ich bin auf ein Hindernis gestoßen, das mich daran hindert, diese Klasse zu tippen. Wenn ich eine UserCollection habe, sollte sie nur User-Objekte zulassen. Wenn ich eine PostCollection habe, sollte es nur Post-Objekte erlauben.
Alle Sammlungen in diesem Framework müssen bestimmte grundlegende Funktionen wie Hinzufügen, Entfernen, Iterieren haben. Ich habe eine Schnittstelle erstellt, aber festgestellt, dass ich Folgendes nicht tun konnte:
interface ICollection { public function add($obj) }
class PostCollection implements ICollection { public function add(Post $obj) {} }
Dies brach seine Übereinstimmung mit der Schnittstelle. Aber ich kann die Schnittstelle nicht stark typisieren, weil dann alle Collections vom selben Typ sind. Also habe ich versucht, die folgenden:
interface ICollection { public function add($obj) }
abstract class Collection implements ICollection { const type = 'null'; }
class PostCollection extends Collection {
const type = 'Post';
public function add($obj) {
if(!($obj instanceof self::type)) {
throw new UhOhException();
}
}
}
Wenn ich versuche, diesen Code auszuführen, erhalte ich syntax error, unexpected T_STRING, expecting T_VARIABLE or '$'
auf der instanceof
Aussage. Ein wenig Forschung in das Problem und es sieht aus wie die Wurzel der Ursache ist $obj instanceof self
ist gültig, um gegen die Klasse zu testen. Es scheint, dass PHP nicht die gesamte self::type
Konstantenanweisung im Ausdruck verarbeitet. Hinzufügen von Klammern um den self::type
Variable warfen einen Fehler in Bezug auf einem unerwarteten ‚(‘.
Ein offensichtliches Problem zu umgehen, die type
Variable eine Konstante nicht zu machen ist. Der Ausdruck $obj instanceof $this->type
funktioniert gut (wenn $type
als Variable deklariert wird, natürlich)
Ich hoffe, dass es eine Möglichkeit gibt, das zu vermeiden, da ich den Wert als Konstante definieren möchte, um mögliche Änderungen in der Variablen später zu vermeiden.Jede Gedanken darüber, wie ich das erreichen kann, oder habe ich PHP in dieser Hinsicht an seine Grenzen gebracht? Gibt es eine Möglichkeit, self::this
zu "entkommen" oder einzukapseln, so dass PHP bei der Verarbeitung nicht stirbt?
UPDATE Basierend auf dem Feedback unten dachte ich an etwas zu versuchen - der Code unten funktioniert! Kann irgendjemand an 1) einen Grund denken, dies nicht zu tun, 2) einen Grund, warum dies letztlich nicht funktionieren wird, oder 3) einen besseren Weg, dies zu schaffen?
interface ICollection { public function add($obj) }
abstract class Collection { const type = null; protected $type = self::type; }
class PostCollection extends Collection {
const type = 'Post';
public function add($obj) {
if(!($obj instanceof $this->type)) {
throw new UhOhException();
}
}
}
UPDATE # 2: Nach den obigen Code in Produktion setzen, stellt sich heraus, es funktioniert nicht. Ich habe keine Ahnung, wie es funktioniert hat, als ich es getestet habe, aber es funktioniert überhaupt nicht. Ich bin mit der Verwendung einer protected
Variable fest, denke ich.
ich glaube, ich antwortete 1 oder 2 - obwohl t Die Variable ist "geschützt", sie kann im Code noch geändert werden. Es gibt keine echte Sicherheit dafür, dass die Variable $ type nicht versehentlich geändert wird. Was ich mir erhofft hatte, war eine Versicherung dagegen. –
Wenn ich richtig verstehe, geben Sie der instanceof-Operation eine Zeichenfolge ($ this-> type), wenn es nur ein Klassenname sein sollte (siehe http://php.net/manual/en/language.operators.type.php) . Ich denke, Sie sollten stattdessen "is_a" verwenden, da dies eine Zeichenfolge erwartet, die $ this-> type ist. – gacrux
Keine wahre Aussage - sehen Sie sich Beispiel 5 auf der Seite an, mit der Sie verlinkt sind. –