我有以下PHP代码:
trait Trait1 {
private $secret; // I want this to be only accessible in Trait1 and not in Foo
public function getSecret() {
return $this->secret;
}
public function setSecret($secret) {
$this->secret = $secret;
}
}
class Foo {
use Trait1;
public function foo() {
return $this->secret; // This returns the $secret in Trait1
}
}
$foo = new Foo();
$foo->setSecret("My secret!");
echo $foo->foo();
以上代码输出"My secret"
我希望函数foo()
无法运行$this->secret
(换句话说,返回运行时错误)。但遗憾的是,它使用Trait1
中的私有变量。
我不喜欢这种行为的原因是,如果我意外地拥有一个共享相同变量名的重叠私有变量;如果你不知道你覆盖了私有变量,它可能会导致问题。
例如:
trait Trait1 {
private $secret;
public function getTraitSecret() {
return $this->secret;
}
public function setTraitSecret($secret) {
$this->secret = $secret;
}
}
class Foo {
use Trait1;
private $secret; // same variable name as in Trait1
public function setFooSecret($secret) {
$this->secret = $secret;
}
public function getFooSecret() {
return $this->secret;
}
}
$foo = new Foo();
$foo->setTraitSecret("Trait secret!");
echo $foo->getTraitSecret(); // returns "Trait secret" as expected and wanted
echo $foo->getFooSecret(); // unfortunately also returns "Trait secret"
$foo->setFooSecret("Inner secret!");
echo $foo->getTraitSecret(); // unfortunately returns inner secret
echo $foo->getFooSecret(); // returns "Inner secret" as expected and wanted
以上代码输出类似于:
Trait secret!
Trait secret!
Inner secret!
Inner secret!
这个问题有一个很好的解决方案吗?
答案 0 :(得分:2)
https://secure.php.net/manual/en/language.oop5.traits.php
如果特征定义了属性,则类无法定义具有相同名称的属性,否则会发出错误。如果类定义兼容(相同的可见性和初始值)或其他致命错误,则为E_STRICT。
所以这不是一种正确的方法。
答案 1 :(得分:0)
此问题的一个潜在解决方案是在特征中设置$secret
的值,以便它不能在类Foo
中使用。
e.g。
trait Trait1 {
private $secret = null;
public function getTraitSecret() {
return $this->secret;
}
public function setTraitSecret($secret) {
$this->secret = $secret;
}
}
现在,以下内容将返回错误:
class Foo {
use Trait1;
private $secret; // ERROR
...
}
这样,就不可能意外地分享'与生成致命错误的变量相同。
对两个变量使用相同的值只会导致警告。