问题 PHP 5.2中的类继承:覆盖扩展类中的静态变量?


我需要能够在从基类扩展基类的类中使用静态变量集。

考虑一下:

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() 打印'棕色'),因为它具有后期静态绑定。但我的生产服务器运行PHP 5.2.11,所以我需要调整我的脚本。

有没有一个相当漂亮的解决方法来解决这个问题?

干杯!
克里斯托弗

编辑:目标

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

我已经构建了一个基础数据库模型,其中包含“find”,“find_by”和“find_all”(所有静态)等函数。

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

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


10003
2018-06-10 19:31


起源

我假设 Dog 应该延长 Animal? - Richard JP Le Guen
你是绝对正确的 :) - Christoffer
通过进一步的解释,我认为你应该把你的find / find by函数作为方法放在一个表类而不是静态的行类上(这听起来像你正在尝试 - gnarf
Gnarf:是的,这也是我昨晚深夜所想出的。它不是那么漂亮,但它会做。 - Christoffer


答案:


遗憾的是,在PHP 5.3之前,没有办法模拟后期静态绑定。如果那些是实例变量和方法,那么你可以让继承按你的意愿工作的唯一方法。


2
2018-06-10 19:36



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


我在Zend Framework中继承了一些东西时遇到了这个问题。我的决心是,在纯粹的静态土地上,你只有一个选项......在继承类中重新定义函数:

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);
    }
}

9
2018-06-10 19:45



谢谢您的回答。它适用于我提供的示例,但实际情况要复杂得多。我编辑我的帖子告诉你我真正想做的事情,希望可能会有与我尝试过的角度非常不同的角度。 - Christoffer


在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)


5
2017-09-01 20:44