我现在正在编写的应用程序和这个人有同样的问题。问题是子类中没有继承静态属性,因此如果我在主类中使用 static:: 关键字,它也会在我的主类中设置变量。
如果我在子类中重新声明静态变量,它会起作用,但我希望有大量的静态属性和子类,并希望避免代码重复。我链接的页面上评分最高的响应有一个指向一些“解决方法”的链接,但它似乎有 404'd。谁能给我一些帮助,或者指出我所说的解决方法的方向?
我现在正在编写的应用程序和这个人有同样的问题。问题是子类中没有继承静态属性,因此如果我在主类中使用 static:: 关键字,它也会在我的主类中设置变量。
如果我在子类中重新声明静态变量,它会起作用,但我希望有大量的静态属性和子类,并希望避免代码重复。我链接的页面上评分最高的响应有一个指向一些“解决方法”的链接,但它似乎有 404'd。谁能给我一些帮助,或者指出我所说的解决方法的方向?
我不确定它在谈论什么具体的解决方法,我能想到很多可行的方法。我个人不会在任何代码中使用这些。我建议您看一下是否有可能在 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;
}
}
}
比 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, )