考虑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();
)。
我希望最终得到以下结论:
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
,但仍保留两个变量 { {1}} ,希望无需在每个模型上重新声明,无论是static
,User
还是其他任何内容!
答案 0 :(得分:0)
调用Product::initialize
时,Model::$class_name
设置为"Product"
,Model::$table_name
设置为"products"
。调用User::initialize
后,Model::$class_name
和Model::$table_name
将被"User"
和"users"
覆盖。
初始化中的static只会产生差异,如果这些属性是在子类中定义的。
你自己回答问题的第二部分,要么重新声明它们,要么使它们成为非静态的。
修改强>
您可以将地图与访问器结合使用来伪造子类本地继承的静态属性(我希望我只是这样做了)。
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中,声明动态静态属性确实不起作用。
答案 1 :(得分:-1)
阅读接受的答案后,我有了使用classCallerContainer的解决方法。
class ParentClass{
protected static $container = [];
protected static function setIndependentProperty($string){
//# stored the the caller class as the bank
static::$container[get_called_class()] = $string;
}
protected static function getIndependentProperty(){
//# collect the value in container base on the caller class
return static::$container[get_called_class()] ?? "";
}
}