PHP - 一个DB抽象层使用静态类vs单例对象? [英] PHP - a DB abstraction layer use static class vs singleton object?

查看:145
本文介绍了PHP - 一个DB抽象层使用静态类vs单例对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不想创建一个关于单例的讨论比静态或更好的比全局等我读了几十个关于类似的主题的问题,但我不能想出这个SPECIFIC问题的答案,所以我希望有人现在可以用一个(或多个)真正简单的例子回答这个问题,而不只是理论讨论。



在我的应用程序我已经在典型DB类抽象DB层并执行对数据库的任务,而无需在代码中到处写 mysql_connect / mysql_select_db / MySQL的...



我可以将该课程作为STATIC CLASS

  class DB 
{
private static $ connection = FALSE; //要打开的连接

//数据库连接值
private static $ server = NULL; private static $ usr = NULL; private static $ psw = NULL; private static $ name = NULL;

公共静态功能的init($ DB_SERVER,$ db_usr,$ db_psw,$ DB_NAME)
{
//只是商店的连接价值,而无需打开连接
$} b
$ b公共静态函数查询($ query_string)
{
//对已打开的连接执行查询,如果未打开连接,则打开连接1st
}

...
}

或作为SINGLETON: / strong>

  class DBSingleton 
{
private $ inst = NULL;
private $ connection = FALSE; //要打开的连接

//数据库连接值
private $ server = NULL;私有$ usr = NULL; private $ psw = NULL; private $ name = NULL;

公共静态功能的getInstance($ DB_SERVER,$ db_usr,$ db_psw,$ DB_NAME)
{
//只是商店的连接价值,而无需打开连接

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

公共函数查询($ query_string)
{
//对已打开的连接执行查询连接未打开,它打开连接1st
}

...
}

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

  //使用静态DB对象执行查询
DB:init(HOST,USR,PSW,DB_NAME);
DB :: query(SELECT ...);

//使用DB单例执行查询
$ temp = DBSingleton :: getInstance(HOST,USR,PSW,DB_NAME);
$ temp-> query(SELECT ...);对我来说Singleton有唯一的优势,就是避免声明为 static

类的每个方法。我敢肯定,在这种特定情况中,有些人可以给我一个 Example 的单例的真正优势。提前感谢。

解决方案

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

 类数据库
{
protected $ _connection;

protected $ _config;

public function __construct(array $ config)//或其他传递配置的方法vars
{
$ this-> _config = $ config;
}

公共函数查询($ query)
{
//使用延迟加载getter
return $ this-> _getConnection ; query($ query);
}

protected function _getConnection()
{
//延迟加载连接
if($ this-> _connection === null)
{
$ dsn = / *从$ this-> _config * /中创建有效的dsn字符串;

try
{
$ this-> _connection = new PDO($ dsn,$ this-> _config ['username'],$ this-> _config [ 'password']);
}
catch(PDOException $ e)
{
/ *手柄连接失败* /
}
}

$ 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);

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



当一个消耗了一个实例(在这种情况下是一个模型)的对象决定调用一个方法时,数据库实例将只连接到它们各自的连接。实例。


I don't want to create a discussion about singleton better than static or better than global, etc. I read dozens of questions about similar subjects on SO, but I couldn't come up with an answer to this SPECIFIC question, so I hope someone could now illuminate me by answering this question with one (or more) real simple EXAMPLES, and not just theoretical discussions.

In my app I have the typical DB class to abstract the DB layer and to perform tasks on DB without having to write everywhere in code 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
   }

   ...
}

Then after in my app if I want to query the DB i could do

//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...");

To me Singleton has got the only advantage to avoid declaring as static each method of the class. I'm sure some of you could give me an EXAMPLE of real advantage of singleton in this specific case. Thanks in advance.

解决方案

What is wrong with the following (simplified) example:

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 );

This demonstrates how you can make use of lazy loading connections, and still have flexibility to use different database connections.

The database instances will only connect to their individual connection when an object that consumes one of the instances (in this case one of the models) decides to call a method of the instance.

这篇关于PHP - 一个DB抽象层使用静态类vs单例对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆