Warum erhalte ich plötzlich den Fehler "Auf typisierte Eigenschaften darf vor der Initialisierung nicht zugegriffen werden", wenn ich Hinweise zum Typ der Eigenschaften eingebe?

10

Ich habe meine Klassendefinitionen aktualisiert, um die neu eingeführten Hinweise zum Eigenschaftstyp wie folgt zu verwenden:

class Foo {

    private int $id;
    private ?string $val;
    private DateTimeInterface $createdAt;
    private ?DateTimeInterface $updatedAt;

    public function __construct(int $id) {
        $this->id = $id;
    }


    public function getId(): int { return $this->id; }
    public function getVal(): ?string { return $this->val; }
    public function getCreatedAt(): ?DateTimeInterface { return $this->createdAt; }
    public function getUpdatedAt(): ?DateTimeInterface { return $this->updatedAt; }

    public function setVal(?string $val) { $this->val = $val; }
    public function setCreatedAt(DateTimeInterface $date) { $this->createdAt = $date; }
    public function setUpdatedAt(DateTimeInterface $date) { $this->updatedAt = $date; }
}

Aber wenn ich versuche, mein Wesen auf Doctrine zu retten, erhalte ich die Fehlermeldung:

Auf typisierte Eigenschaften darf vor der Initialisierung nicht zugegriffen werden

Dies geschieht nicht nur mit $idoder $createdAt, sondern auch mit $valueoder $updatedAt, die nullbare Eigenschaften sind.

Yivi
quelle

Antworten:

20

Da PHP 7.4 Typhinweise für Eigenschaften einführt, ist es besonders wichtig, gültige Werte für alle Eigenschaften bereitzustellen, damit alle Eigenschaften Werte haben, die ihren deklarierten Typen entsprechen.

Eine Variable, die noch nie zugewiesen wurde, hat keinen nullWert, befindet sich jedoch in einem undefinedStatus, der niemals mit einem deklarierten Typ übereinstimmt . undefined !== null.

Für den obigen Code, wenn Sie Folgendes getan haben:

$f = new Foo(1);
$f->getVal();

Sie würden bekommen:

Schwerwiegender Fehler: Nicht erfasster Fehler: Auf die typisierte Eigenschaft Foo :: $ val darf vor der Initialisierung nicht zugegriffen werden

Da $valist weder stringnoch nullbeim Zugriff darauf.

Um dies zu umgehen, weisen Sie allen Ihren Eigenschaften Werte zu, die den deklarierten Typen entsprechen. Sie können dies entweder als Standardwerte für die Eigenschaft oder während der Erstellung tun, abhängig von Ihren Vorlieben und dem Typ der Eigenschaft.

Zum Beispiel könnten Sie Folgendes tun:

class Foo {

    private int $id;
    private ?string $val = null; // <-- declaring default null value for the property
    private DateTimeInterface $createdAt;
    private ?DateTimeInterface $updatedAt;

    public function __construct(int $id) {
        // and on the constructor we set the default values for all the other 
        // properties, so now the instance is on a valid state
        $this->id = $id;
        $this->createdAt = new DateTimeImmutable();
        $this->updatedAt = new DateTimeImmutable();
    }

Jetzt hätten alle Eigenschaften einen gültigen Wert und die Instanz wäre in einem gültigen Zustand.

Dies kann besonders häufig auftreten, wenn Sie sich für Entitätswerte auf Werte verlassen, die aus der Datenbank stammen. ZB automatisch generierte IDs oder Erstellung und / oder aktualisierte Werte; die oft als DB-Anliegen übrig bleiben.

Für automatisch generierte IDs wird empfohlen, die Typdeklaration in zu ändern ?int $id = null. Für den Rest wählen Sie einfach einen geeigneten Wert für den Typ der Eigenschaft.

Yivi
quelle
-5

Mein Fehler:

"Typed property Proxies\\__CG__\\App\\Entity\\Organization::$ must not be accessed before initialization (in __sleep)"

Meine Lösung - fügen Sie der Klasse die nächste Methode hinzu:

public function __sleep()
{
    return [];
}
Lebnik
quelle
1
Bitte lesen Sie die Frage genau durch und beantworten Sie sie dann anhand der Frage, nicht vollständig anhand Ihres Problems / Ihrer Lösung.
MAChitgarha