Php PDO类的最佳实践?

Php PDO类的最佳实践?,php,pdo,Php,Pdo,我想创建一个PDO类来处理数据库连接 以下是我所拥有的: require('php/packages/store/store_db_settings.php'); class store_pdo { private $DBH; // Data Base Handler function __construct() { $DBH = new PDO(DB_DSN,DB_USER,DB_PASSWORD); } public funct

我想创建一个PDO类来处理数据库连接

以下是我所拥有的:

require('php/packages/store/store_db_settings.php');

class store_pdo
{
    private $DBH; // Data Base Handler

    function __construct() 
    {
        $DBH = new PDO(DB_DSN,DB_USER,DB_PASSWORD);
    }

    public function getHandler()
    {
        return $DBH;
    }

}
我觉得这似乎还可以,但是我习惯于使用像
mysql\u query
这样的东西,并不确定我将来会遇到什么问题。所以我认为这里的经验可以提供指导

我所拥有的足够吗?我应该使我的类成为单例还是使用静态函数?是否有最佳实践

我不想这样做,但在其他几个类使用它之后,我发现我应该以不同的方式编写它


另外,我刚刚注意到,
最佳实践
标签不再被允许。。。这是否意味着现在也不鼓励这样的问题?

单例和静态类都可以。我想不出在什么情况下会有什么不同

如果可能使用多个连接,请确保从一开始就可以使用单例/静态类多连接(使用连接数组或对象属性…)


然而,有人可能会争辩说,所有这些方法都创建了某种“上帝对象”,只不过是一个美化了的
全局
,与真正的OOP原则背道而驰。我问过一次,得到了很多很好的反馈。

扩展PDO,让您更好地控制它

class Database Extends PDO
{
    static $instance; //singleton
    static function Singleton($params = false)
    {
       if(!isset(self::$instance))
       {
           self::$instance = new self($params); //tomh
           self::$instance->init();
       }
       return self::$instance;
    }
    private function __construct(){}; //not allowed with singleton.

    public function init($params) //Override PDO::__construct()
    {
       parent::__construct($params);
    }

    public function query($query)
    {
        //Catch,Custom Query Object maybe. W.e
        return parent::query($modified_query);
    }
}
用法:

$Database = Database::Singleton(array('user' => 'root')); //....
$Database->query('Helooooooo Sexy MySql, Send me my Shizzle');

当您第一次需要连接到两个不同的数据库(用于复制或两个不同的数据库)时,Singleton会咬您的屁股。那你的代码就乱七八糟了

相反,利用单个静态功能轻松加载上次使用的配置:

class MyPDODB extends PDO
{
    // Prevent unconfigured PDO instances!
    private function __construct($config)
    {
        $dsn = sprintf('mysql:dbname=%s;host=%s;port=%d;', $config['database'], $config['hostname'], $config['port']);
        parent::__construct($dsn, $config['username'], $config['password']);        
    }

    public static function loadDB($config_in = null)
    {
        static $last_config = null;

        if (!is_null($config_in))
        {
            self::validateConfig($config_in);
            $config = $config_in;
            if (!isset($config['isTemp']) || $config['isTemp'] !== true)
            {
                $last_config = $config;
            }
        }
        else
        {
            if (!is_null($last_config)) { $config = $last_config; }
            else throw new MyDBException("No config provided');
        }

        return new MyPDODB($config);
    }
}
在任何函数中,您只需执行以下操作:

$db = MyPDODB::loadDB();
$db->prepare($sql);
$db->execute();

很简单,是吧?

re:
最佳实践
tag——据我所知,反对意见是,这是一个本身意义不大的标签。当然,询问最佳实践是可以的!最佳实践是非常主观的。在过去,围绕这类问题一直在进行战争。我同意Russell的观点,这是一个问答网站,而不是一个文档网站。这个问题似乎离题了,因为它要求进行代码审查。请查看CodeReview.StackExchange.com。这是一个好主意,但我认为他希望能够从任何地方访问对象-听起来这是他的主要问题。这打破了Liskov替换原则。有一篇文章是关于这有多可怕的:读了上面的文章,说这是一个可怕的想法有点苛刻。这篇文章提供了一个更好的解决方案谢谢,你的第二段是我脑海中最大的担忧,我不知道为什么我需要这样做,但我已经做了很多次我从未想过我需要做的事情。我真的不知道我将如何着手使其具有多连接功能。。。这可能是主观的,无法回答的,但如果我现在加上它,这是雅格尼的情况,还是雅格尼真的不适用于这种情况?谢谢你的见解@约翰,也许你实际上不需要它,但在这种情况下,我主张从一开始就为它制定条款。否则,如果以后发现需要重构,就必须进行重构。如果使用静态或单例,我将创建一个从内部数组返回PDO连接的函数:
DB::getConnection(1)->query(…)
-如果
getConnection()
没有参数,则返回默认(第一个)连接。这不是很突兀,但给你最大的灵活性。我的第一次-1到佩卡。无论是单例类还是静态类,都可能会让你大吃一惊,特别是考虑到从一个数据库转移到所有数据库的趋势。如果你不相信我,就看看Drupal和WordPress的不幸吧。@Theodore是的,我今天比我写这篇文章时更同意你。虽然可以论证,但我在最后一段中确实提出了两个问题:1。这是否意味着在每次函数调用中都会重新连接到数据库?2.在这里使用多个db时,为了确保连接到正确的db,您不是每次都要向loadDB()传递一些配置吗?我遗漏了很多代码。这是我制作的一个完整的库,对phpexperts.pro的成员开放。简而言之,不,它不会重新连接每个函数调用。PHP的PDO缓存连接尝试;它足够聪明地认识到,如果您连接到堆栈中较高的一个特定PDODB,那么它只会在堆栈中稍后使用该资源句柄。每个PHPDB库都是一样的,afaik。只要每次都能找到正确的分贝。。。看,如果您不想更改全局数据库,您可以将param$config['isTemp']=true,它只对该实例使用该配置。