正如您在下面看到的,我有一个超类(文章)和两个子类。我希望每个子类都有一个静态数组来保存它的所有对象。
abstract class Article
{
public static $articles = array(); // Variable for storing all the objects of each sub-class.
public function add_Object_To_Array()
{
array_push(self::$articles, $this);
}
}
class Report extends Article{}
class Interview extends Article{}
-创建两个 Report 对象并将它们添加到数组中:
$tmp = new Report();
$tmp->add_Object_To_Array();
$tmp = new Report();
$tmp->add_Object_To_Array();
-创建两个 Interview 对象并将它们添加到数组中:
$tmp = new Interview();
$tmp->add_Object_To_Array();
$tmp = new Interview();
$tmp->add_Object_To_Array();
print_r(Report::$articles);
print_r(Interview::$articles);
-上面的脚本吐出两个数组:
Array
(
[0] => Report Object()
[1] => Report Object()
[2] => Interview Object()
[3] => Interview Object()
)
Array
(
[0] => Report Object()
[1] => Report Object()
[2] => Interview Object()
[3] => Interview Object()
)
如果你问我,这看起来很相似,但第一个应该只包含报告,第二个应该只包含采访。
1。看起来只有一个数组,为什么只有一个数组?
2.我有一个同一类中的对象的静态容器,这是错误的编码吗? (有什么建议吗?)
我对 php 还很陌生,但有 java 背景。
所有内容都只进入一个数组,原因有两个:
$articles
属性仅在Article
类中定义。
如果您习惯了非静态属性,静态类属性的继承方式与您可能期望的方式不同。虽然它们可供子类使用,但它们仍然引用父类上的单个变量 - 导致您在这里看到的行为,其中两个子类共享相同的数组。
防止这种情况的唯一方法是在每个子类中定义一个单独的数组,如下所示:
class Report extends Article {
public static $articles = array();
}
class Interview extends Article {
public static $articles = array();
}
如果您将静态变量声明视为在定义类时运行的代码,那么这实际上是有意义的。创建静态变量并为其分配一个空数组是在定义
Article
类时发生的。当定义
Interview
和
Report
类时,不会再发生这种情况。只有一次会分配一个空数组 - 只有一个共享变量。
self
方法中使用
add_Object_To_Array()
而不是
static
。
self::
指的是它定义的类,因此由于您的
add_Object_To_Array()
方法是在
Article
类中定义的,因此它将引用
Article::$articles
数组。
static::
从 PHP 5.3 开始可用,指的是它被称为的类。这称为 后期静态绑定,并且将导致
add_Object_To_Array()
引用
Report::$articles
或
Interview::$articles
,具体取决于您调用它的对象的类型。
public function add_Object_To_Array() {
array_push(static::$articles, $this);
}
此解决方案使用 查找我们要存储的对象的类型,然后将其存储在父类中 - 以类名作为键的子数组中:
abstract class Article
{
public static $articles = array();
public function add_Object_To_Array()
{
// get the actual class of the current object
$class = get_class($this);
// define an empty subarray for this class if we haven't seen it before
if (!isset(self::$articles[$class])) {
self::$articles[$class] = array();
}
// add this object to the appropriate subarray
array_push(self::$articles[$class], $this);
}
}
class Report extends Article{}
class Interview extends Article{}
上面的代码不使用后期静态绑定,因此它适用于任何 PHP 版本,而不仅仅是 PHP 5.3+。
当您使用原始示例运行此版本时,您将得到如下输出:
Array
(
[Report] => Array
(
[0] => Report Object
(
)
[1] => Report Object
(
)
)
[Interview] => Array
(
[0] => Interview Object
(
)
[1] => Interview Object
(
)
)
)
如果您有 PHP 5.3 或更高版本,您可以进一步扩展并使用 函数来定义
getInstances()
静态方法(在
Article
类中),其工作方式如下:
public static function getInstances()
{
$class = get_called_class();
// return isset(self::$articles[$class]) ? self::$articles[$class] : array();
if (isset(self::$articles[$class])) {
return self::$articles[$class];
} else {
return array();
}
}
然后你可以在你的例子中调用这个方法,如下所示:
print_r(Report::getInstances());
print_r(Interview::getInstances());
static::
),但您还需要在每个子类中单独定义变量(这将使它们独立)。您可以使用这个:
abstract class Article
{
public static $articles = array();
public function add_Object_To_Array()
{
array_push(static::$articles, $this);
}
}
class Report extends Article{
public static $articles = array();
}
class Interview extends Article{
public static $articles = array();
}
然后当从每个子类调用add_Object_To_Array()
时,它会将文章存储在不同的位置。请参阅