PHP - 使用无法通过 using class 访问的变量创建特征
PHP - Creating a trait with variables that cannot be accessed by the using class
问题
我有以下 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
(换句话说 return 一个 运行 时间错误)。然而不幸的是,它使用了 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!
解决方案?
这个问题有好的解决办法吗?
这个问题的一个潜在解决方案是在特征中为 $secret
设置一个值,这样它就不能在 class Foo
.
中使用
例如
trait Trait1 {
private $secret = null;
public function getTraitSecret() {
return $this->secret;
}
public function setTraitSecret($secret) {
$this->secret = $secret;
}
}
现在下面会return一个错误:
class Foo {
use Trait1;
private $secret; // ERROR
...
}
这样,就不可能意外地 'share' 同一个变量,因为它会产生致命错误。
对两个变量使用相同的值可能只会导致警告。
https://secure.php.net/manual/en/language.oop5.traits.php
If a trait defines a property then a class can not define a property with the same name, otherwise an error is issued. It is an E_STRICT if the class definition is compatible (same visibility and initial value) or fatal error otherwise.
所以这不是一个正确的方法。
问题
我有以下 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
(换句话说 return 一个 运行 时间错误)。然而不幸的是,它使用了 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!
解决方案?
这个问题有好的解决办法吗?
这个问题的一个潜在解决方案是在特征中为 $secret
设置一个值,这样它就不能在 class Foo
.
例如
trait Trait1 {
private $secret = null;
public function getTraitSecret() {
return $this->secret;
}
public function setTraitSecret($secret) {
$this->secret = $secret;
}
}
现在下面会return一个错误:
class Foo {
use Trait1;
private $secret; // ERROR
...
}
这样,就不可能意外地 'share' 同一个变量,因为它会产生致命错误。
对两个变量使用相同的值可能只会导致警告。
https://secure.php.net/manual/en/language.oop5.traits.php
If a trait defines a property then a class can not define a property with the same name, otherwise an error is issued. It is an E_STRICT if the class definition is compatible (same visibility and initial value) or fatal error otherwise.
所以这不是一个正确的方法。