我和我正在编写的应用程序有this guy相同的问题。问题是静态属性不是在子类中继承的,所以如果我在我的主类中使用static ::关键字,它也会在我的主类中设置变量。
如果我重新声明我的子类中的静态变量,它可以工作,但我希望有大量的静态属性和子类,并希望避免代码重复。我链接的页面上排名靠前的响应有一些指向“解决方法”的链接,但它似乎有404个。任何人都可以借给我一些帮助,或者让我指出所说的解决方法吗?
答案 0 :(得分:6)
我不确定它在谈论什么具体的解决方法,我可以想到很多可行的方法。我个人不会在任何代码中使用这些。我建议你看看Is it possible to overuse late static binding in PHP?并重新考虑是否有更好的方法来做任何你希望完成的事情。
另外请记住,我的代码完全未经测试,就像我在这里写的那样。
所有其他方法都基于此。无论您使用静态属性,都可以插入代码来检测类并获取它。如果您从未计划在其他任何地方使用该物业,我只会考虑这一点。
$class = get_called_class();
if(isset(self::$_names[$class])) {
return self::$_names[$class];
}
else {
return static::NAME_DEFAULT;
}
如果您打算在不止一个地方使用它,这种方法会更好。一些单例模式使用类似的方法。
<?php
class SomeParent {
const NAME_DEFAULT = 'Whatever defaults here';
private static $_names = array();
static function getName($property) {
$class = get_called_class();
if(isset(self::$_names[$class])) {
$name self::$_names[$class];
}
else {
$name = "Kandy"; // use some sort of default value
}
}
static function setName($value) {
$class = get_called_class();
self::$_names[$class] = $value;
}
}
这是迄今为止最方便的方法。但是,您需要有一个对象实例才能使用它(__get和__set不能静态使用)。它也是最慢的方法(比其他两个慢得多)。我猜测,因为你已经在使用静态属性,所以这已经是一个非选择。 (如果这种方法适合你,那么如果不使用静态属性可能会更好)
<?php
class SomeParent {
const NAME_DEFAULT = 'Whatever defaults here';
private static $_names = array();
function __get($property) {
if($property == 'name') {
$class = get_called_class();
if(isset(self::$_names[$class])) {
return self::$_names[$class];
}
else {
return static::NAME_DEFAULT;
}
}
// should probably trigger some sort of error here
}
function __set($property, $value) {
if($property == 'name') {
$class = get_called_class();
self::$_names[$class] = $value;
}
else {
static::$property = $value;
}
}
}
答案 1 :(得分:0)
要比Reece45的答案更进一步,您可以使用以下方法获取数组的值。
<?php
class MyParent {
public static $config = array('a' => 1, 'b' => 2);
public static function getConfig() {
$ret = array();
$c = get_called_class();
do {
$ret = array_merge($c::$config, $ret);
} while(($c = get_parent_class($c)) !== false);
return $ret;
}
}
class MyChild extends MyParent {
public static $config = array('a' => 5, 'c' => 3, 'd' => 4);
public function myMethod($config) {
$config = array_merge(self::getConfig(), $config);
}
}
class SubChild extends MyChild {
public static $config = array('e' => 7);
}
var_export(MyChild::getConfig());
// result: array ( 'a' => 5, 'b' => 2, 'c' => 3, 'd' => 4, )
$mc = new MyChild();
var_export($mc->myMethod(array('b' => 6)));
// result: array ( 'a' => 5, 'b' => 6, 'c' => 3, 'd' => 4, )
var_export(SubChild::getConfig());
// result: array ( 'a' => 5, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 7, )
答案 2 :(得分:0)
对于那些最终想知道“WTF PHP”的人来说,这种行为似乎有几个原因以及为什么保留它,尽管很奇怪:
还有两个问题: