法尔孔中的单例组件是真正的单例吗?


Is a singleton component in phalcon a real singleton?

让我声明一个问题:
据我所知,当请求结束时,php将清除它创建的对象和其他数据。

但正如Phalcon的文件所说:
"服务可以注册为"共享"服务,这意味着它们将始终充当单例。一旦服务首次解析,每次使用者从容器中检索服务时,都会返回相同的实例"。

<?php
//Register the session service as "always shared"
$di->set('session', function() {
    //...
}, true);

我想知道的是:在创建共享组件后,在下一个请求时,phalcon 会重用共享组件吗?我的意思是 phalcon 不会创建新的组件实例。

对于DI:setShared()和您的示例,是的,它将满足单例的条件。相反,如果您DI::set(..., ..., false)它将在每次DI::get(...)创建新实例 - 除非您使用 DI::getShared() 检索它时,什么将根据派生闭包创建新实例并将其保存到DI以备将来使用 - 但您总是需要DI::getShared()如下所示:

// not shared
$di->set('test', function() {
    $x = new 'stdClass();
    $x->test1 = true;
    return $x;
}, false);
// first use creates singletonized instance
$x = $di->getShared('test');
$x->test2 = true; // writing to singleton
// retrieving singletoned instance
var_dump($di->getShared('test'));
// getting fresh instance
var_dump($di->get('test'));
// despite of previous ::get(), still a singleton
var_dump($di->getShared('test'));

和概念验证:

object(stdClass)[25]
  public 'test1' => boolean true
  public 'test2' => boolean true
object(stdClass)[26]
  public 'test1' => boolean true
object(stdClass)[25]
  public 'test1' => boolean true
  public 'test2' => boolean true

为了证明您创建了多少个实例,我建议在服务中声明析构函数以显示一些输出。无论如何,PHP使用了一些东西,在某些情况下可能会在请求结束后保留 - 例如打开的SQL连接。