根据下面的代码,我用于常规的mysql,我怎么能将它转换为使用mysqli?
是否像更改**mysql _query($ sql)一样简单 ; 到mysqli _query($ sql) ; ?**
<?PHP
//in my header file that is included on every page I have this
$DB["dbName"] = "emails";
$DB["host"] = "localhost";
$DB["user"] = "root";
$DB["pass"] = "";
$link = mysql_connect($DB['host'], $DB['user'], $DB['pass']) or die("<center>An Internal Error has Occured. Please report following error to the webmaster.<br><br>".mysql_error()."'</center>");
mysql_select_db($DB['dbName']);
// end header connection part
// function from a functions file that I run a mysql query through in any page.
function executeQuery($sql) {
$result = mysql_query($sql);
if (mysql_error()) {
$error = '<BR><center><font size="+1" face="arial" color="red">An Internal Error has Occured.<BR> The error has been recorded for review</font></center><br>';
if ($_SESSION['auto_id'] == 1) {
$sql_formatted = highlight_string(stripslashes($sql), true);
$error .= '<b>The MySQL Syntax Used</b><br>' . $sql_formatted . '<br><br><b>The MySQL Error Returned</b><br>' . mysql_error();
}
die($error);
}
return $result;
}
// example query ran on anypage of the site using executeQuery function
$sql='SELECT auto_id FROM friend_reg_user WHERE auto_id=' .$info['auto_id'];
$result_member=executequery($sql);
if($line_member=mysql_fetch_array($result_member)){
extract($line_member);
} else {
header("location: index.php");
exit;
}
?>
Run Code Online (Sandbox Code Playgroud)
Pas*_*TIN 72
要做的第一件事可能是mysql_*
用等效的方法替换每个函数调用mysqli_*
,至少如果你愿意使用过程API - 这将是更简单的方法,考虑到你已经有一些基于MySQL API的代码,是程序性的.
为了解决这个问题,MySQLi扩展函数摘要绝对是有用的.
例如:
mysql_connect
将被替换为 mysqli_connect
mysql_error
将取决于mysqli_error
和/或mysqli_connect_error
取决于上下文mysql_query
将被替换为 mysqli_query
请注意,对于某些函数,您可能需要仔细检查参数:也许这里和那里存在一些差异 - 但不是很多,我会说:mysql和mysqli都基于相同的库(libmysql; at至少对于PHP <= 5.2)
例如:
mysql_select_db
一次连接,以指示您要在哪个数据库上进行查询mysqli_connect
.mysqli_select_db
如果您愿意,还可以使用一种功能.
完成后,尝试执行脚本的新版本...并检查一切是否正常; 如果不是......寻找漏洞的时间;-)
小智 31
(我意识到这是旧的,但它仍然出现......)
如果你确实替换mysql_*
,mysqli_*
那么请记住,一大堆mysqli_*
函数需要传递数据库链接.
例如:
mysql_query($query)
Run Code Online (Sandbox Code Playgroud)
变
mysqli_query($link, $query)
Run Code Online (Sandbox Code Playgroud)
即,需要进行大量检查.
Dha*_*man 22
mysql_*
功能升级到 MySQLi API的终极指南新的 mysqli 扩展的原因是利用 MySQL 系统版本 4.1.3 和更新版本中的新功能。将现有代码从mysql_*
mysqli API更改为 mysqli API 时,您应该利用这些改进,否则您的升级工作可能会白费。
mysqli 扩展有很多好处,对 mysql 扩展的主要增强是:
当从mysql_*
函数升级到 MySQLi 时,重要的是要考虑这些特性,以及这个 API 应该使用的方式的一些变化。
新的 mysqli 面向对象接口是对旧函数的重大改进,它可以使您的代码更干净,并且不易受排版错误的影响。还有这个 API 的过程版本,但不鼓励使用它,因为它会导致代码可读性降低,更容易出错。
要使用 MySQLi 打开与数据库的新连接,您需要创建 MySQLi 类的新实例。
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
Run Code Online (Sandbox Code Playgroud)
使用程序风格,它看起来像这样:
$mysqli = mysqli_connect($host, $user, $password, $dbName);
mysqli_set_charset($mysqli, 'utf8mb4');
Run Code Online (Sandbox Code Playgroud)
请记住,只有前 3 个参数与mysql_connect
. 旧 API 中的相同代码是:
$link = mysql_connect($host, $user, $password);
mysql_select_db($dbName, $link);
mysql_query('SET NAMES utf8');
Run Code Online (Sandbox Code Playgroud)
如果您的 PHP 代码依赖于 php.ini 中定义的默认参数的隐式连接,那么您现在必须打开 MySQLi 连接并在您的代码中传递参数,然后提供所有过程函数的连接链接或使用 OOP 样式。
有关更多信息,请参阅文章:如何使用 mysqli 正确连接
这是一个很大的。MySQL 在 MySQL 4.1 (2004) 中添加了对原生预准备语句的支持。准备好的语句是防止 SQL 注入的最好方法。对原生准备好的语句的支持被添加到 PHP 中是合乎逻辑的。只要数据需要与 SQL 语句一起传递(即WHERE
,INSERT
或者UPDATE
是通常的用例),就应该使用准备好的语句。
旧的 MySQL API 有一个函数来转义 SQL 中使用的字符串,称为mysql_real_escape_string
,但它从来没有用于防止 SQL 注入,自然不应该用于此目的。
新的 MySQLi APImysqli_real_escape_string
为向后兼容性提供了一个替代功能,它与旧的存在相同的问题,因此除非准备好的语句不可用,否则不应使用。
旧的 mysql_* 方式:
$login = mysql_real_escape_string($_POST['login']);
$result = mysql_query("SELECT * FROM users WHERE user='$login'");
Run Code Online (Sandbox Code Playgroud)
准备好的语句方式:
$stmt = $mysqli->prepare('SELECT * FROM users WHERE user=?');
$stmt->bind_param('s', $_POST['login']);
$stmt->execute();
$result = $stmt->get_result();
Run Code Online (Sandbox Code Playgroud)
MySQLi 中的预处理语句对于初学者来说可能看起来有点令人反感。如果您正在开始一个新项目,那么决定使用更强大、更简单的PDO API 可能是个好主意。
一些老派的 PHP 开发人员习惯于手动检查 SQL 错误并将它们直接显示在浏览器中作为调试的手段。但事实证明,这种做法不仅繁琐,而且存在安全隐患。幸运的是 MySQLi 改进了错误报告功能。
MySQLi 能够将它遇到的任何错误报告为 PHP 异常。PHP 异常会在脚本中冒泡,如果未处理将立即终止它,这意味着在错误之后不会执行任何语句。该异常将触发 PHP 致命错误,并将表现为任何由 PHP 核心触发的错误,并遵循display_errors
和log_errors
设置。要启用 MySQLi 异常mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
,请在打开数据库连接之前使用该行并插入它。
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
Run Code Online (Sandbox Code Playgroud)
如果您习惯于编写代码,例如:
$result = mysql_query('SELECT * WHERE 1=1');
if (!$result) {
die('Invalid query: ' . mysql_error());
}
Run Code Online (Sandbox Code Playgroud)
或者
$result = mysql_query('SELECT * WHERE 1=1') or die(mysql_error());
Run Code Online (Sandbox Code Playgroud)
你不再需要die()
在你的代码中。
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
$result = $mysqli->query('SELECT * FROM non_existent_table');
// The following line will never be executed due to the mysqli_sql_exception being thrown above
foreach ($result as $row) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因您不能使用异常,MySQLi 具有等效的错误检索功能。您可以使用mysqli_connect_error()
来检查连接错误和mysqli_error($mysqli)
任何其他错误。注意强制参数mysqli_error($mysqli)
或坚持 OOP 风格并使用$mysqli->error
.
$result = $mysqli->query('SELECT * FROM non_existent_table') or trigger_error($mysqli->error, E_USER_ERROR);
Run Code Online (Sandbox Code Playgroud)
更多解释请看这些帖子:
mysqli or die,do it have to die?
不同环境下如何获取MySQLi错误信息?
不幸的是,并不是每个函数mysql_*
在 MySQLi 中都有对应的函数,只是在名称和连接链接中添加了一个“i”作为第一个参数。以下是其中一些的列表:
mysql_client_encoding()
已被替换 mysqli_character_set_name($mysqli)
mysql_create_db
没有对应物。使用准备好的语句或mysqli_query
代替mysql_drop_db
没有对应物。使用准备好的语句或mysqli_query
代替mysql_db_name
&mysql_list_dbs
支持已被删除,转而支持 SQLSHOW DATABASES
mysql_list_tables
支持已被删除,转而支持 SQL SHOW TABLES FROM dbname
mysql_list_fields
支持已被删除,转而支持 SQL SHOW COLUMNS FROM sometable
mysql_db_query
->mysqli_select_db()
然后使用查询或在查询中指定数据库名称mysql_fetch_field($result, 5)
-> 中不存在第二个参数(偏移量)mysqli_fetch_field
。您可以使用mysqli_fetch_field_direct
记住返回的不同结果mysql_field_flags
, mysql_field_len
, mysql_field_name
, mysql_field_table
& mysql_field_type
-> 已替换为mysqli_fetch_field_direct
mysql_list_processes
已被删除。如果您需要线程 ID,请使用mysqli_thread_id
mysql_pconnect
已被替换mysqli_connect()
为p:
主机前缀mysql_result
->mysqli_data_seek()
与mysqli_field_seek()
和结合使用mysqli_fetch_field()
mysql_tablename
支持已被删除,转而支持 SQL SHOW TABLES
mysql_unbuffered_query
已被删除。有关缓冲和非缓冲查询的更多信息,请参阅本文小智 15
我总是处理这个最简单的方法
其中$ con = mysqli_connect($ serverName,$ dbusername,$ dbpassword);
按以下顺序更换3个步骤
这对我来说每次都适用
Tom*_*uba 14
我创建了一个名为 Rector的工具,用于处理即时升级。还有mysql吗?mysqli设置。
它处理:
函数重命名
不断重命名
切换参数
非 1:1 函数调用更改,例如
$data = mysql_db_name($result, $row);
Run Code Online (Sandbox Code Playgroud)
?
mysqli_data_seek($result, $row);
$fetch = mysql_fetch_row($result);
$data = $fetch[0];
Run Code Online (Sandbox Code Playgroud)
composer require rector/rector --dev
// or in case of composer conflicts
composer require rector/rector-prefixed --dev
Run Code Online (Sandbox Code Playgroud)
rector.php
在项目根目录下创建Mysql转Mysqli设置<?php
use Rector\Core\Configuration\Option;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters->set(Option::SETS, [
SetList::MYSQL_TO_MYSQLI,
]);
};
Run Code Online (Sandbox Code Playgroud)
vendor/bin/rector process src --dry-run
Run Code Online (Sandbox Code Playgroud)
vendor/bin/rector process src
Run Code Online (Sandbox Code Playgroud)
我已经在 2 个大型 PHP 项目上运行过它,并且运行良好。
小智 5
对于大型项目,需要更改许多文件,并且如果以前的PHP项目版本为5.6,而新的PHP版本为7.1,则可以创建一个新文件sql.php并将其包含在标题中或在所有使用它的位置使用时间和需要sql连接。例如:
//local
$sql_host = "localhost";
$sql_username = "root";
$sql_password = "";
$sql_database = "db";
$mysqli = new mysqli($sql_host , $sql_username , $sql_password , $sql_database );
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
// /* change character set to utf8 */
if (!$mysqli->set_charset("utf8")) {
printf("Error loading character set utf8: %s\n", $mysqli->error);
exit();
} else {
// printf("Current character set: %s\n", $mysqli->character_set_name());
}
if (!function_exists('mysql_real_escape_string')) {
function mysql_real_escape_string($string){
global $mysqli;
if($string){
// $mysqli = new mysqli($sql_host , $sql_username , $sql_password , $sql_database );
$newString = $mysqli->real_escape_string($string);
return $newString;
}
}
}
// $mysqli->close();
$conn = null;
if (!function_exists('mysql_query')) {
function mysql_query($query) {
global $mysqli;
// echo "DAAAAA";
if($query) {
$result = $mysqli->query($query);
return $result;
}
}
}
else {
$conn=mysql_connect($sql_host,$sql_username, $sql_password);
mysql_set_charset("utf8", $conn);
mysql_select_db($sql_database);
}
if (!function_exists('mysql_fetch_array')) {
function mysql_fetch_array($result){
if($result){
$row = $result->fetch_assoc();
return $row;
}
}
}
if (!function_exists('mysql_num_rows')) {
function mysql_num_rows($result){
if($result){
$row_cnt = $result->num_rows;;
return $row_cnt;
}
}
}
if (!function_exists('mysql_free_result')) {
function mysql_free_result($result){
if($result){
global $mysqli;
$result->free();
}
}
}
if (!function_exists('mysql_data_seek')) {
function mysql_data_seek($result, $offset){
if($result){
global $mysqli;
return $result->data_seek($offset);
}
}
}
if (!function_exists('mysql_close')) {
function mysql_close(){
global $mysqli;
return $mysqli->close();
}
}
if (!function_exists('mysql_insert_id')) {
function mysql_insert_id(){
global $mysqli;
$lastInsertId = $mysqli->insert_id;
return $lastInsertId;
}
}
if (!function_exists('mysql_error')) {
function mysql_error(){
global $mysqli;
$error = $mysqli->error;
return $error;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
131796 次 |
最近记录: |