我不想创造一个关于单身比静电更好,或者比全球更好的讨论,等等.我在SO上读了几十个关于类似主题的问题,但是我想不出这个具体问题的答案,所以我希望现在有人能用一个(或更多)real simple EXAMPLES个回答这个问题来启发我,而不仅仅是理论上的讨论.

在我的应用程序中,我有typical DB class to abstract the DB layer,可以在数据库上执行任务,而不必到处用代码mysql_connect / mysql_select_db / mysql...编写

I could write the class either as a STATIC CLASS:

class DB
{
   private static $connection = FALSE; //connection to be opened

   //DB connection values
   private static $server = NULL; private static $usr = NULL; private static $psw = NULL; private static $name = NULL;

   public static function init($db_server, $db_usr, $db_psw, $db_name)
   {
      //simply stores connections values, without opening connection
   }

   public static function query($query_string)
   {
      //performs query over alerady opened connection, if not open, it opens connection 1st
   }

   ...
}

OR as a SINGLETON:

class DBSingleton
{
   private $inst = NULL;
   private $connection = FALSE; //connection to be opened

   //DB connection values
   private $server = NULL; private $usr = NULL; private $psw = NULL; private $name = NULL;

   public static function getInstance($db_server, $db_usr, $db_psw, $db_name)
   {
      //simply stores connections values, without opening connection

      if($inst === NULL)
         $this->inst = new DBSingleton();
      return $this->inst;
   }
   private __construct()...

   public function query($query_string)
   {
      //performs query over already opened connection, if connection is not open, it opens connection 1st
   }

   ...
}

然后在我的应用程序中,如果我想查询数据库,我可以这样做

//Performing query using static DB object
DB:init(HOST, USR, PSW, DB_NAME);
DB::query("SELECT...");

//Performing query using DB singleton
$temp = DBSingleton::getInstance(HOST, USR, PSW, DB_NAME);
$temp->query("SELECT...");

对我来说,Singleton唯一的优势是避免将类的每个方法声明为static.我相信你们中的一些人可以给我一个EXAMPLE分的单人版在这specific case分中的真正优势.提前谢谢您.

推荐答案

以下(简化)示例有什么问题:

class Database
{
    protected $_connection;

    protected $_config;

    public function __construct( array $config ) // or other means of passing config vars
    {
        $this->_config = $config;
    }

    public function query( $query )
    {
        // use lazy loading getter
        return $this->_getConnection()->query( $query );
    }

    protected function _getConnection()
    {
        // lazy load connection
        if( $this->_connection === null )
        {
            $dsn = /* create valid dsn string from $this->_config */;

            try
            {
                $this->_connection = new PDO( $dsn, $this->_config[ 'username' ], $this->_config[ 'password' ] );
            }
            catch( PDOException $e )
            {
                /* handle failed connecting */
            }
        }

        return $this->_connection;
    }
}

$db1 = new Database( array(
    'driver'   => 'mysql',
    'host'     => 'localhost',
    'dbname'   => 'test',
    'username' => 'test_root',
    'password' => '**********'
) );

$db2 = new Database( array(
    'driver'   => 'pgsql',
    'host'     => '213.222.1.43',
    'dbname'   => 'otherdb',
    'username' => 'otherdb_root',
    'password' => '**********'
) );

$someModel       = new SomeModel( $db1 );
$someOtherModel  = new SomeOtherModel( $db2 );
$yetAnotherModel = new YetAnotherModel( $db2 );

这演示了如何利用延迟加载连接,并且仍然可以灵活地使用不同的数据库连接.

只有当使用其中一个实例的对象(在本例中是其中一个模型)决定调用实例的方法时,数据库实例才会连接到它们各自的连接.

Database相关问答推荐

如何在Ballina中的事务失败时回滚缓存插入操作

安装postgresql用于使用和调试Apache-AGE

从仅连接器电源查询制作图表

在保持抽象的同时将格式化文本存储在数据库中

任何用于存储过程的静态代码分析工具?

如何以编程方式在 C# 中创建 Microsoft Access 数据库?

如何将 MySQL 5.5.40 升级到 MySQL 5.7

每个请求可以多次查询 MongoDB 吗?

什么是 Scalar标量查询?

什么是表前缀?

返回 SQLite 数据库中表大小的查询

什么是本体数据库?

设计数据库时最重要的考虑因素是什么?

如何从 T-SQL 中的表中 Select 前 N 行?

mysql 无法从存储引擎读取自增值

Redis Pub/Sub 和 Redis Stream 之间的主要区别是什么?

显式事务回滚是否必要?

防止 PostgreSQL 有时 Select 错误的查询计划

Spring data : CrudRepository 的保存方法和更新

从 SQLite 导出到 SQL Server