【问题标题】:Making PDO Database Connection available in controllers and models使 PDO 数据库连接在控制器和模型中可用
【发布时间】:2016-12-28 17:25:12
【问题描述】:

现在,我有点沮丧,我希望有人可以帮助我并为我指明正确的方向。

我有一个“旧”项目,它使用 mysql 语句连接到数据库等。

在这个项目中,我有以下内容:

一个包含

的索引文件
*
* load configuration and connect to database
*/
$projectConfiguration = new projectConfiguration();
$dbconnect = $projectConfiguration->connect($projectConfiguration->databaseHost, $projectConfiguration->databaseName, $projectConfiguration->databaseUser, $projectConfiguration->databasePass);

// load controller
$ReqMod = FatFramework\Functions::getRequestParameter("mod");
if (!$ReqMod) {
$ReqMod = FatFramework\Functions::getRequestParameter("controller");
}
$module = ($ReqMod) ? $ReqMod : 'default';

在这种风格中,我在类中调用视图和操作,例如 SaveAction()

使用 mysql 总是很容易在控制器调用的模型中使用这个数据库连接,比如

public function loadCustomersList($sAdditionalWhere = false)
{
    $sQuery = "SELECT * FROM customers WHERE 1 ";
    if ($sAdditionalWhere) {
        $sQuery .= "AND " . $sAdditionalWhere . " ";
    }
    $sQuery .= "ORDER BY company";
    $sql = mysql_query($sQuery);
    while (($customer = mysql_fetch_object($sql)) != false) {
        $aCustomers[] = $customer;
    }
    return $aCustomers;
}

我想完全折射这个项目并使用 PDO。在过去的 4 个小时里,我一直在尝试寻找解决方案,但我无法弄清楚如何让它发挥作用。

我认为我不需要额外的 dbconnect 类,因为 PDO 本身就是一个类,对吗?

在新的索引文件中,我尝试了以下操作:

$db = new database();
try{
    $dbc = new PDO($db->get_DbConSettings());
    $dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e)
{
    echo 'Verbindung fehlgeschlagen: '.$e->getMessage();
}

但是有了这个 $dbc 将在控制器或模型中不可用。有没有办法让它在那里可用?如果不是,最好的解决方案是什么? 我必须在每个模型中建立数据库连接吗?

我遇到的另一个问题是: $db->get_DbConSettings() 在 $dbc = 新的 PDO

回馈

'mysql:host=127.0.0.1; dbname=c1virtbkk', 'root', '123'

($dbc = new PDO('mysql:host=127.0.0.1; dbname=c1virtbkk', 'root', '123');)

我无法连接到数据库。我得到以下信息:

Verbindung fehlgeschlagen: could not find driver

如果我不使用 $db->get_DbConSettings 并手动输入所需的信息,我不会收到任何错误并且可以进行查询。有什么提示吗?

非常感谢您的帮助。

提前致谢!

标记

【问题讨论】:

    标签: mysql pdo connection


    【解决方案1】:

    绝对不要在每个模型中创建新的 PDO 连接。创建 MySQL 数据库连接相当快,但这样做仍然有一些开销。您想在整个请求中重用连接。如果不出意外,它允许您跨多个模型共享事务。

    一些框架将共享资源对象存储在“注册表”类中,该类是单例键值存储。它实际上只是一个全局哈希数组,但将其作为一个类可以使注册表本身更容易使用 PHPUnit 进行测试。有关注册表的示例,请参阅 https://framework.zend.com/manual/1.12/en/zend.registry.using.html

    您说得对,PDO 是一个类,尽管它是作为 C 扩展而不是 PHP 类实现的。但它是一个类,new PDO(...) 返回该类的一个对象。

    创建自己的 db 类的一个原因是帮助您进行单元测试,因为您可以为您的 db 类创建一个模拟对象,这样您就可以在不需要实时数据库的情况下测试您的其他类(甚至是模型类)联系。您的 db 类可以扩展或包含 PDO 对象。

    您关于“找不到驱动程序”错误的问题可能是因为没有安装mysql的PDO驱动程序。 PDO 是一个 PHP 扩展,然后每个品牌的 SQL 数据库都有一个单独的扩展。您可以通过以下方式确认:

    $ php -i
    
    ...lots of output...
    
    PDO
    
    PDO support => enabled
    PDO drivers => mysql, odbc, sqlite
    
    pdo_mysql
    
    PDO Driver for MySQL => enabled
    Client API version => mysqlnd 5.0.11-dev - 20120503 - $Id: 76b08b24596e12d4553bd41fc93cccd5bac2fe7a $
    
    ...more output for other extensions...
    

    请注意,PDO 告诉我我安装了哪些驱动程序:mysql、odbc 和 sqlite。

    所以你需要安装pdo_mysql。我不确定您使用的是什么操作系统,但我经常使用 CentOS Linux 或 Ubuntu Linux。 pdo_mysql 可以通过 yum 或 apt 作为单独的包使用。


    你的评论:

    好的,这是一个注册表示例:

    class registry {
      protected static $items = array();
    
      public static get($key) {
        return isset(self::$items[$key])?
          self::$items[$key] : null;
      }
    
      public static set($key, $object) {
        self::$items[$key] = $object;
      }
    }
    

    在您的控制器初始代码中,您将创建一个数据库对象并将其存储在注册表中:

    $projectConfiguration = new projectConfiguration();
    $dbconnect = $projectConfiguration->connect(
      $projectConfiguration->databaseHost, 
      $projectConfiguration->databaseName,
      $projectConfiguration->databaseUser,
      $projectConfiguration->databasePass);
    
    registry::set('db', $dbconnect);
    

    然后在您的模型类方法中(或任何您需要数据库的地方),从注册表中获取 db 对象并使用它:

    public function loadCustomersList($sAdditionalWhere = false)
    {
        $sQuery = "SELECT * FROM customers WHERE 1 ";
        if ($sAdditionalWhere) {
            $sQuery .= "AND " . $sAdditionalWhere . " ";
        }
        $sQuery .= "ORDER BY company";
    
        $db = registry::get('db');
        $stmt = $db->query($sQuery);
        $aCustomers = $stmt->fetchAll(PDO::FETCH_ASSOC);
        return $aCustomers;
    }
    

    【讨论】:

    • 非常感谢您提供的详细信息。我很难理解前两段,但我会弄明白的?我可以要求一个愤怒的请求:你能为注册表提供一个例子吗? Zend 页面让我很困惑?
    • 再次感谢您!我会尽快尝试这个。关于驱动问题:我检查了 phpinfo() 并且 PDO MySQL 已启用。让我感到困惑的是,如果我在 $dbc = new PDO 中使用 $db->get_DbConSettings() 只会收到此错误。如果我将必要的信息直接写入新 PDO (...),我不会收到错误消息。
    • 那么我猜你的 get_DbConSettings() 函数没有使用正确的参数创建 PDO 对象。查看文档以获取 PDO 构造函数的正确参数。
    猜你喜欢
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 2019-07-29
    • 2020-10-18
    • 2015-01-16
    • 1970-01-01
    相关资源
    最近更新 更多