从 mysql 连接迁移到 mysqli

Posted

技术标签:

【中文标题】从 mysql 连接迁移到 mysqli【英文标题】:Moving from mysql connection to mysqli 【发布时间】:2012-11-26 10:48:39 【问题描述】:

我有一个用于我的脚本的函数。 openDBConn()closeDBConn() 这两个都调用了 mysql_connect() 函数。如下所示使用

openDBConn();
$car_model = getCarModel($car_id);
$car_color = getCarColor($car_id);
closeDBConn();

这样做也可以让我做以下事情

openDBConn();
mysqlStartTranscation();

upgradeCarColor($car_id);
addNewWing($car_id);

mysqlCommit();
closeDBConn();

现在的困境是,如果我搬到mysqli,我需要通过连接链接。

我还读到 mysql_* 正在被弃用,我的问题是:

    在我的大部分功能停止工作之前,我还有多少时间? 是否有任何当前或将来访问当前 mysqli 连接的方法,因为向我的函数添加额外参数会很痛苦? 是否有任何适当的编码方式以程序方式访问当前的 mysqli 连接链接。如果不是在程序上,那么 OOP 方式中的最佳方式是什么?

【问题讨论】:

mysql_ 系列函数将在 5.5 中弃用,并可能在任何后续 主要 版本中完全删除。考虑到 5.5 甚至还没有处于测试阶段,而且发布 之后 已经有一段时间了,所以您不必惊慌。慢慢来,按照自己的节奏学习。此外,请查看相关侧边栏上的每一个最后一个问题。他们会提供一些帮助。 另外,认真看看PDO 而不是mysqli。它们都一样有能力,但是 PDO 的预处理语句语法要友好得多。 PDO 是 OO-only,没有像 mysqli 那样的程序回退。 【参考方案1】:

首先,我为您的问题 +1,因为您开始迁移是一件好事。

OOP 和参数

关于 OOP 编程和参数传递,这里有一个基于单例工厂模式的解决方案:

class MysqliConnection
   private static $connection = null;
   public static function getConnection()
       
      
       if(self::$connection === null)
           //Here get some routine to make your configuration extern
           self::$connection = new Mysqli(/*args*/);
       
       return self::$connection;

当你想发送查询时,你可以这样使用它:

 function methodWhichSendsAQuery()
      $mysqli = MysqliConnection::getConnection();
      $query = $mysqli->prepare(/*your query*/);
      /*some param bindings with $query->bindParam()*/
      $query->execute();
      return $query->fetchAll(); //an array with all results
  

我更喜欢这个解决方案,因为它干净、易读并且不依赖于全局变量。单一职责原则得到尊重,没关系。

将mysql_重构为mysqli

如果你习惯于用旧的方式处理 mysql_,重构会非常困难,我的意思是没有 ressource 参数,mysql_escape_stringetc 等等。

Mysql 提供了一个强大的脚本,可以从 mysql_ 迁移到 mysqli here,您可以获取更多信息here。

我可以对你说的是,mysqli 带来了一个名为“prepared statement”的功能,该功能真的非常强大并且在安全性方面非常强大。 mysqli 处理预处理语句的方式不如 PDO 的方式用户友好,但属性相同。

【讨论】:

【参考方案2】:
    您拥有世界上所有的时间,因为他们永远不会停止自己的工作! 是的,有几种方法可以做到这一点。 是的,但没有一种万能的解决方案。每种情况都不同,适合您特定情况的方法可能并不适合每种情况。

首先,旧的 ext/mysql 自 php 5.5.0 起已弃用,但它永远不会完全停止工作,因为扩展本身最终将被移动到 PHP PECL repository 中(到时候删除它)。但是,我们还没有到那里,只有当您选择升级到该版本的 PHP 时,您才会受到影响。没有确定移除扩展的确切时间。

其次,您可以使用变量来存储数据库连接,就像旧的 ext/mysql 扩展在幕后为您所做的那样。诀窍是您不知道它在做什么(它使用您在调用 mysql_connect 时创建的最后一个打开连接,并且每次调用 mysql_query 之类的东西来访问数据库时都使用它)。

您可以使用程序样式在函数中使用静态变量来执行此操作....

function openDBConn() 
    static $link;
    if (!isset($link)) 
      $link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
    
    return $link; // returns the link

或者您可以使用 OOP 对类静态变量执行此操作...

Class MyDBConnect 

    public static $link;

    public function openDBConn() 
        if (!isset(static::$link)) 
            static::$link = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
        
    


我想鼓励您使用更新的 API,并为此赞扬您,但我也想在您继续前进时提醒您。当您开始将函数从旧的 ext/mysql 函数移植到新的 mysqli 扩展时,请注意不要同时移植旧扩展的不良做法(例如使用旧的 SQL 字符串连接和转义技术 ext/ mysql 提供)。而是利用 MySQLi prepared statements and parameterized queries。

我想让您注意的是使用更新的 API 与您的 MySQL 数据库(即PDO and MySQLi)交互的好处。

【讨论】:

感谢您,非常感谢。我一直认为我可以使用 mysqli_init() 来访问最后一个连接链接,但它返回的只是一个带有空 thread_id 的对象 不客气,但这不是mysqli_init 所做的。它用于获取要交给mysqli_real_connect 的对象,这与mysqli_connect 的作用非常不同。详情请阅读相关手册链接。 我试过你的代码,但是当我在执行查询的函数中调用它时,链接是空的。我有什么遗漏吗? 如果我有 2 种类型的连接,例如 openDBConn('read') 和 openDBConn('write),这会有什么不同? 如果您想要多个连接,使用这种方法解决您的问题会变得更加复杂,并且实际上变得更难阅读、更难编写和更难调试。您最好只实例化单个 mysqli 对象并根据需要携带它们(将它们传递给您的函数)。

以上是关于从 mysql 连接迁移到 mysqli的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的网站从 mysql 迁移到 mysqli? [复制]

PHP mysql 到 mysqli 迁移问题(自定义函数,程序风格)

从 MySQL 5.6.35 迁移到 MariaDB 10.6.3 - 查询不起作用

将大表从 MySql 迁移到 MsSql

如何将MySQL数据库迁移到Oracle数据库

java项目数据库从oracle迁移到mysql 中 java部分的一些修改