如何防止在继承的类中共享静态变量? [英] How to prevent sharing of static variables in inherited classes?
问题描述
考虑Model.php
:
class Model {
protected static $class_name;
protected static $table_name;
protected $id;
public static function initialize() {
static::$class_name = get_called_class();
static::$table_name = strtolower(static::$class_name).'s';
}
}
及其子级User.php
和Product.php
:
class User extends Model {
protected $username;
protected $password;
}
User::initialize();
class Product extends Model {
protected $name;
protected $price;
}
Product::initialize();
由于每个User
或Product
将具有相同的$class_name
和$table_name
,因此将它们设置为static
是有意义的.在子模型上调用initialize()
方法时(例如User::initialize();
和Product::initialize();
),将分配实际值.
Since every User
or Product
will have the same $class_name
and $table_name
, it makes sense to make them static
. The actual values are assigned when initialize()
method is called on the child model (e.g. User::initialize();
and Product::initialize();
).
我希望得到以下结果:
User -> $class_name -> 'User', $table_name -> 'users'
Product -> $class_name -> 'Product', $table_name -> 'products'
但是我得到以下信息:
User -> $class_name -> 'User', $table_name -> 'users'
Product -> $class_name -> 'User', $table_name -> 'users'
鉴于我正在对static::
使用后期静态绑定,这怎么可能?以及如何解决这个问题?我的目标是让User
和Product
具有独立的class_name
和table_name
,但仍希望同时保留两个变量 static
无需在每个模型上重新声明它们,无论是User
,Product
还是其他任何模型!
How is this possible given that I am using late static binding with static::
? And how can this be fixed? My goal is for User
and Product
to have independent class_name
and table_name
, but still keep both variables static
, hopefully without redeclaring them on each model, be it User
, Product
or any other!
推荐答案
调用Product::initialize
时,将Model::$class_name
设置为"Product"
,将Model::$table_name
设置为"products"
.调用User::initialize
时,Model::$class_name
和Model::$table_name
被"User"
和"users"
覆盖.
When Product::initialize
is called, Model::$class_name
is set to "Product"
and Model::$table_name
to "products"
. When User::initialize
is called, Model::$class_name
and Model::$table_name
are overwritten with "User"
and "users"
.
如果那些属性是在子类中定义的,则initialize中的static只会有所作为.
The static in initialize would only make a difference, if those attributes were defined in the sub classes.
问题的第二部分,您回答了自己,要么重新声明它们,要么使它们变为非静态.
The second part of your question you answered yourself, either redeclare them or make them non-static.
修改
您可以将地图与访问器结合使用,以伪造子类本地继承的静态属性(我希望我对此做了补充).
You could use a map in combination with accessors to fake sub-class local inherited static properties (I hope I just made that up).
class Foo {
private static $class_names = [];
private static $table_names = [];
public static function getClassName() {
return self::$class_names[static::class];
}
public static function getTableName() {
return self::$table_names[static::class];
}
public static function initialize() {
self::$class_names[static::class] = static::class;
self::$table_names[static::class] = strtolower(static::class).'s';
}
}
class Bar extends Foo {
}
Bar::initialize();
class Baz extends Foo {
}
Baz::initialize();
echo Bar::getTableName() . " " . Bar::getClassName() . "\n";
echo Baz::getTableName() . " " . Baz::getClassName() . "\n";
可悲的是,声明动态静态属性在PHP 7中不起作用.
Declaring dynamic static properties does sadly not work in PHP 7.
这篇关于如何防止在继承的类中共享静态变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!