На основе приведенного ниже кода, который я использую для обычного 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 (то есть 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 могут показаться немного сложными для новичков. Если вы начинаете новый проект, то хорошей идеей может быть решение использовать более мощный и простой 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_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:префиксом хоста
в 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