【问题标题】:php PDO connection close scopephp PDO 连接关闭范围
【发布时间】:2017-03-10 19:40:34
【问题描述】:

根据 php 文档,PDO 连接存在于其对象的整个生命周期中。所以在下面的代码中...

<?php

for($i = 0; $i < 5; $i++)
{
    myfunc();
}

function myFunc()
{
    $conn = new PDO("connectionStuff");

    //Do things
}

?>

...既然 $conn 只在 myFunc 的范围内,那么每次 myFunc 执行完成时 PDO 连接是否会关闭?还是在整个页面完成之前保持 5 个 PDO 连接处于打开状态?

我必须在 myFunc 的末尾设置 $conn = null,还是没有必要?

【问题讨论】:

  • 自己测试一下。只需在 php 脚本末尾添加 var_dump($conn); 即可。您总是在建立一个新的 PDO 实例,它会覆盖之前创建的实例。所以在myFunc()函数结束之前,总是有一个单一的PDO连接。
  • 好的,谢谢。另外,这是最佳实践,还是我应该每页使用一个 PDO 连接并将连接对象传递给函数?

标签: php mysql pdo


【解决方案1】:

只是为了回答您在 cmets 中提出的问题。在现代编程中,最好的做法是使用dependency injection 处理像您这样的情况。此外,使用容器更实用。在现代面向对象的框架中,总是有一个服务管理器,它充当容器并提供您需要的所有东西。

class DiContainer {
    protected $instances = [];

    public function __construct(array $aInstances = []) {
        $this->instances = $aInstances;
    }

    public function set($sName, $oInstance) {
        if (isset($this->instances[$sName]) {
            throw new \Exception(sprintf(
                'An instance for "%s" already exists'
                $sName
            ));
        }

        $this->instances[$sName] = $oInstance;
    }

    public function get($sName) {
        if (!isset($this->instances[$sName)) {
            throw new ErrorException(sprintf(
                'No instance for "%s"',
                $sName
            ));
        }

        return $this->instances[$sName];
    }
}

这是依赖容器。您可以在其中存储应用程序所需的所有实例。请记住,这是一个未经测试的小示例,它显示了依赖注入的好处。您不应该以高效的方式使用它,因为 DI 容器比这个简单的示例要复杂得多。

实际上你可以像下面的例子那样使用它。

// when you instanciate your application
$oContainer = new DiContainer([
    'db-connection' => new PDO(...),
]);

// in your specific class
public function doSomethingWithDatabase(DiContainer $oContainer) {
    $oDbHandle = $oContainer->get('db-connection');
    ...
}

【讨论】:

  • 谢谢。我喜欢这个主意。所以归根结底,数据库连接应该传递到函数中,而不是在函数内部实例化,对吗?
猜你喜欢
  • 1970-01-01
  • 2013-08-19
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 2019-07-20
  • 2018-06-12
  • 2014-05-24
相关资源
最近更新 更多