【问题标题】:Get type of typed property in PHP 7.4在 PHP 7.4 中获取类型化属性的类型
【发布时间】:2019-12-05 06:32:50
【问题描述】:

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

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 在初始化之前不得访问

【问题讨论】:

    标签: php php-7.4


    【解决方案1】:

    虽然该手册目前似乎没有记录它,但ReflectionProperty 中添加了一种方法,可让您获取类型。这实际上是在RFC for typed properties中指定的

    您将如何使用它:

    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

    【讨论】:

      猜你喜欢
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 2020-01-29
      • 2015-07-28
      • 2020-07-27
      • 2021-07-16
      • 1970-01-01
      相关资源
      最近更新 更多