Как изменить mysql на mysqli?
Основываясь на этом коде ниже, я использую для регулярного 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;
}
?>
Ответы
Ответ 1
Первое, что нужно сделать, вероятно, будет заменить каждый вызов функции mysql_*
его эквивалентным mysqli_*
, по крайней мере, если вы захотите использовать процедурный API - что было бы проще, учитывая, что у вас уже есть некоторый код на основе на MySQL API, который является процедурным.
Чтобы помочь с этим, Сводка функций расширения MySQLi определенно окажется полезной.
Например:
Примечание: для некоторых функций вам может потребоваться тщательно проверить параметры: может быть, есть некоторые различия здесь и там - но не так много, я бы сказал: и mysql, и mysqli основаны на одной и той же библиотеке (libmysql; по крайней мере, для PHP & lt; = 5.2)
Например:
- с mysql вы должны использовать
mysql_select_db
после подключения, чтобы указать, к какой базе данных вы хотите выполнять свои запросы
- С другой стороны, mysqli позволяет указать это имя базы данных в качестве четвертого параметра для
mysqli_connect
.
- Тем не менее, есть также
mysqli_select_db
функция, которую вы можете использовать, если хотите.
Как только вы закончите с этим, попробуйте выполнить новую версию вашего скрипта... И проверьте, все ли работает; если нет... Время для поиска ошибок ;-)
Ответ 2
(Я понимаю, что это старый, но он все еще подходит...)
Если вы замените mysql_*
на mysqli_*
, то имейте в виду, что для всей загрузки функций mysqli_*
требуется передать ссылку базы данных.
например:.
mysql_query($query)
становится
mysqli_query($link, $query)
I.e., требуется большая проверка.
Ответ 3
Самый простой способ, которым я всегда справляюсь
$con = mysqli_connect($serverName,$dbusername,$dbpassword);
3 шага замены в следующем порядке
- Все " mysql_select_db ( " с " mysqli_select_db ($ con, "
- Все " mysql_query ( " с " mysqli_query ($ con ") и
- Все " mysql_ " с " mysqli_ ".
Это работает для меня каждый раз
Ответ 4
Я бы рекомендовал использовать PDO для доступа к SQL.
Тогда это всего лишь случай изменения драйвера и обеспечения работы SQL на новом бэкэнде. Теоретически. Перенос данных - это другая проблема.
Абстрактный доступ к базе данных отличный.
Ответ 5
В случае больших проектов много файлов для изменения, а также если предыдущая версия проекта PHP была 5.6, а новая - 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;
}
}
Ответ 6
mysql_*
руководство по обновлению функций mysql_*
до MySQLi API
Причиной нового расширения mysqli стало использование новых функций, доступных в системах MySQL версий 4.1.3 и новее. При изменении существующего кода с mysql_*
на mysqli API вы должны воспользоваться этими улучшениями, иначе ваши усилия по обновлению могут mysql_*
напрасными.
Расширение mysqli имеет ряд преимуществ, ключевые улучшения по сравнению с расширением mysql:
- Объектно-ориентированный интерфейс
- Поддержка подготовленных заявлений
- Расширенные возможности отладки
При обновлении функций mysql_*
до MySQLi важно учитывать эти функции, а также некоторые изменения в способе использования этого API.
1. Объектно-ориентированный интерфейс и процедурные функции.
Новый объектно-ориентированный интерфейс mysqli является большим улучшением по сравнению со старыми функциями и может сделать ваш код чище и менее восприимчивым к опечаткам. Существует также процедурная версия этого API, но его использование не рекомендуется, так как это приводит к менее читаемому коду, который более подвержен ошибкам.
Чтобы открыть новое соединение с базой данных с MySQLi, вам нужно создать новый экземпляр класса MySQLi.
$mysqli = new \mysqli($host, $user, $password, $dbName);
$mysqli->set_charset('utf8mb4');
Используя процедурный стиль, это выглядело бы так:
$mysqli = mysqli_connect($host, $user, $password, $dbName);
mysqli_set_charset($mysqli, 'utf8mb4');
Имейте в виду, что только первые 3 параметра такие же, как в mysql_connect
. Тот же код в старом API будет:
$link = mysql_connect($host, $user, $password);
mysql_select_db($dbName, $link);
mysql_query('SET NAMES utf8');
Если ваш PHP-код основывался на неявном соединении с параметрами по умолчанию, определенными в php.ini, теперь вам нужно открыть соединение MySQLi, передав параметры в вашем коде, а затем предоставить ссылку на соединение со всеми процедурными функциями или использовать стиль ООП.
Для получения дополнительной информации см. Статью: Как правильно подключиться с помощью mysqli
2. Поддержка подготовленных заявлений
Это большой. В MySQL добавлена поддержка встроенных операторов в MySQL 4.1 (2004). Подготовленные операторы - лучший способ предотвратить внедрение SQL. Было логично, что в PHP была добавлена поддержка нативно подготовленных операторов. Подготовленные операторы следует использовать всякий раз, когда данные должны передаваться вместе с оператором SQL (т. WHERE
, INSERT
или UPDATE
являются обычными вариантами использования).
У старого MySQL API была функция для экранирования строк, используемых в SQL, называемая mysql_real_escape_string
, но она никогда не предназначалась для защиты от SQL-инъекций и, естественно, не должна использоваться для этой цели.
Новый MySQLi API предлагает замещающую функцию mysqli_real_escape_string
для обратной совместимости, которая страдает теми же проблемами, что и старая, и поэтому ее не следует использовать, если готовые операторы недоступны.
Старый способ mysql_ *:
$login = mysql_real_escape_string($_POST['login']);
$result = mysql_query("SELECT * FROM users WHERE user='$login'");
Подготовленный способ постановки:
$stmt = $mysqli->prepare('SELECT * FROM users WHERE user=?');
$stmt->bind_param('s', $_POST['login']);
$stmt->execute();
$result = $stmt->get_result();
Подготовленные заявления в MySQLi могут показаться немного неприятными для начинающих. Если вы начинаете новый проект, тогда решение об использовании более мощного и простого API PDO может быть хорошей идеей.
3. Расширенные возможности отладки
Некоторые разработчики 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');
Если вы привыкли писать такой код:
$result = mysql_query('SELECT * WHERE 1=1');
if (!$result) {
die('Invalid query: ' . mysql_error());
}
или же
$result = mysql_query('SELECT * WHERE 1=1') or die(mysql_error());
вам больше не нужно 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) {
// ...
}
Если по какой-то причине вы не можете использовать исключения, MySQLi имеет эквивалентные функции для поиска ошибок. Вы можете использовать mysqli_connect_error()
для проверки ошибок подключения и mysqli_error($mysqli)
для любых других ошибок. Обратите внимание на обязательный аргумент в mysqli_error($mysqli)
или, в качестве альтернативы, придерживайтесь стиля ООП и используйте $mysqli->error
.
$result = $mysqli->query('SELECT * FROM non_existent_table') or trigger_error($mysqli->error, E_USER_ERROR);
Смотрите эти сообщения для более подробного объяснения:
MySQL или умереть, он должен умереть?
Как получить информацию об ошибках MySQLi в разных средах?
4. Другие изменения
К сожалению, не каждая функция из mysql_*
имеет свой аналог в MySQLi только с добавленным "i" в имени и связи в качестве первого параметра. Вот список некоторых из них:
-
mysql_client_encoding()
был заменен mysqli_character_set_name($mysqli)
-
mysql_create_db
не имеет аналога. mysqli_query
этого используйте подготовленные операторы или mysqli_query
-
mysql_drop_db
не имеет аналогов. mysqli_query
этого используйте подготовленные операторы или mysqli_query
-
mysql_db_name
& mysql_list_dbs
поддержка была прекращена в пользу SQL SHOW 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
был удален. Если вам нужен идентификатор потока, используйте mysqli_thread_id
-
mysql_pconnect
был заменен mysqli_connect()
с префиксом p:
host -
mysql_result
→ использовать mysqli_data_seek()
в сочетании с mysqli_field_seek()
и mysqli_fetch_field()
- Поддержка
mysql_tablename
прекращена в пользу SQL. SHOW TABLES
-
mysql_unbuffered_query
был удален. См. Эту статью для получения дополнительной информации Буферизованные и Небуферизованные запросы
Ответ 7
Если у вас есть много файлов для изменения в ваших проектах, вы можете создавать функции с теми же именами, что и функции mysql,
и в функциях сделать преобразование, как этот код:
$sql_host = "your host";
$sql_username = "username";
$sql_password = "password";
$sql_database = "database";
$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();
}
function mysql_query($query){
$result = $mysqli->query($query);
return $result;
}
function mysql_fetch_array($result){
if($result){
$row = $result->fetch_assoc();
return $row;
}
}
function mysql_num_rows($result){
if($result){
$row_cnt = $result->num_rows;;
return $row_cnt;
}
}
Ответ 8
Краткая версия преобразования mysql в mysqli
mysql_connect ---> mysqli_connect
mysql_select_db ---> mysqli_select_db
mysql_error ---> mysqli_connect_error()
mysql_query ---> mysqli_query
mysql_fetch_assoc ---> mysqli_fetch_assoc
Ответ 9
Вот полное руководство, как сделать это быстро, если вам нужно снова сделать worgking веб-сайтом после обновления PHP. Я использовал его после обновления хостинга для своих клиентов с версии 5.4 (OMG !!!) до версии 7.x PHP.
Это обходной путь, и лучше переписать весь код, используя PDO или mysqli Class.
1. Определение соединения
Прежде всего, вам нужно поместить соединение в новую переменную $link
или $con
, или что угодно.
пример
Измените соединение с:
@mysql_connect($host, $username, $password) or die("Error message...");
@mysql_select_db($db);
или же
@mysql_connect($host, $username, $password, $db) or die("Error message...");
чтобы:
$con = mysqli_connect($host, $username, $password, $db) or die("Error message...");
2. mysql_ * модификация
С Notepad++ я использую "Найти в файлах" (Ctrl + Shift + f):
![Search and replace notepad++ box]()
в следующем порядке я выбираю "Заменить в файлах":
-
mysql_query (-> mysqli_query ($ con,
-
mysql_error() → mysqli_error ($ con)
-
mysql_close() → mysqli_close ($ con)
-
mysql_ → mysqli_
3. корректировки
если вы получаете ошибки, это может быть потому, что ваш $ con не доступен из ваших функций.
Вам нужно добавить global $con;
во всех ваших функциях, например:
function my_function(...) {
global $con;
...
}
В классе SQL вы поместите соединение с $this->con
вместо $con
. и заменять его при каждом вызове функций (например: mysqli_query($con, $query);
)
Надеюсь, поможет.
Ответ 10
Хотя этой теме уже десять лет, мне все еще часто требуется "создавать патч" для существующих приложений, которые опираются на расширение mysql
- первоначальные программисты были слишком ленивы, чтобы реорганизовать весь свой код, и просто сказать клиентам, что они должны запустить доступна последняя версия PHP 5.6.
PHP 5.6 официально объявлен устаревшим; другими словами, у разработчиков было десятилетие, чтобы избавиться от своих зависимостей от mysql
и перейти к PDO
(или, ну, mysqli
...). Но... изменение такого большого количества старого кода стоит дорого, и не каждый менеджер готов платить за бесчисленные часы, чтобы "исправить" проекты с десятками тысяч строк.
Я искал много решений, и в моем случае я часто использовал решение, представленное @esty-shlomovitz - но в то же время я нашел что-то еще лучше:
https://www.phpclasses.org/package/9199-PHP-Replace-mysql-functions-using-the-mysqli-extension.html
(вам необходимо зарегистрироваться, чтобы скачать его, но это займет всего минуту)
Это всего лишь два файла, которые служат заменой для всего расширения mysql
и очень умно эмулируют практически все (используя mysqli
) без необходимости беспокоиться об этом. Конечно, это не идеальное решение, но, скорее всего, оно будет работать в 99% случаев.
Кроме того, хороший учебник по работе с миграцией (со списком многих распространенных ошибок при миграции) также можно найти здесь: https://www.phpclasses.org/blog/package/9199/post/3-Smoothly-Migrate-your-PHP-Code-using-the-Old-MySQL-extension-to-MySQLi.html
(если вы читаете это в 2030 году, а сайт PHPclasses не работает, вы всегда можете попробовать archive.org :-)
Ответ 11
Вы можете выполнить массовый поиск и замену, используя notepad++, для меня это сработало:
Найти: mysql_
Заменить: mysqli_
Найти: _query (
Заменить: _query ($ conn,
Необходимо изменить следующее, но это зависит от того, как вы подключаетесь...
Обновите строку подключения в config.php следующим образом:
$conn = mysqli_connect($db_host, $db_username, $db_password, $db_name) or die("Unable to Connect");
Надеюсь это поможет.
Ответ 12
Мой простой сценарий оболочки, чтобы изменить mysql на mysqli во всех файлах php в каталоге:
for I in *.php
do
cat $I | sed s/'mysql_select_db('/'mysqli_select_db($link,'/ |
sed s/'mysql_query('/'mysqli_query($link,'/|
sed s/mysql_/mysqli_/ > tmpf;
mv tmpf $I;
done