2014-10-29 118 views
0

写一些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被定义为公共;因为我想有保护(这只是为了好看)我绊了一个错误致命错误:无法访问受保护的财产B :: $ VAR在...上线5

为什么这种情况发生在这种情况下, ? T1 :: a1是否将范围更改为“课外”?

+0

“我想要保护(只是为了使它很好)”大声笑! – foxygen 2014-10-29 19:48:37

+0

如果你在'T2'的'a2()'中返回$ this-> a1();'''相同的结果? – Rudie 2014-10-29 19:49:41

+0

对不起,你在这里构建'$ b'的代码? (或者修复你的代码,使之成为$ a,我假设你打算这样做,或者引入$ b的声明和初始化) – 2014-10-29 19:49:42

回答

2

您正在直接调用特性的静态方法。从来不是一个好主意。

除了类中的use语句外,不应该使用特征名称。

如果你打电话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(); 
+0

好吧,从来没有一个好主意,但它会很高兴听到一些解释,为什么 – Yang 2014-10-29 19:57:25

+1

PHP文档说:特质是一种“复制”和“建立类的粘贴机制”。在编译器之外它们不存在。你不能检测方法来自哪里,哪些特征已经被加载等。它们只是用来构造类。这就是为什么你不应该在别的地方使用它们。 – Rudie 2014-10-29 20:01:52

1

如果您使用的特质,不要把他们当作静态类。不要使用

function a2() { return T1::a1(); } 

但简单地使用:

function a2() { return $this->a1(); } 

如果你打电话给他们,如果他们是静态类功能$this变成一个无意义的关键字和a1()将不知道你想什么当你打$this->var