7

编辑:是否使用mysqli_超出了这个问题的范围。考虑使用 PDO。


需要采取哪些步骤将脚本从使用过时的mysql_函数转换为mysqli_?

mysqli_使用代替时有什么需要做的不同的事情mysql吗?

mysql_这是一个使用函数的基本脚本:

<?php

//define host, username and password

$con = mysql_connect($host,$username,$password);
if (!$con) {
    die('Could not connect: ' . mysql_error());
}

$db_name ="db1";
mysql_select_db($dbname, $con);

$value1 = mysql_real_escape_string($input_string);

$query = 'SELECT * FROM table1 WHERE table1.col1=' . $value1 . '';
$result = mysql_query($query, $con);

while($row = mysql_fetch_assoc*$result)
{
    $col1 = $row['col1'];
    $col2 = $row['col2'];

    echo $col1 . ' ' . $col2 . '<br />';
}

mysql_close($con);
?>
4

3 回答 3

17

注意:从 转换mysql_mysqli_可能不是最佳的。如果您准备将所有代码转换为OOP ,请考虑使用PDO

尝试替换mysql_with的所有实例mysqli_并祈祷它有效可能很诱人。你会很接近,但不是很准确。

连接数据库:

幸运的是,mysqli_connect它的工作方式足够紧密mysql_query,您可以换掉它们的函数名称。

mysql_:

$con = mysql_connect($host, $username, $password);

mysqli_:

$con = mysqli_connect($host, $username, $password);

选择数据库

现在,对于库中的大多数其他函数mysqli_,您需要将mysqli_select_db数据库连接作为其第一个参数传递。大多数mysqli_功能首先需要连接对象。

对于此函数,您只需切换传递给函数的参数的顺序即可。如果您之前没有将连接对象传递给它,那么您现在必须将其添加为第一个参数。

mysql_:

mysql_select_db($dbname, $con);

mysqli_:

mysqli_select_db($con, $dbname);

作为奖励,您还可以将数据库名称作为第四个参数传递给mysqli_connect- 绕过需要调用mysqli_select_db.

$con = mysqli_connect($host, $username, $password, $dbname);

清理用户输入

使用mysqli_real_escape_stringmysql_real_escape_string. 您只需要将连接对象作为第一个参数传递。

mysql_:

$value1 = mysql_real_escape_string($input_string);

mysqli_:

$value1 = mysqli_real_escape_string($con, $input_string);

非常重要:准备和运行查询

mysql_这些函数一开始就被弃用的原因之一是它们无法处理准备好的语句。如果您只是将代码转换为mysqli_不采取这一重要步骤,那么您将受到这些mysql_功能的一些最大弱点的影响。

值得阅读这些关于准备好的陈述及其好处的文章:

维基百科 - 准备好的陈述

PHP.net - MySQLi 准备好的语句

注意:使用准备好的语句时,最好明确列出您尝试查询的每一列,而不是使用*表示法来查询所有列。通过这种方式,您可以确保您已将调用中的所有列都计算在内mysqli_stmt_bind_result

mysql_:

$query = 'SELECT * FROM table1 WHERE table1.col1=' . $value1 . '';
$result = mysql_query($query, $con);
while($row = mysql_fetch_assoc*$result)
{
    $col1 = $row['col1'];
    $col2 = $row['col2'];

    echo $col1 . ' ' . $col2 . '<br />';
}

mysqli_:

$query = 'SELECT col1,col2 FROM table1 WHERE table1.col1=?';
if ($stmt = mysqli_prepare($link, $query)) {

    /* pass parameters to query */
    mysqli_stmt_bind_param($stmt, "s", $value1);

    /* run the query on the database */
    mysqli_stmt_execute($stmt);

    /* assign variable for each column to store results in */
    mysqli_stmt_bind_result($stmt, $col1, $col2);

    /* fetch values */
    while (mysqli_stmt_fetch($stmt)) {
        /*
            on each fetch, the values for each column 
            in the results are automatically stored in 
            the variables we assigned using 
            "mysqli_stmt_bind_result"
        */
        echo $col1 . ' ' . $col2 . '<br />';
    }

    /* close statement */
    mysqli_stmt_close($stmt);
}

显示错误

显示错误与mysqli_. mysqli_error需要连接对象作为其第一个参数。但是如果连接失败怎么办?mysqli_引入了一小组不需要连接对象的函数:mysqli_connect_*函数。

mysql_:

if (!$con) {
    die('Could not connect: ' . mysql_error());
}

if (!$result) {
    die('SQL Error: ' . mysql_error());
}

mysqli_:

/* check connection error*/
if (mysqli_connect_errno()) {
    die( 'Could not connect: ' . mysqli_connect_error() );
}

/* check query error */
if ($stmt = mysqli_prepare($link, $query)) {

    // ... execute query

    if (mysqli_stmt_error($stmt)) {
        echo 'SQL Error: ' . mysqli_stmt_error($stmt);
    }
}
于 2013-02-24T20:00:16.497 回答
1

例子。

这是你的 dbc 类

<?php

class dbc {

    public $dbserver = 'server';
    public $dbusername = 'user';
    public $dbpassword = 'pass';
    public $dbname = 'db';

    function openDb() {    
        try {
            $db = new PDO('mysql:host=' . $this->dbserver . ';dbname=' . $this->dbname . ';charset=utf8', '' . $this->dbusername . '', '' . $this->dbpassword . '');
        } catch (PDOException $e) {
            die("error, please try again");
        }        
        return $db;
    }

    function getAllData($qty) {
        //prepared query to prevent SQL injections
        $query = "select * from TABLE where qty = ?";
        $stmt = $this->openDb()->prepare($query);
        $stmt->bindValue(1, $qty, PDO::PARAM_INT);
        $stmt->execute();
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        return $rows;
    }    
?>

您的 PHP 页面:

<?php 
require "dbc.php";

$getList = $db->getAllData(25);

foreach ($getList as $key=> $row) {
         echo $row['columnName'] .' key: '. $key;
    }
于 2013-02-24T20:39:51.800 回答
0

不要将 mysql_ 函数转换为 mysqli_。时期。

没有一个理由这样做。

首先,没有理由机械地这样做,只更改函数名称而使算法保持不变:

如果不实现参数化查询,这样的举动几乎没有意义。
如果您唯一关心的是“已弃用”错误 - 您可以将它们关闭

error_reporting(E_ALL & ~E_DEPRECATED);

并继续愉快地使用旧的 mysql_*
请注意,只有在 2-3 年内 PHP 5.5 将到达共享主机时,您才需要它。
所以,也没有必要着急。

其次,您真正需要的是从代码中消除所有裸 API 调用

将它们封装到某种抽象库中。这应该是你主要关心的问题,而不是这个库中使用的特定 API,它可以在眨眼之间改变。

mysql_*最后,从 切换到的唯一真正原因mysqli_*是参数化查询。

mysqli 完全无法与它们一起使用。

使用准备好的语句 PDO 是您唯一的选择。

让我告诉你我的意思。
想象一下,我们有一组来自 HTML 表单的复选框,可以动态添加到查询中。
使用 PDO,我们可以拥有一些相对健全且相当简洁(但仍然无用的复杂和污染)的代码:

$in  = str_repeat('?,', count($_GET['cat']) - 1) . '?';
$sql = "SELECT * FROM table WHERE category IN ($in)";
$stm = $db->prepare($sql);
$stm->execute($_GET['cat']);
$data = $stm->fetchAll();

使用 mysqli,这样一个微不足道的案例将花费您数小时编写和调试几页极其复杂的代码。

试试看。

然而,即使是 PDO 也需要一些晦涩无用的代码来创建某些查询部分。因此,最好的方法是使用一些更智能的库,例如safemysql,它将在内部完成所有工作,从绑定到获取,将所有代码变成单行

$data = $db->getALL("SELECT * FROM table WHERE category IN (?a)", $_GET['cat']);
于 2013-02-24T20:04:24.463 回答