【问题标题】:Best practices for a PDO class? [closed]PDO 类的最佳实践? [关闭]
【发布时间】:2011-04-03 17:35:35
【问题描述】:

我想创建一个 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_query 之类的东西,并且不确定我将来会遇到什么问题。所以我认为这里的经验可以提供指导。

我有足够的吗?我应该让我的类单例,还是使用静态函数?有最佳做法吗?

我不想用这个,然后我在有几个其他类使用它之后,发现我应该用不同的方式写它。

附:我刚刚注意到 best-practices 标记不再被允许......这是否意味着现在也不鼓励这样的问题?

【问题讨论】:

  • re: best-practices 标签 - 据我了解,反对意见是它本身没有多大意义。当然,询问最佳实践是可以的!
  • 最佳实践是非常主观的。过去曾就 SO 上的此类问题展开过战争。
  • 我同意 Russell 的观点,这是一个问答网站,而不是文档网站。
  • 这个问题似乎跑题了,因为它要求进行代码审查。请检查 CodeReview.StackExchange.com。

标签: php pdo


【解决方案1】:

单例类和静态类都可以正常工作。我想不出什么情况会有所作为。

确保如果有可能使用多个连接,则从一开始就使您的 Singleton/Static 类具有多连接能力(使用连接数组或对象属性...)

不过,可以说,所有这些方法都创建了某种“上帝对象”,只不过是一种美化的global,并且违背了真正的 OOP 原则。我曾经问过a question about this,得到了很多很好的反馈。

【讨论】:

  • 谢谢,你的第二段是我最关心的问题,我不知道为什么我需要这样做,但我最终做了很多我从未想过会做的事情需要。我不确定我将如何使其具有多连接能力......这可能是主观的且无法回答,但如果我现在添加它,这是 yagni 的情况,还是 yagni 并不真正适用于这种情况?感谢您的见解!
  • @John 实际上您可能不需要它,但在这种情况下,我建议从一开始就为它创建规定。否则,如果您以后需要它,您将不得不进行重构。如果您使用静态或单例,我将创建一个从内部数组返回 PDO 连接的函数:DB::getConnection(1)->query(....) - 如果getConnection() 没有参数,则返回默认(第一个)连接。这不是很突兀,但可以为您提供最大的灵活性。
  • 我第一次到 Pekka 的 -1。单例类和静态类都可能让你大吃一惊,尤其是考虑到远离 One DB Solves All 的趋势。如果你不相信我,看看 Drupal 和 WordPress 的困境。
  • @Theodore 是的,我今天比写这篇文章时更同意你的看法。尽管可以说,我确实在最后一段中解决了这个问题
【解决方案2】:

扩展 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');

【讨论】:

【解决方案3】:

当您第一次需要连接到两个不同的数据库(用于复制或两个不同的数据库)时,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();

简单吧?

【讨论】:

  • 两个问题: 1. 这不是说每次函数调用都会重新连接数据库吗? 2.在这里使用多个数据库时,为了确保您连接到正确的数据库,您是否不必每次都将一些配置传递给 loadDB()?
  • 我遗漏了很多代码。这是我创建的一个完整的库,对 phpexperts.pro 的成员开放源代码。简而言之,不,它不会重新连接每个函数调用。 PHP 的 PDO 缓存连接尝试;意识到如果您连接到堆栈中的某个特定 PDO DB,它就足够聪明了,它只是在堆栈中稍后使用该资源句柄。它与每个 PHP DB 库都是一样的,afaik。至于每次都找到正确的数据库...看,如果您不想更改全局数据库,则设置参数 $config['isTemp'] = true 并且它仅对该实例使用该配置。
猜你喜欢
  • 2012-07-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 2013-10-02
  • 2010-10-06
  • 2011-10-28
  • 2010-09-10
  • 2011-10-11
相关资源
最近更新 更多