Web

Как изменить mysql на mysqli?

На основе приведенного ниже кода, который я использую для обычного mysql, как я могу преобразовать его для использования mysqli?

Это так же просто, как перейти с mysql_query($sql); на mysqli_query($sql);?

<?php

//в моем заголовочном файле, который включается в каждую страницу, есть следующее

$DB["dbName"] = "emails";

$DB["host"]   = "localhost";

$DB["user"]   = "root";

$DB["pass"]   = "";

$link = mysql_connect($DB['host'], $DB['user'], $DB['pass']) or die("<center>Произошла внутренняя ошибка. Пожалуйста, сообщите о следующей ошибке веб-мастеру.<br><br>".mysql_error()."'</center>");

mysql_select_db($DB['dbName']);

// функция из файла функций, через которую я запускаю запрос mysql на любой странице.

function executeQuery($sql) {

    $result = mysql_query($sql);

    if (mysql_error()) {

        $error = '<BR><center><font size="+1" face="arial" color="red">Произошла внутренняя ошибка.<BR>Ошибка была зарегистрирована для просмотра</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>MySQL вернул ошибку</b><br>' . mysql_error();

        }

        die($error);

    }

    return $result;

}

 

// пример запроса, выполняемого на любой странице сайта с помощью функции executeQuery

$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_connect будет заменен на mysqli_connect

  • mysql_error будет заменен на mysqli_error и/или mysqli_connect_error, в зависимости от контекста

  • mysql_query будет заменен на mysqli_query

  • и так далее

Примечание: для некоторых функций вам может потребоваться тщательно проверить параметры: возможно, есть некоторые различия здесь и там, но не так много, я бы сказал: и mysql, и mysqli основаны на одной и той же библиотеке (libmysql; по крайней мере для PHP <= 5.2).

Например:

  • с mysql вы должны использовать mysql_select_db один раз для подключения, чтобы указать, к какой базе данных вы хотите выполнять свои запросы;

  • mysqli, с другой стороны, позволяет вам указать это имя базы данных в качестве четвертого параметра для mysqli_connect;

  • тем не менее есть также функция mysqli_select_db, которую вы можете использовать, если хотите.


Как только вы закончите с этим, попробуйте запустить новую версию вашего скрипта. 

 

Ответ 2

Полное руководство по обновлению mysql_* функций на MySQLi API

Причина создания нового расширения mysqli заключалась в том, чтобы воспользоваться преимуществами новых функций, имеющихся в системах MySQL версии 4.1.3 и новее. При изменении существующего кода с mysql_* API на mysqli вы должны воспользоваться этими улучшениями, иначе ваши усилия по обновлению могут быть напрасными.

Расширение 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, передав параметры в вашем коде, а затем предоставить ссылку на соединение для всех процедурных функций или использовать стиль ООП.

 

2. Поддержка подготовленных отчетов

Это большой вопрос. MySQL добавил поддержку собственных подготовленных операторов в MySQL 4.1. Подготовленные операторы лучший способ предотвратить SQL-инъекцию. Было вполне логично, что в PHP была добавлена поддержка собственных подготовленных операторов. Подготовленные операторы следует использовать всякий раз, когда данные должны быть переданы вместе с вызовом SQL (то есть WHEREINSERT или 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 могут показаться немного сложными для новичков. Если вы начинаете новый проект, то хорошей идеей может быть решение использовать более мощный и простой PDO API.

 

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');

// Следующая строка никогда не будет выполнена из-за выброшенного выше исключения mysqli_sql_exception

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);

 

4. Прочие изменения

К сожалению, не каждая функция from mysql_* имеет свой аналог в MySQLi только с добавлением «i» в имени и ссылке на соединение в качестве первого параметра. Вот список некоторых из них:

  • mysql_client_encoding() был заменен на mysqli_character_set_name($mysqli)

  • mysql_create_db не имеет аналогов. Используйте подготовленные операторы или mysqli_query вместо этого

  • mysql_drop_db не имеет аналогов. Используйте подготовленные операторы или mysqli_query вместо этого

  • mysql_db_namemysql_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_flagsmysql_field_lenmysql_field_namemysql_field_tablemysql_field_type-> заменено на mysqli_fetch_field_direct

  • mysql_list_processes был удален. Если вам нужен идентификатор потока, используйте 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 был удален

 

Ответ 3

В случае больших проектов нужно изменить много файлов, а также, если предыдущая версия проекта PHP была 5.6, а новая 7.1, вы можете создать новый файл sql.php и включить его в заголовок или где-нибудь, где вы его используете. Например:

$sql_host     = "localhost";      

$sql_username = "root";    

$sql_password = "";       

$sql_database = "db"; 

$mysqli = new mysqli($sql_host , $sql_username , $sql_password , $sql_database );

/* проверка соединения */

if ($mysqli->connect_errno) {

    printf("Connect failed: %s\n", $mysqli->connect_error);

    exit();

}

// /* изменение набора символов на utf8 */

if (!$mysqli->set_charset("utf8")) {

    printf("Ошибка загрузки набора символов utf8: %s\n", $mysqli->error);

    exit();

} else {

    // printf("Текущий набор символов установлен на: %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 "Бла-бла";

        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;

    }

}

Схожие статьи

Web

Когда я использую Plesk, отображается фатальная ошибка PHP

Web

Как настроить права доступа к файлам в Laravel?

Web

PHP REST API POSTMAN. Фатальная ошибка Uncaught PDOException: SQLSTATE[42000]: Синтаксическая ошибка или нарушение доступа: 1064 У вас ошибка в синтаксисе SQL

Web

Почему команда PECL выдает длинный список ошибок

×