当 trait 属性 被不同的值覆盖时的错误或功能

Bug or feature when trait property is overriden with different value

PHP manual中我们可以读到:

If a trait defines a property then a class can not define a property with the same name unless it is compatible (same visibility and initial value), otherwise a fatal error is issued. Before PHP 7.0.0, defining a property in the class with the same visibility and initial value as in the trait, raised an E_STRICT notice.

还有一个例子:

<?php
trait PropertiesTrait {
    public $same = true;
    public $different = false;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true; // Strict Standards
    public $different = true; // Fatal error
}
?>

让我们尝试一下,删除 $different 属性 并将不同的值设置为 $same 属性(在 PHP 7.1 中测试的所有内容)。

<?php
trait PropertiesTrait {
    public $same = true;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = 2;
}
?>

根据文档,它应该会导致致命错误,但实际上不会。但是,一旦我们将例如 true 更改为 false,它将再次导致致命错误。

它似乎并不完全按照文档中的描述工作 - 似乎有些转换是在比较之前进行的。然而,它可能会非常棘手,因为它可能会导致一些意想不到的行为,例如:

trait PropertiesTrait
{
    public $same = true;

    public function message()
    {
        if ($this->same === true) {
            return "A";
        }
        return "B";
    }
}

class PropertiesExample
{
    use PropertiesTrait;
    public $same = 2;
}

$example = new PropertiesExample();
echo $example->message();

在分析特征代码时,您会期望 message() 方法将 return A 因为根据文档不可能用不同的值覆盖此 属性 但是似乎是因为演员表,实际上是。

所以问题是 - 它是一个错误还是它可能是我们想要的工作方式,我们在哪里可以阅读 PHP 手册中关于 traits 属性的转换?

好像是bug。我已在此处报告:https://bugs.php.net/bug.php?id=74269

根据评论添加:

The conflict detection logic uses zend_operator's compare_function, which does loose comparisons. The original RFC doesn't say whether to be strict or loose but I think the intention is that it would be strict.