【问题标题】:Class inheritance in PHP 5.2: Overriding static variable in extension class?PHP 5.2 中的类继承:覆盖扩展类中的静态变量?
【发布时间】:2011-03-02 08:37:51
【问题描述】:

我需要能够使用在类中设置的静态变量,该类从基类扩展基类...。

考虑一下:

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 实现非常不可靠。然后我转向在所有包含类名的模型类中使用静态变量的选项。

【问题讨论】:

  • 我认为Dog 应该扩展Animal
  • 随着进一步的解释,我认为你应该把你的 find/find by 函数作为方法放在一个表类上,而不是放在一个行类上(这听起来像是你正在尝试的)跨度>
  • Gnarf:是的,这也是我昨晚想出来的。它不那么漂亮,但它会做。

标签: php inheritance


【解决方案1】:

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

Late Static Bindings (PHP.net)

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 感谢您的回答。它在我提供的示例中有效,但实际情况要复杂得多。我编辑我的帖子来告诉你我真正想做的事情,希望可能会有与我尝试过的完全不同的角度。
    【解决方案3】:

    遗憾的是,在 PHP 5.3 之前,无法模拟后期静态绑定。让继承按预期工作的唯一方法是这些是实例变量和方法。

    【讨论】:

    • 这意味着我不能使用静态方法自己创建对象?
    • 如果您依赖存储在子类中的静态数据,则不会。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多