1

PHP 手册中,我们可以阅读:

如果一个特征定义了一个属性,那么一个类不能定义一个具有相同名称的属性,除非它是兼容的(相同的可见性和初始值),否则会发出致命错误。在 PHP 7.0.0 之前,在类中定义一个与 trait 具有相同可见性和初始值的属性,会引发 E_STRICT 通知。

还有一个例子:

<?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;
}
?>

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

它似乎与文档中描述的不完全一样 - 似乎在比较之前进行了一些演员表。然而,它可能非常棘手,因为它可能导致一些意想不到的行为,例如:

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()方法将返回A,因为根据文档不可能用不同的值覆盖此属性,但似乎是因为强制转换实际上是这样。

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

4

1 回答 1

1

这似乎是错误。我在这里报告过: https ://bugs.php.net/bug.php?id=74269

根据评论补充:

冲突检测逻辑使用 zend_operator 的 compare_function,它进行松散比较。最初的 RFC 没有说是严格还是宽松,但我认为其意图是严格。

于 2017-03-18T21:12:34.170 回答