扩展类和静态值
我想了解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和扩展模型为我的$ name属性创建一个完全独立的作用域。因此,User1和User2被声明为具有与Model相同结构的独立类。然后我可以在不同的范围内为它们静态地定义它们的值。
但我现在在质疑。如果我扩展并调用相同的$ name变量,它们是否都指向Model类?或者当我使用新的User1()声明每个类时,它只创建一个单独的范围;和新的User2();?
谢谢。
你遇到这个问题,因为你正在访问相同的变量
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 2012-07-14 17:53:43
@pilotguy,我实际上会建议你尽量避免使用静态变量。类中的静态变量就像命名空间'global'一样。虽然语法已更改,但它们具有与[全局状态](http://www.youtube.com/watch?v=-FRm3VPhseI)相关的相同行为和相同问题。 – 2012-07-14 17:58:36
你可以解决它:
<?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它看起来像它们应该是具有不同值的实例&实例方法,但这可能是因为精简的例子。
嗯,这是一个不错的主意。我的目标是不要强制用户实例化模型层,直到他们必须完成。这是为了便于编码+我敢打赌,我可以争辩说,它对性能也很好。我正在考虑一个模型只是一个适配器到数据库......我所有返回的数据集都是指向模型的特定于框架的“记录”对象。 – pilotguy 2012-07-15 12:46:08
是的,所有延伸型号的类都将指向相同的$ 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
如果使用的是静态类,它不是面向对象编程。我正在移除标签。此外,模型是[层](http://stackoverflow.com/a/5864000/727208),而不是一个类。 – 2012-07-14 17:37:17
... rriigghhtt。好吧。 – pilotguy 2012-07-14 17:42:08