0

我遇到以下问题:

<?php

/**
 * Mother class defining static methods/attribute
 */
class A
{
    public static $_greetings = 'Nothing';

    public static function hi()
        {
            $c = get_called_class();
            echo $c.' says '.$c::$_greetings.PHP_EOL;
        }

    public static function set($classname)
        {
            $c = get_called_class();
            $g = $classname::$_greetings;

            echo 'Setting '.$c.'::_greetings to '.$g.PHP_EOL;
            $c::$_greetings = $g;
        }
}

/**
 * Children using inherited static method
 */
class C1 extends A
{
    public function say() { self::hi(); }
}

class C2 extends A
{
    public function say() { self::hi(); }
}

/**
 * Data containers
 */
class D1
{
    public static $_greetings = 'Hello World!';
}

class D2
{
    public static $_greetings = 'Ola Chica!';
}

// ------------------------------------------------------------------------

/**
 * The great misunderstanding...
 */
C1::set( 'D1' );
C2::set( 'D2' );

$c1 = new C1();
$c2 = new C2();

$c1->say();
$c2->say();

echo C1::$_greetings.PHP_EOL;
echo C2::$_greetings.PHP_EOL;

简而言之A,定义了一种打印静态消息的方法$_greetings。此消息将使用A::set( classname )它来设置,它也接受包含静态参数的类的名称$_greetings。然后是两个孩子,他们定义了自己的方法say()来使用继承的 static 打招呼hi()。我希望输出是:

Setting C1::_greetings to Hello World!
Setting C2::_greetings to Ola Chica!
C1 says Hello World!
C2 says Ola Chica!
Hello World!
Ola Chica!

但相反,我得到:

Setting C1::_greetings to Hello World!
Setting C2::_greetings to Ola Chica!
C1 says Ola Chica!
C2 says Ola Chica!
Ola Chica!
Ola Chica!

我想了解为什么...!?非常感谢那些愿意花时间理解问题的人:)

4

1 回答 1

1

我可以在这里找到答案,即使问题的表述方式不同: PHP 5.3: Late static binding doesn't work for properties when defined in parent class while missing in child class

在我的小例子中,问题显然来自这样一个事实,除非另有说明(见下文如何),静态变量的存储对于“家庭”类(即,对于母类和所有子类)是相同的。为了确保每个类都有自己的存储空间,您只需要在子类中重新声明相同的静态变量,如下所示:

/**
 * Children using inherited static method
 */
class C1 extends A
{
    public static $_greetings;
    public function say() { self::hi(); }
}

class C2 extends A
{
    public static $_greetings;
    public function say() { self::hi(); }
}

将其放回到前面的示例中,输出完全符合预期:

Setting C1::_greetings to Hello World!
Setting C2::_greetings to Ola Chica!
C1 says Hello World!
C2 says Ola Chica!
Hello World!
Ola Chica!
于 2013-08-08T22:09:39.533 回答