如何防止在继承的类中共享静态变量? [英] How to prevent sharing of static variables in inherited classes?

查看:82
本文介绍了如何防止在继承的类中共享静态变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑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.phpProduct.php:

class User extends Model {
    protected $username;
    protected $password;
}
User::initialize();

class Product extends Model {
    protected $name;
    protected $price;
}
Product::initialize();

由于每个UserProduct将具有相同的$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::使用后期静态绑定,这怎么可能?以及如何解决这个问题?我的目标是让UserProduct具有独立的class_nametable_name,但仍希望同时保留两个变量 static 无需在每个模型上重新声明它们,无论是UserProduct还是其他任何模型!

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_nameModel::$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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆