Php 为什么我突然得到一个“a”;在初始化之前,不能访问类型化属性";引入属性类型提示时出错?
我已经更新了类定义,以使用新引入的属性类型提示,如下所示:Php 为什么我突然得到一个“a”;在初始化之前,不能访问类型化属性";引入属性类型提示时出错?,php,doctrine-orm,php-7,type-hinting,php-7.4,Php,Doctrine Orm,Php 7,Type Hinting,Php 7.4,我已经更新了类定义,以使用新引入的属性类型提示,如下所示: class-Foo{ 私人国际货币单位; 私有?字符串$val; 私有DateTimeInterface$createdAt; private?DateTimeInterface$updatedAt; 公共函数构造(int$id){ $this->id=$id; } 公共函数getId():int{return$this->id;} 公共函数getVal():?字符串{return$this->val;} 公共函数getCreatedA
class-Foo{
私人国际货币单位;
私有?字符串$val;
私有DateTimeInterface$createdAt;
private?DateTimeInterface$updatedAt;
公共函数构造(int$id){
$this->id=$id;
}
公共函数getId():int{return$this->id;}
公共函数getVal():?字符串{return$this->val;}
公共函数getCreatedAt():?DateTimeInterface{return$this->createdAt;}
公共函数getUpdatedAt():?DateTimeInterface{return$this->updatedAt;}
公共函数setVal(?string$val){$this->val=$val;}
公共函数setCreatedAt(DateTimeInterface$date){$this->createdAt=$date;}
公共函数setUpdatedAt(DateTimeInterface$date){$this->updatedAt=$date;}
}
但当我试图在条令上保存我的实体时,我得到了一个错误,即:
在初始化之前,不能访问类型化属性
这不仅发生在
$id
或$createdAt
上,也发生在$value
或$updatedAt
上,它们是可为空的属性。由于PHP7.4为属性引入了类型提示,因此为所有属性提供有效值尤为重要,因此,所有属性都具有与其声明的类型匹配的值
从未分配过的属性没有null
值,但它处于未定义的状态,将永远不会与任何声明的类型匹配<代码>未定义!==空
对于上述代码,如果您执行了以下操作:
$f = new Foo(1);
$f->getVal();
你会得到:
致命错误:未捕获错误:初始化之前不能访问类型化属性Foo::$val
因为$val
在访问它时既不是字符串
也不是空值
解决这个问题的方法是为所有与声明的类型匹配的属性赋值。根据您的首选项和特性类型,可以将其作为特性的默认值或在构造过程中执行
例如,对于上述情况,可以执行以下操作:
class-Foo{
私人国际货币单位;
private?字符串$val=null;//id=$id;
$this->createdAt=new DateTimeImmutable();
$this->updatedAt=new DateTimeImmutable();
$this->collection=newarraycollection();
}
现在,所有属性都将有一个有效的值,并且实例将处于有效状态
当您依赖来自DB的值作为实体值时,这种情况可能会特别频繁。例如,自动生成的ID,或创建和/或更新的值;这通常是DB关注的问题
对于自动生成的ID,将类型声明更改为:
private ?int $id = null
对于所有其他属性,只需为属性的类型选择一个合适的值。对于可为null的类型化属性,您需要使用语法
private?字符串$val=null代码>
否则会抛出一个致命错误
由于这个概念会导致不必要的致命错误,我创建了一个bug报告,但没有成功,但至少我尝试了…a),这已经在另一个答案中介绍过了。b) 那不是虫子。那是精心设计的。如果一个属性除了定义的类型之外还可能包含一个null
,那么您需要对其进行明确说明。我希望这样的报告会立即被拒绝。换句话说,自PHP 7.4以来,类型提示类成员存在空安全性。您好,如果Livewire指示的变量是模型绑定属性怎么办<代码>公共用户$User我试图在save()
中使用它,我试图这样做:$this->user->save()代码>,它表示在初始化之前不能访问它。如果我将model属性上的users值设置为null,则会抛出另一个错误。