首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >设计模式:如何仅在需要时创建数据库对象/连接?

设计模式:如何仅在需要时创建数据库对象/连接?
EN

Stack Overflow用户
提问于 2013-05-10 07:37:36
回答 9查看 11.9K关注 0票数 19

我有一个简单的应用程序,假设它有一些类和一个处理数据库请求的“额外”类。目前,每次使用应用程序时,我都会创建数据库对象,但在某些情况下,不需要数据库连接。我是这样做的(PHP btw):

代码语言:javascript
复制
$db = new Database();    
$foo = new Foo($db); // passing the db

但有时$foo对象不需要db访问,因为只调用没有数据库操作的方法。所以我的问题是:处理这种情况的专业方法是什么/如何仅在需要时创建db连接/对象?

我的目标是避免不必要的数据库连接。

EN

回答 9

Stack Overflow用户

发布于 2013-05-17 10:48:12

这大致就是我所使用的。

代码语言:javascript
复制
class Database {

    protected static $connection;

    // this could be public if you wanted to be able to get at the core database
    // set the class variable if it hasn't been done and return it
    protected function getConnection(){
        if (!isset(self::$connection)){
            self::$connection = new mysqli($args);
        }
        return self::$connection;
    }
    // proxy property get to contained object 
    public function __get($property){
        return $this->getConnection()->__get($property);
    }
    // proxy property set to contained object
    public function __set($property, $value){
        $this->getConnection()->__set($property, $value);
    }

    // proxy method calls to the contained object
    public function __call($method, $args){
        return call_user_func_array(array($this->getConnection(), $method), $args);
    }

    // proxy static method calls to the contained object
    public function __callStatic($method, $args){
        $connClass = get_class($this->getConnection());
        return call_user_func_array(array($connClass, $method), $args);
    }
}

注意:只有当只有一个数据库在运行时,它才能起作用。如果您想要多个不同的数据库,可以对其进行扩展,但要注意getConnection方法中的后期静态绑定。

票数 3
EN

Stack Overflow用户

发布于 2013-05-10 07:44:33

下面是一个简单方法的示例:

代码语言:javascript
复制
class Database {
  public $connection = null ;

  public function __construct($autosetup = false){
    if ($autosetup){
      $this->setConnection() ;
    }
  }

  public function getProducts(){//Move it to another class if you wish
    $this->query($sql_to_get_products);
  }

  public function query($sql) {
    if (!$connection || !$connection->ping()){
      $this->setupConnection() ;
    }
    return $this->connection->query($sql);
  }

  public function setConnection(){
    $this->connection = new MySQLi($a, $b, $c, $d) ;
  }

  public function connectionAvailable(){
    return ($connection && $connection->ping()) ;
  }
}
票数 2
EN

Stack Overflow用户

发布于 2013-05-10 09:25:22

考虑使用依赖注入容器,像Pimple这样的东西将是一个很好的起点。使用依赖注入容器,你可以“教”容器如何在你的应用程序中创建对象,直到你请求它们,它们才会被实例化。使用Pimple,您可以配置要共享的资源,使其在请求期间只实例化一次,无论您向容器请求它的频率有多高。

您可以将您的类设置为在其构造函数中接受容器,或者使用setter方法注入到您的类中。

一个简化的示例可能如下所示:

代码语言:javascript
复制
<?php

// somewhere in your application bootstrap

$container = new Pimple();
$container['db'] = $container->share(
  function ($c) {
    return new Database();
  }
);

// somewhere else in your application

$foo = new Foo($container);

// somewhere in the Foo class definition

$bar = $this->container['db']->getBars();

希望能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16472924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档