编辑:是否使用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);
?>
答案 0 :(得分:16)
mysql_
转换为mysqli_
可能不是最佳选择。如果您准备将所有代码转换为PDO,请考虑OOP。尝试用mysql_
替换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_string
与mysql_real_escape_string
非常相似。您只需要将连接对象作为第一个参数传递。
的MySQL _:
$value1 = mysql_real_escape_string($input_string);
的mysqli _:
$value1 = mysqli_real_escape_string($con, $input_string);
mysql_
函数开始时被弃用的一个原因是它们无法处理预准备语句。如果您只是将代码转换为mysqli_
而不采取这一重要步骤,那么您将遇到mysql_
函数的一些最大弱点。
值得阅读这些关于准备好的陈述及其好处的文章:
Wikipedia - Prepared Statements
PHP.net - MySQLi Prepared Statements
注意:使用预准备语句时,最好明确列出您尝试查询的每个列,而不是使用*
表示法查询所有列。这样,您就可以确保在调用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);
}
}
答案 1 :(得分: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;
}
答案 2 :(得分:0)
没有一个理由这样做。
首先,没有理由机械地做到这一点,仅更改功能名称,使算法保持不变:
如果没有实现参数化查询,这样的移动就没什么意义了 如果您唯一关注的是“已弃用”错误 - 您可以使用
关闭它们error_reporting(E_ALL & ~E_DEPRECATED);
并继续愉快地使用旧的mysql_ *
请注意,只有在2 - 3年内,当PHP 5.5到达共享主机时,您才需要这样做
所以,没有必要赶时间。
其次,您真正需要的是从代码中消除所有裸API调用
将它们封装到某种抽象库中。这应该是您的主要关注点,而不是此库中使用的特定API,可以在瞬间更改。
最后,从mysql_*
切换到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();
试试看吧。
然而,即使PDO也需要一些模糊和无用的代码来创建某些查询部分。因此,最好的方法是使用一些更智能的库,例如safemysql,它将完成内部的所有工作,从绑定到提取,使所有代码成为单行:
$data = $db->getALL("SELECT * FROM table WHERE category IN (?a)", $_GET['cat']);