Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请教一下,关于单例模式是只有controller下才会有的问题,还是任何一个类都会有这个问题? #441

Open
euii opened this issue May 8, 2023 · 5 comments
Labels
question Further information is requested

Comments

@euii
Copy link

euii commented May 8, 2023

我现在手里有一个旧的系统,我想改造它,系统中有一个Repository目录,这里面几乎所有的类都使用了类似的代码

class GeoCityRepository extends Base
{
    protected $geoCity;

    public function __construct()
    {
        parent::__construct();
        $this->geoCity = new GeoCity;
    }
}

我在常见问题文档中说controller挂在router下,router是单例所以controller里的__construct只走一次,我的疑问是运行在cli模式下是否所有的类都不能用上述形式的代码,还是仅仅是controller里不能使用上述形式的代码?

@hhxsv5
Copy link
Owner

hhxsv5 commented May 8, 2023

任何单例类都可能有问题,你需要保证每个单例类不能存储用户请求级别的数据,如用户ID。
不然会出现用请求A的数据实例化了单例类,请求B就会读到请求A的的单例对象,数据就串了,在登录态验证、权限校验时影响非常严重。

@hhxsv5 hhxsv5 added the question Further information is requested label May 8, 2023
@euii
Copy link
Author

euii commented May 9, 2023

任何单例类都可能有问题,你需要保证每个单例类不能存储用户请求级别的数据,如用户ID。 不然会出现用请求A的数据实例化了单例类,请求B就会读到请求A的的单例对象,数据就串了,在登录态验证、权限校验时影响非常严重。

那将这些使用单例的接口全部配置到cleaner里是不是就可以解决这个问题?

@hhxsv5
Copy link
Owner

hhxsv5 commented May 9, 2023

Controller的单例:配置destroy_controllers
ServiceProvider的单例:配置register_providers
其他的单例:编写自定义Cleaner,继承自BaseCleaner

@euii
Copy link
Author

euii commented May 9, 2023

Controller的单例:配置destroy_controllers ServiceProvider的单例:配置register_providers 其他的单例:编写自定义Cleaner,继承自BaseCleaner

谢谢你的答复,我现在的情况是属于其它单例,继承BaseCleaner,实现function clean() ,关于clean()代码是要forgetinstance就可以了吗?还是有其它的实现逻辑?我不太清楚移除单例的基本逻辑是否就是将实例unset掉,然后再次访问的时候发现这个类的实例没有就会重新new出,一个常规的类使用以下类似的代码,对吗?

 $this->currentApp->forgetInstance('url');
        Facade::clearResolvedInstance('url');

@hhxsv5
Copy link
Owner

hhxsv5 commented May 11, 2023

对,清理单例的逻辑就是将实例置为null,这样每次请求就会重新初始化。实质就是保证单例的作用范围是请求内,而不是请求间。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants