请教在webman中关于单例的疑问

oscar

实际需求:在控制器中需要对当前访问者进行权限判断。权限内容保存在磁盘文件中data.db,文件容量大概1MB。
目前做法:因为也只有几个路径需要进行判断,没有使用中间件,而是在基类中使用beforeAction来执行判断。

//权限判断伪代码
class AbcUtil
{
    private static $instance  =  null;
    private static $db = null;
    private function __construct(){
        self::$db = file_get_contents('data.db');
        echo 'init';
    }
    private function __clone() {}
    public static function getInstance(){
            if(!(self::$instance instanceof self)){
                self::$instance = new self();
            }
            return self::$instance;
    }

    public  function check($a){
        //TODO .....
    }
}

//基类Base中beforeAction使用
Base.php
public function beforeAction(Request $request){
    AbcUtil::getInstance()->check($request);
}

A extends Base {
    a(){}
    b(){}
}

B extends Base {
    c(){}
    d(){}
}

依次执行控制器中的方法:
a()会打印init
b()不打印
c()打印init
d()不打印
a()不打印
b()不打印

我的疑问是,单例不是全局中只有一个实例么?上面多次打印init就是进行了多次实例化,因为初始化要从磁盘上读取文件内容,这样会不会有性能问题?
我想实现的是应用启动后只进行一次资源读取,后面只从内存读取,感觉我上面的做法不太合理。资源初始化应该在哪里进行呢?

谢谢大家不吝指教!

212 2 0
2个回答

2548a

我不知道你怎么测试的,单例是只执行一次,但是不代表进程只有一个,10个进程就会有10个单例,如果你通过访问控制器的话,不代表它进入的是同一个进程,自然就会执行初始化了.

  • oscar 2022-05-17

    啊!!一语点醒梦中人!我怎么没想到是进程这个问题呢。同问,是每个进程里都有一个相同的单例吗?@liziyu

liziyu

不懂就问:是每个进程里都有一个相同的单例吗?

  • 2548a 2022-05-17

    进程就相当于干活的人数,每个人干的活都是一样的,但是他们的大脑都是独立的,也就是里面的数据是不跟其它人共享的.所以也就会出现你上面说的,a进程实例化了,等会安排到b进程干活了,它又会再实例化一次,因为a的数据跟它没有关系

  • oscar 2022-05-17

    很形象,我算是明白了。非常感谢!

  • liziyu 2022-05-17

    看来我猜中了一点点,谢谢大佬指点。

🔝