प्रॉपर्टीज के प्रकारों का परिचय देते समय मुझे अचानक "टाइप की गई संपत्ति को आरंभीकरण से पहले एक्सेस नहीं किया जाना चाहिए" त्रुटि क्यों हो रही है?


10

मैंने अपनी कक्षा की परिभाषाओं को इस तरह से प्रस्तुत नई संपत्ति के संकेत का उपयोग करने के लिए अद्यतन किया है:

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

लेकिन जब मैं सिद्धांत पर अपनी इकाई को बचाने की कोशिश कर रहा हूं तो मुझे एक त्रुटि मिल रही है:

आरंभीकरण से पहले टाइप की गई संपत्ति तक पहुँचा नहीं जाना चाहिए

यह न केवल के साथ होता है $idया $createdAt, लेकिन यह भी साथ हो $valueया $updatedAt, जो नल गुण हैं।

जवाबों:


20

चूंकि PHP 7.4 संपत्तियों के लिए टाइप-हिंटिंग का परिचय देता है, इसलिए सभी संपत्तियों के लिए मान्य मान प्रदान करना विशेष रूप से महत्वपूर्ण है, ताकि सभी गुणों में ऐसे मान हों जो उनके घोषित प्रकारों से मेल खाते हों।

एक चर जिसे कभी नहीं सौंपा गया है, का कोई nullमूल्य नहीं है , लेकिन यह एक ऐसी undefinedस्थिति पर है, जो किसी भी घोषित प्रकार से मेल नहीं खाएगाundefined !== null

उपरोक्त कोड के लिए, यदि आपने किया था:

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

आपको मिलेगा:

घातक त्रुटि: अनकवर्ड एरर: टाइप की गई संपत्ति Foo :: $ val को आरंभीकरण से पहले एक्सेस नहीं किया जाना चाहिए

चूँकि इसे एक्सेस करना $valन तो है stringऔर न ही null

इसके आस-पास जाने का तरीका आपके सभी गुणों को मान निर्दिष्ट करना है जो घोषित प्रकारों से मेल खाते हैं। आप इसे अपनी प्राथमिकता और संपत्ति के प्रकार के आधार पर संपत्ति के लिए या निर्माण के दौरान डिफ़ॉल्ट मान के रूप में कर सकते हैं।

उदाहरण के लिए, ऊपर आप कर सकते हैं:

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();
    }

अब सभी संपत्तियों का एक वैध मूल्य होगा और उदाहरण एक वैध स्थिति पर होगा।

यह विशेष रूप से अक्सर तब मारा जा सकता है जब आप उन मूल्यों पर निर्भर होते हैं जो इकाई मूल्यों के लिए DB से आते हैं। उदाहरण के लिए स्वतः-निर्मित आईडी, या निर्माण और / या अपडेट किए गए मान; जिसे अक्सर एक DB चिंता के रूप में छोड़ दिया जाता है।

स्वतः-जनरेट की गई आईडी के लिए, अनुशंसित तरीका आगे की घोषणा प्रकार को बदलने के लिए है ?int $id = null। बाकी सभी के लिए, संपत्ति के प्रकार के लिए उचित मूल्य चुनें।


-5

मेरी त्रुटि:

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

मेरा समाधान - कक्षा में अगली विधि जोड़ें:

public function __sleep()
{
    return [];
}

1
कृपया प्रश्न को ठीक से पढ़ें, फिर प्रश्न के आधार पर उत्तर दें, न कि पूरी तरह से आपकी समस्या / समाधान पर आधारित हो।
मशीगारगढ़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.