PHP 5.2中的类继承:如何在扩展类中覆盖静态变量?

11
我需要能够使用一个静态变量,该变量在继承基类的类中设置...从基类中访问。

考虑以下代码:
class Animal {
    public static $color = 'black';

    public static function get_color()
    {
        return self::$color;
    }
}

class Dog extends Animal {
    public static $color = 'brown';
}

echo Animal::get_color(); // prints 'black'
echo Dog::get_color(); // also prints 'black'

由于它使用了延迟静态绑定,所以在PHP 5.3.x中(Dog::get_color()打印出'brown')这个方法运行的很好。但是我的生产服务器运行的是PHP 5.2.11, 所以我需要调整我的脚本。

是否有一种相对简单的解决方法来解决这个问题?

谢谢!
Christoffer

编辑:目标

正如下面所述,这是我试图完成的一个非常简化的例子。如果我向您提供了我用来解决问题的两个选项(以及问题本身),那么有人可能会有不同的解决方案......

我构建了一个基础数据库模型,其中包含函数"find"、"find_by"和"find_all"(所有的函数都是静态的)。

在PHP 5.3中,有一个名为get_called_class()的函数,我目前使用它来确定被调用类的名称,然后使用它来映射到正确的数据库表。例如,类User将指向users

get_called_class()在PHP 5.2.x中不存在,我找到的“hack”实现非常不可靠。然后我转向这个在所有模型类中都包含类名的静态变量的选项。


1
我假设 Dog 应该继承 Animal - Richard JP Le Guen
1
根据进一步的解释,我认为您应该将find/find by函数作为表类的方法而不是行类上的静态方法(这似乎是您正在尝试的方法)。 - gnarf
Gnarf:是的,这也是我昨晚想出来的。它不太美观,但可以用。 - Christoffer
3个回答

9

当我在Zend框架中对某些东西进行子类化时,遇到了这个问题。我的结论是,在纯静态的情况下,您只有一种选择……在继承类中重新定义该函数:

class Animal {
    public static $color = 'black';

    public static function get_color()
    {
        return self::$color;
    }
}

class Dog extends Animal {
    public static $color = 'brown';

    public static function get_color() 
    {
      return self::$color;
    }
}

如果您能够创建实例 - 您可以使用 get_class($this) 来查找调用的类,例如:
class Animal {
    public static $color = 'black';

    public function getColor() // note, not static
    {
      $class = get_class($this);
      return $class::$color;
    }
}

class Dog extends Animal {
    public static $color = 'brown';
}

$animal = new Animal();
echo $animal->getColor(); // prints 'black'
$dog = new Dog();
echo $dog->getColor(); // prints 'brown'

我想到的另一个选项是在静态函数中使用函数参数来定义调用它的类。它可以默认为__CLASS__,然后你可以从子类中 return parent::get_class($class)。这样的模式可以用于使重用静态函数更加容易(因为我怀疑返回公共静态属性不是你在那个静态方法中尝试使用self::的唯一事情):

class Animal {
    public static $color = 'black';

    public static function get_color($class = __CLASS__)
    {
        // Super Simple Example Case... I imagine this function to be more complicated
        return $class::$color;
    }
}

class Dog extends Animal {
    public static $color = 'brown';

    public static function get_color($class = __CLASS__)
    {
      return parent::get_color($class);
    }
}

1
谢谢你的回答。它在我提供的例子中有效,但实际情况要复杂得多。我编辑了我的帖子告诉你我真正想做什么,希望可能会有与我尝试过的不同的角度。 - Christoffer

5
在 PHP 5.3+ 中,以下代码被推荐使用:
class Animal {
    public static $color = 'black';

    public static function get_color()
    {
        return static::$color; // Here comes Late Static Bindings
    }
}

class Dog extends Animal {
    public static $color = 'brown';
}

echo Animal::get_color(); // prints 'black'
echo Dog::get_color(); // prints 'brown'

静态延迟绑定(PHP.net)


2

遗憾的是,在PHP 5.3之前,没有办法模拟后期静态绑定。你所能做到的只有将它们作为实例变量和方法来使用,这样才能使继承按照你的意愿工作。


这意味着我不能使用静态方法来创建对象本身? - Christoffer
1
不,如果你依赖于存储在子类中的静态数据,那就不行。 - VoteyDisciple

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接