【问题标题】:Extended classes and static values扩展类和静态值
【发布时间】:2012-07-14 17:23:28
【问题描述】:

我试图了解 PHP 如何在扩展类中使用静态方法管理内存和变量。我有三个类,一个名为 Model、User1、User2。因此:

class Model {
    static public $structure;
    static public $name;
    static function get_structure() {
        return self::$structure = file_get_contents(self::$name.'.json');
    }
}
class User1 extends Model {

}
class User2 extends Model {

}
User1::$name = 'User1';
User2::$name = 'User2';
echo User1::get_structure();
echo User2::get_structure();

如果我运行 User1::get_structure();由于某种原因,它没有相应地填充结果,它似乎正在获取 User2 的值(最后声明的 $name 值)。

我假设声明 User2 和扩展 Model 为我的 $name 属性创建了一个完全独立的范围。所以 User1 和 User2 被声明为与 Model 结构相同的单独类。然后我可以在不同的范围内为它们静态定义值。

然而,我现在对此提出质疑。如果我扩展并调用相同的 $name 变量,它们是否都指向 Model 类?或者当我用 new User1(); 声明每个类时,它是否只创建一个单独的范围?和 new User2();?

谢谢。

【问题讨论】:

  • 如果你使用的是静态类,那就不是 OOP。我正在删除标签。此外,模型是 layer,而不是类。

标签: php inheritance static


【解决方案1】:

你得到这个行为,因为你访问的是同一个变量

class X
{
    public static $data = null;
}

class Foo extends X{};
class Bar extends X{};

Foo::$data = 'lorem ipsum';
echo Bar::$data;
// :: output :: lorem ipsum;

您的 $name 变量始终与 Model 类绑定,即使在继承的类中也是如此。

【讨论】:

  • 非常好,这正好证实了我的想法。谢谢。
  • @pilotguy,我实际上建议您尽量避免使用静态变量。类中的静态变量类似于命名空间global。虽然语法发生了变化,但它们都具有与global state 相关的相同行为和相同问题。
【解决方案2】:

是的,所有扩展 Model 的类都将指向同一个 $name 变量。 将静态变量视为“全局”变量。

也许这个例子会让你明白:

class Model 
{
    static public $name;
}

class User1 extends Model 
{
    public function setName( $name )
    {
        parent::$name = $name;
    }

    public function getName()
    {
        return parent::$name;
    }
}

class User2 extends Model 
{
    public function setName( $name )
    {
        parent::$name = $name;
    }

    public function getName()
    {
        return parent::$name;
    }
}

$user1 = new User1();
$user1->setName("User1");

$user2 = new User2();
$user1->setName("User2");

echo $user1->getName();
echo $user2->getName();

// Output : User2User2

【讨论】:

    【解决方案3】:

    您可以通过以下方式解决它:

    <?php
    class Model {
        static public $structure;
        static public $name;
        static function get_structure() {
            $class = get_called_class();
            return $class::$structure = file_get_contents($class::$name.'.json');
        }
    }
    class User1 extends Model {
        static public $structure;
        static public $name;
    }
    class User2 extends Model {
        static public $structure;
        static public $name;
    }
    User1::$name = 'User1';
    User2::$name = 'User2';
    echo User1::get_structure();
    echo User2::get_structure();
    

    ...但是,您可能会问自己这个设计是否合适。例如 atm 看起来它们应该是具有单独值和实例方法的实例,但这可能是因为压缩示例。

    【讨论】:

    • 嗯,这是个好主意。我的目标是不强迫用户实例化模型层,直到他们绝对必须这样做。这是为了便于编码 + 我敢打赌我可以说它对性能也有好处。我正在考虑一个模型,它只是数据库的适配器......我返回的所有数据集都是指向模型的特定于框架的“记录”对象。
    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    • 2015-07-05
    相关资源
    最近更新 更多