【问题标题】:Finding out the type from an uninitialized typed property从未初始化的类型化属性中找出类型
【发布时间】:2021-12-03 16:31:06
【问题描述】:

我的User 类中有以下代码:

class User {
    
    public int $id = 0;
    public string $code;
    public string $name;
}

在从数据库中分配$code时,我需要找出var是什么类型才能分配它,所以我在__construct函数中为User使用gettype()

foreach($data as $key => $val) {
    settype($val, gettype($this->$key));
    $this->$key = $val;
}

但是它返回这个错误:

致命错误:未捕获的错误:类型化属性 User::$code 在初始化之前不得访问

我了解错误消息的含义。

有没有办法在变量被设置之前找出它的转换类型?

【问题讨论】:

  • 在设置值之前,变量实际上没有类型。
  • 不确定这种方法是否特别有用。这意味着具有特定数据的类必须不断检查它自己的数据类型——这是一个巨大的开销(恕我直言)。
  • @DonR 我看不出类型转换的意义,如果它在 __construct 没有类型但我已经声明了它,为什么我不能检查它是什么?跨度>
  • @NigelRen 您指的是哪种方法?
  • 所以,真正的问题是 PDO 为您提供了字符串。也许你应该解决这个问题?

标签: php oop


【解决方案1】:

我不确定你到底想做什么,而且在不了解整个事情的情况下,我不会冒险对它的逻辑发表意见。

暂且不说,在未初始化的类型属性上使用gettype() 是行不通的,因为此时该属性实际上没有任何价值。

但是,由于属性是类型化的,所以可以通过反射得到属性定义的类型:

class User {
    
    public int $id = 0;
    public string $code;
    public string $name;
    
    public function __construct() {
        
        $reflect = new ReflectionClass($this);
        $props   = $reflect->getProperties();
        foreach ($props as $prop) {
            echo $prop->getType()->getName(), "\n";            
        }

    }
}

new User();

以上将output:

int
string
string

动态执行此操作似乎需要很多开销,因此请确保没有更好的工具可供您使用。在__construct()方法上做这种事情,乍看之下并不十分明智,但我当然不知道你的具体限制。

【讨论】:

  • 啊,好吧,我不知道。谢谢。似乎有很多解决方法,尽管当他们可以让我在类型分配值之前检查它!
  • 否,因为在分配任何内容之前它没有类型。是uninitilized,与null 不同。您甚至可以说此时对象处于无效状态,因为属性没有与其声明类型匹配的值。再说一次,我不想对你正在尝试做的事情发表意见,因为我可以想象 可能 是这样的有效用例(尽管我猜它很少发生在类本身),但你正在尝试做的事情乍一看似乎有点复杂和冒险。
【解决方案2】:

如果你创建一个变量为

$foo;

那么就是null直到初始化成功,所以没有类型。

如果它是一个类型化的属性,那么它只是未初始化,而不是 null。 我的其余答案包含根据评论部分收到的信息进行的一些实验。因此,变量或属性在初始化之前是null,但类型化属性除外,它们只是未初始化。

在评论部分建议未初始化的变量不等于null。所以我写了这个测试代码:

<?php

$foo;
echo var_dump($foo === null);

并执行它

它给出警告并计算为true,因此未初始化的变量确实是null

由于yivi指出问题指的是一个属性,所以我又做了一个实验:

<?php

class Foo {
        public $foo;
        public function __construct() {
            echo var_dump($this->foo === null);
        }
}

new Foo();

结果是

【讨论】:

  • 这并不完全正确。已初始化的属性没有值null。这只是uninitialized。将其与 null 进行比较也会失败。
  • @yivi 你试过你的假设吗?我已经编写了一个测试代码并执行了它。结果意味着未初始化的变量确实是null,即使引用它会提示警告。我已将详细信息添加到我的答案中。
  • 问题是询问属性,而不是变量。使用 typed 属性再试一次。
  • 也许阅读整个问题会有所帮助。这些是问题所涉及的 TYPED 属性。你的例子不适合这个问题。
  • @yivi 你是对的。也试过了,结果表明你是对的。相应地编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-31
  • 2013-12-16
相关资源
最近更新 更多