无法访问 trait 中的受保护属性

3

正在编写一些 PHP 代码。经过调试,我将我的优秀行为减少到以下代码:

trait T1 {
     function a1() { return $this->var; }
}
trait T2 {
     use T1;
     function a2() { return T1::a1(); }
}
class A {
     use T2;
     protected $var = 3;
}

$a = new A;
echo $a->a2();

只要A类中的$var被定义为public,这段代码就能正常工作;但是我想将其定义为protected(只是为了美观),却遇到了一个错误 Fatal error: Cannot access protected property B::$var in ... on line 5

为什么会出现这种情况?T1::a1是否会进行作用域更改以使其“在类外”?


“我想要将它保护起来(只是为了让它更好看)”哈哈! - foxygen
T2中,如果您在a2()中返回$this->a1();,结果是否相同? - Rudie
我不确定为什么,但这个可以工作:http://3v4l.org/iOFSt 可能是属性名称var,或者对a1()的静态调用。使用var作为属性名称也可以:http://3v4l.org/TNcVA - Rudie
感谢大家的提示。在不使用 :: 运算符的情况下,示例确实有效,但对于我更复杂的项目则无效。肯定是有其他问题。通过编写“use x as y”并更改特征包含的顺序和位置来解决了这个问题。抱歉,我无法确定我犯了什么错误。 - 000
顺便提一下:使用 :: 运算符来访问 parent:: 等时,它有点像“按规定”,用于访问特定实例。在 trait 上下文中,我似乎有些误解了 ;) - 000
显示剩余2条评论
2个回答

7

你正在直接调用trait的静态方法,这不是一个好主意。

除了在类中的use语句中,你不应该在任何地方使用trait名称。

如果你将a1()作为$this的方法调用,它可以正常工作:http://3v4l.org/TNcVA

trait T1 {
    function a1() {
        return $this->var;
    }
}
trait T2 {
    use T1;
    function a2() {
        return $this->a1();
    }
}
class A {
    use T2;
    protected $var = 3;
}

$a = new A;
echo $a->a2();

好的,这不是一个好主意,但听一下为什么会很好。 - Yang
1
PHP文档称:traits是一种“复制粘贴机制,用于构建类”。在编译器之外,它们不存在。您无法检测方法来自哪里,加载了哪些traits等。它们只用于构造类。这就是为什么您不应该在其他地方使用它们的原因。 - Rudie

1
如果您正在使用 traits,请不要将它们视为静态类。不要使用。
function a2() { return T1::a1(); }

但只需使用:
function a2() { return $this->a1(); }

如果将它们称为静态类功能,则$this变成一个无意义的关键字,当你使用$this->var时,a1()将不知道你要做什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接