在 PHP 7.4 中获取类型化属性的类型

我有一个DTO带类型的 PHP 变量:


class CreateMembershipInputDto extends BaseDto

{

    public bool $is_gift;

    public int $year;

    public string $name;

    public \DateTime $shipping_date;

    public ContactInputDto $buyer;

    public ?ContactInputDto $receiver;

}

我正在尝试制作某种自动映射器来填充属性,但是我需要检查变量的类型,但这似乎是不可能的。


class BaseDto

{

    public function __construct($json)

    {

        $jsonArray = json_decode($json, true);

        foreach($jsonArray as $key=>$value){

            $type = gettype($this->$key);

            if($type instanceof BaseDto)

                $this->$key = new $type($value);

            else

                $this->$key = $value;

        }

    }

}

ContactInputDto:


class ContactInputDto extends BaseDto

{

    public string $firstname;

    public string $lastname;

    public string $street_housenumber;

    public string $postal_code;

    public string $place;

    public string $country;

    public string $email;

    public string $phone;

}

是否有可能使该行"gettype($this->$key)"工作,而不会引发以下错误:


类型化属性 App\Dto\CreateMembershipInputDto::$is_gift 在初始化之前不得访问


繁花不似锦
浏览 147回答 1
1回答

白衣非少年

虽然该手册目前似乎没有记录它,但添加了一种方法ReflectionProperty来允许您获取类型。这实际上是在RFC 中为类型化属性指定的以下是您将如何使用它:class CreateMembershipInputDto extends BaseDto {    public bool $is_gift;    public int $year;    public string $name;    public \DateTime $shipping_date;    public ContactInputDto $buyer;    public ?ContactInputDto $receiver;}class BaseDto{    public function __construct($json)    {           $r = new \ReflectionClass(static::class); //Static should resolve the the actual class being constructed        $jsonArray = json_decode($json, true);        foreach($jsonArray as $key=>$value){            $prop = $r->getProperty($key);            if (!$prop || !$prop->getType()) { continue; } // Not a valid property or property has no type               $type = $prop->getType();            if($type->getName() === BaseDto::class) //types names are strings                $this->$key = new $type($value);            else                $this->$key = $value;        }    }}如果您想检查类型是否扩展BaseDto,您将需要(new \ReflectionClass($type->getName()))->isSubclassOf(BaseDto::class)注意getName指的是ReflectionNamedType::getName。在 PHP 8 之前,这是您可以获得的唯一可能的实例,$prop->getType()但是从 PHP 8 开始,您可能还会获得一个ReflectionUnionType包含多种类型的实例
打开App,查看更多内容
随时随地看视频慕课网APP