Каковы технические причины, по которым нельзя использовать функции mysql_*
? (например, mysql_query()
, mysql_connect()
или mysql_real_escape_string()
)?
Зачем мне использовать что-то еще, даже если они работают на моем сайте?
Если они не работают на моем сайте, почему я получаю такие ошибки, как
Предупреждение: mysql_connect (): нет такого файла или каталога
14 ответов
Во-первых, давайте начнем со стандартного комментария, который мы даем всем:
Пожалуйста, не используйте функции
mysql_*
в новом коде . Они больше не поддерживаются и официально устарели. Видите красное поле ? Узнайте о подготовленных операторах взамен и используйте PDO или MySQLi - эта статья поможет вам решить, какой. Если вы выберете PDO, вот хорошее руководство.
Давайте рассмотрим это предложение за предложением и объясним:
Они больше не поддерживаются и официально не поддерживаются
Это означает, что сообщество PHP постепенно прекращает поддержку этих очень старых функций. Скорее всего, их не будет в будущей (недавней) версии PHP! Продолжение использования этих функций может сломать ваш код в (не так уж) далеком будущем.
НОВИНКА! - ext / mysql теперь официально устарел с PHP 5.5! < / сильный>
Новее! ext / mysql удален из PHP 7 .
Вместо этого вам следует узнать о заранее подготовленных заявлениях
Расширение
mysql_*
не поддерживает подготовленные операторы , что является (среди прочего) очень эффективной контрмерой против внедрения SQL . Он исправил очень серьезную уязвимость в приложениях, зависящих от MySQL, которая позволяет злоумышленникам получить доступ к вашему скрипту и выполнить любой возможный запрос к вашей базе данных.Для получения дополнительной информации см. Как предотвратить SQL-инъекцию в PHP ?
Видите красную рамку?
Когда вы переходите на любую страницу руководства по функциям
mysql
, вы видите красную рамку, поясняющую, что ее больше не следует использовать.Используйте PDO или MySQLi
Существуют лучшие, более надежные и хорошо продуманные альтернативы: PDO - объект базы данных PHP , который предлагает полный подход ООП к взаимодействию с базой данных, и MySQLi , специфичный для MySQL улучшение.
IN (...) construct
.
Говоря о технических причинах, их всего несколько, очень конкретных и редко используемых. Скорее всего, вы никогда в жизни ими не воспользуетесь.
Может быть, я слишком невежественен, но у меня никогда не было возможности использовать такие вещи, как
- неблокирующие, асинхронные запросы
- хранимые процедуры, возвращающие несколько наборов результатов
- Шифрование (SSL)
- Сжатие
Если они вам нужны - это, несомненно, технические причины, чтобы отойти от расширения mysql к чему-то более стильному и современному.
Тем не менее, есть и некоторые нетехнические проблемы, которые могут немного усложнить вашу работу
- дальнейшее использование этих функций с современными версиями PHP приведет к появлению уведомлений об устаревшем уровне. Их просто можно отключить.
- в отдаленном будущем они могут быть удалены из стандартной сборки PHP. Это тоже не имеет большого значения, поскольку mydsql ext будет перемещен в PECL, и каждый хостер будет счастлив скомпилировать PHP с ним, поскольку они не хотят терять клиентов, чьи сайты работали десятилетиями.
- сильное сопротивление со стороны сообщества Stackoverflow. Каждый раз, когда вы упоминаете об этих честных функциях, вам говорят, что они находятся под строгим табу.
- будучи средним пользователем PHP, вы, скорее всего, ошибетесь и ошибетесь в использовании этих функций. Просто из-за всех этих многочисленных руководств и руководств, которые учат вас неправильному пути. Не сами функции - я должен это подчеркнуть, - а то, как они используются.
Последняя проблема является проблемой.
Но, на мой взгляд, и предлагаемое решение ничем не лучше.
Мне кажется слишком идеалистической мечтой, что все эти пользователи PHP сразу научатся правильно обрабатывать SQL-запросы. Скорее всего, они просто механически изменили бы mysql_ * на mysqli_ *, оставив подход без изменений . Тем более, что mysqli делает использование подготовленных операторов невероятно болезненным и хлопотным.
Не говоря уже о том, что родные подготовленные операторы недостаточно для защиты от инъекций SQL, и ни mysqli, ни PDO не предлагают решения.
Поэтому вместо того, чтобы бороться с этим честным расширением, я предпочел бы бороться с неправильными методами и обучать людей правильным путям.
Кроме того, есть несколько ложных или несущественных причин, например
- Не поддерживает хранимые процедуры (мы использовали
mysql_query("CALL my_proc");
целую вечность) - Не поддерживает транзакции (как указано выше)
- Не поддерживает множественные утверждения (кому они нужны?)
- Не находится в активной разработке (и что? Насколько это влияет на вас ?)
- Отсутствует объектно-ориентированный интерфейс (на создание - дело нескольких часов)
- Не поддерживает подготовленные операторы или параметризованные запросы.
Последнее - интересный момент. Хотя mysql ext не поддерживает родные подготовленные операторы, они не требуются для обеспечения безопасности. Мы можем легко подделать подготовленные операторы, используя ручные заполнители (как это делает PDO):
function paraQuery()
{
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val)
{
$args[$key] = mysql_real_escape_string($val);
}
$query = vsprintf($query, $args);
$result = mysql_query($query);
if (!$result)
{
throw new Exception(mysql_error()." [$query]");
}
return $result;
}
$query = "SELECT * FROM table where a=%s AND b LIKE %s LIMIT %d";
$result = paraQuery($query, $a, "%$b%", $limit);
вуаля , все параметризовано и безопасно.
Но ладно, если вам не нравится красное поле в руководстве, возникает проблема выбора: mysqli или PDO?
Что ж, ответ будет таким:
- Если вы понимаете необходимость использования уровня абстракции базы данных и ищете API для его создания, mysqli - очень хороший выбор, поскольку он действительно поддерживает многие специфичные для mysql функции. .
Если, как и подавляющее большинство разработчиков PHP, вы используете необработанные вызовы API прямо в коде приложения (что по сути является неправильной практикой) - PDO - единственный выбор , поскольку это расширение претендует на роль не просто API. а скорее полу-DAL, все еще неполный, но предлагающий множество важных функций, две из которых существенно отличают PDO от mysqli:
- в отличие от mysqli, PDO может связывать заполнители по значению, что позволяет выполнять динамически формируемые запросы без нескольких экранов довольно беспорядочного кода.
- в отличие от mysqli, PDO всегда может возвращать результат запроса в виде простого обычного массива, в то время как mysqli может делать это только на установках mysqlnd.
Итак, если вы средний пользователь PHP и хотите избавить себя от множества головных болей при использовании собственных подготовленных операторов, PDO - опять же - единственный выбор.
Однако PDO - тоже не серебряная пуля, и у нее есть свои трудности.
Итак, я написал решения для всех распространенных ошибок и сложных случаев в вики по тегам PDO
Тем не менее, все, кто говорит о расширениях, всегда упускают из виду 2 важных факта о Mysqli и PDO:
Подготовленное заявление не является серебряной пулей . Есть динамические идентификаторы, которые нельзя связать с помощью подготовленных операторов. Существуют динамические запросы с неизвестным количеством параметров, что затрудняет построение запроса.
В коде приложения не должно быть функций mysqli_ * или PDO.
Между ними и кодом приложения должен быть уровень абстракции , который будет выполнять всю грязную работу по привязке, циклу, обработке ошибок и т. Д. Внутри, делая код приложения СУХИМ и чистым. Особенно для сложных случаев, таких как динамическое построение запросов.
Итак, просто переключиться на PDO или mysqli недостаточно. Вместо вызова необработанных функций API в их коде нужно использовать ORM, построитель запросов или любой другой класс абстракции базы данных.
И наоборот - если у вас есть уровень абстракции между кодом вашего приложения и mysql API - на самом деле не имеет значения, какой движок используется. Вы можете использовать mysql ext до тех пор, пока он не станет устаревшим, а затем легко переписать абстракцию в другой движок, сохранив весь код приложения без изменений .
Вот несколько примеров, основанных на моем классе safemysql, чтобы показать, как это класс абстракции должен быть:
$city_ids = array(1,2,3);
$cities = $db->getCol("SELECT name FROM cities WHERE is IN(?a)", $city_ids);
Сравните эту единственную строку с объемом кода, который вам понадобится для PDO.
Затем сравните с сумасшедшим объемом кода, который вам понадобится, с необработанными подготовленными операторами Mysqli. Обратите внимание, что обработка ошибок, профилирование и ведение журнала запросов уже встроены и работают.
$insert = array('name' => 'John', 'surname' => "O'Hara");
$db->query("INSERT INTO users SET ?u", $insert);
Сравните это с обычными вставками PDO, когда каждое отдельное имя поля повторяется от шести до десяти раз - во всех этих многочисленных именованных заполнителях, привязках и определениях запросов.
Другой пример:
$data = $db->getAll("SELECT * FROM goods ORDER BY ?n", $_GET['order']);
Вряд ли вы найдете пример для PDO, который справился бы с таким практическим случаем.
И это будет слишком многословно и, скорее всего, небезопасно.
Итак, еще раз - вас должен беспокоить не только необработанный драйвер, но и класс абстракции, полезный не только для глупых примеров из руководства для начинающих, но и для решения любых реальных проблем.
mysql_*
упрощает поиск уязвимостей. Поскольку PHP используется очень большим количеством начинающих пользователей, mysql_*
активно вреден на практике, даже если теоретически его можно использовать без сучка и задоринки.
everything is parameterized and safe
- он может быть параметризован, но ваша функция не использует настоящие подготовленные операторы.
Not under active development
только для этих «0,01%»? Если вы создадите что-то с этой функцией ожидания, обновите свою версию mysql через год и получите неработающую систему, я уверен, что внезапно появилось очень много людей с этими «0,01%». Я бы сказал, что deprecated
и not under active development
тесно связаны. Вы можете сказать, что для этого нет "[достойной] причины", но факт в том, что когда предлагается выбор между вариантами, no active development
почти так же плох, как deprecated
, я бы сказал?
Причин много, но, возможно, самая важная из них заключается в том, что эти функции поощряют небезопасные методы программирования, поскольку они не поддерживают подготовленные операторы. Подготовленные операторы помогают предотвратить атаки с использованием SQL-инъекций.
При использовании функций mysql_*
вы должны помнить, чтобы пользовательские параметры запускались через mysql_real_escape_string()
. Если вы забыли только в одном месте или вам удалось избежать только части ввода, ваша база данных может подвергнуться атаке.
Использование подготовленных операторов в PDO
или mysqli
сделает так, что такого рода программные ошибки будут более трудными для выполнения.
Этот ответ написан, чтобы показать, насколько тривиально обходить плохо написанный код проверки пользователя PHP, как (и с помощью чего) эти атаки работают и как заменить старые функции MySQL защищенным подготовленным оператором - и, в основном, почему пользователи StackOverflow (вероятно, с большим количеством представителей) лают на новых пользователей, задающих вопросы, чтобы улучшить их код.
Прежде всего, пожалуйста, не стесняйтесь создавать эту тестовую базу данных MySQL (я назвал мой Prep):
mysql> create table users(
-> id int(2) primary key auto_increment,
-> userid tinytext,
-> pass tinytext);
Query OK, 0 rows affected (0.05 sec)
mysql> insert into users values(null, 'Fluffeh', 'mypass');
Query OK, 1 row affected (0.04 sec)
mysql> create user 'prepared'@'localhost' identified by 'example';
Query OK, 0 rows affected (0.01 sec)
mysql> grant all privileges on prep.* to 'prepared'@'localhost' with grant option;
Query OK, 0 rows affected (0.00 sec)
После этого мы можем перейти к вашему PHP-коду.
Предположим, что следующий скрипт является процессом проверки для администратора на веб-сайте (упрощенный, но работающий, если вы копируете и используете его для тестирования):
<?php
if(!empty($_POST['user']))
{
$user=$_POST['user'];
}
else
{
$user='bob';
}
if(!empty($_POST['pass']))
{
$pass=$_POST['pass'];
}
else
{
$pass='bob';
}
$database='prep';
$link=mysql_connect('localhost', 'prepared', 'example');
mysql_select_db($database) or die( "Unable to select database");
$sql="select id, userid, pass from users where userid='$user' and pass='$pass'";
//echo $sql."<br><br>";
$result=mysql_query($sql);
$isAdmin=false;
while ($row = mysql_fetch_assoc($result)) {
echo "My id is ".$row['id']." and my username is ".$row['userid']." and lastly, my password is ".$row['pass']."<br>";
$isAdmin=true;
// We have correctly matched the Username and Password
// Lets give this person full access
}
if($isAdmin)
{
echo "The check passed. We have a verified admin!<br>";
}
else
{
echo "You could not be verified. Please try again...<br>";
}
mysql_close($link);
?>
<form name="exploited" method='post'>
User: <input type='text' name='user'><br>
Pass: <input type='text' name='pass'><br>
<input type='submit'>
</form>
На первый взгляд кажется вполне законным.
Пользователь должен ввести логин и пароль, верно?
Отлично, теперь введите следующее:
user: bob
pass: somePass
И представить его.
Результат выглядит следующим образом:
You could not be verified. Please try again...
Супер! Работая как положено, теперь давайте попробуем ввести действительное имя пользователя и пароль:
user: Fluffeh
pass: mypass
Удивительно! Привет пятерки со всех сторон, код правильно проверен админом. Это идеально!
Ну не совсем. Допустим, пользователь умный маленький человек. Допустим, человек - это я.
Введите в следующем:
user: bob
pass: n' or 1=1 or 'm=m
И вывод:
The check passed. We have a verified admin!
Поздравляю, вы только что разрешили мне войти в раздел ваших сверхзащищенных администраторов, указав ложное имя пользователя и ложный пароль. Серьезно, если вы мне не верите, создайте базу данных с помощью предоставленного мною кода и запустите этот PHP-код, который на первый взгляд действительно ДЕЙСТВИТЕЛЬНО проверяет имя пользователя и пароль.
Итак, в ответ, это то, почему вы кричали.
Итак, давайте посмотрим, что пошло не так, и почему я только что попал в вашу пещеру супер-админ-только-летучая мышь. Я сделал предположение и предположил, что вы не были осторожны со своими данными и просто передали их напрямую в базу данных. Я сконструировал вход таким образом, чтобы он ИЗМЕНИЛ запрос, который вы на самом деле выполняли. Итак, что это должно было быть, и чем это закончилось?
select id, userid, pass from users where userid='$user' and pass='$pass'
Это запрос, но когда мы заменяем переменные фактическими данными, которые мы использовали, мы получаем следующее:
select id, userid, pass from users where userid='bob' and pass='n' or 1=1 or 'm=m'
Посмотрите, как я сконструировал свой «пароль», чтобы он сначала закрывал одинарную кавычку вокруг пароля, а затем вводил совершенно новое сравнение? Затем для безопасности я добавил еще одну «строку», чтобы одинарная кавычка закрывалась, как и ожидалось, в исходном коде.
Однако речь идет не о людях, которые кричат на вас, а о том, как сделать ваш код более безопасным.
Итак, что пошло не так, и как мы можем это исправить?
Это классическая атака SQL-инъекций. Один из самых простых в этом отношении. По шкале векторов атаки это малыш атакует танк - и выигрывает.
Итак, как мы можем защитить ваш священный раздел администратора и сделать его красивым и безопасным? Первое, что нужно сделать, это прекратить использовать эти действительно старые и устаревшие функции mysql_*
. Я знаю, что вы следовали учебному пособию, которое вы нашли в Интернете, и оно работает, но оно старое, оно устарело, и за несколько минут я только что преодолел его, не потратив ни капельки пота.
Теперь у вас есть лучшие варианты использования mysqli_ или PDO. Я лично большой поклонник PDO, поэтому я буду использовать PDO в оставшейся части этого ответа. Есть плюсы и минусы, но лично я считаю, что плюсы намного перевешивают минусы. Его можно переносить на несколько механизмов баз данных — независимо от того, используете ли вы MySQL, Oracle или что-то еще — просто изменив строку подключения, он имеет все причудливые функции, которые мы хотим использовать, и он приятный и чистый. Мне нравится чистота.
Теперь давайте снова посмотрим на этот код, на этот раз написанный с использованием объекта PDO:
<?php
if(!empty($_POST['user']))
{
$user=$_POST['user'];
}
else
{
$user='bob';
}
if(!empty($_POST['pass']))
{
$pass=$_POST['pass'];
}
else
{
$pass='bob';
}
$isAdmin=false;
$database='prep';
$pdo=new PDO ('mysql:host=localhost;dbname=prep', 'prepared', 'example');
$sql="select id, userid, pass from users where userid=:user and pass=:password";
$myPDO = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
if($myPDO->execute(array(':user' => $user, ':password' => $pass)))
{
while($row=$myPDO->fetch(PDO::FETCH_ASSOC))
{
echo "My id is ".$row['id']." and my username is ".$row['userid']." and lastly, my password is ".$row['pass']."<br>";
$isAdmin=true;
// We have correctly matched the Username and Password
// Lets give this person full access
}
}
if($isAdmin)
{
echo "The check passed. We have a verified admin!<br>";
}
else
{
echo "You could not be verified. Please try again...<br>";
}
?>
<form name="exploited" method='post'>
User: <input type='text' name='user'><br>
Pass: <input type='text' name='pass'><br>
<input type='submit'>
</form>
Основное отличие состоит в том, что функций mysql_*
больше нет. Все это делается через объект PDO, во-вторых, используется подготовленный оператор. Вы спросите, что такое подготовленное заявление? Это способ сообщить базе данных перед выполнением запроса, какой именно запрос мы собираемся выполнить. В этом случае мы сообщаем базе данных: «Привет, я собираюсь запустить оператор выбора, требующий идентификатор, идентификатор пользователя и проход из таблицы пользователей, где идентификатор пользователя является переменной, а проход также является переменной».
Затем в операторе execute мы передаем базе данных массив со всеми переменными, которые он теперь ожидает.
Результаты фантастические. Давайте попробуем эти комбинации имени пользователя и пароля еще раз:
user: bob
pass: somePass
Пользователь не был подтвержден. Потрясающе.
Как насчет:
user: Fluffeh
pass: mypass
О, я просто немного взволнован, это сработало: проверка прошла. У нас есть проверенный админ!
Теперь, давайте попробуем данные, которые введет умный парень, чтобы попытаться обойти нашу маленькую систему проверки:
user: bob
pass: n' or 1=1 or 'm=m
На этот раз мы получаем следующее:
You could not be verified. Please try again...
Вот почему на вас кричат при публикации вопросов, потому что люди видят, что ваш код можно обойти даже без попыток. Пожалуйста, используйте этот вопрос и ответ, чтобы улучшить свой код, сделать его более безопасным и использовать текущие функции.
Наконец, это не означает, что это ИДЕАЛЬНЫЙ код. Есть много других вещей, которые вы могли бы сделать, чтобы улучшить его, например, использовать хешированные пароли, убедиться, что при хранении конфиденциальной информации в базе данных вы не храните ее в виде простого текста, иметь несколько уровней проверки - но на самом деле, если вы просто измените свой старый код, подверженный инъекциям, на этот, вы будете ХОРОШО на пути к написанию хорошего кода - и тот факт, что вы зашли так далеко и все еще читаете, дает мне надежду, что вы не только реализуете этот тип кода при написании своих веб-сайтов и приложений, но вы можете пойти и изучить те другие вещи, которые я только что упомянул, и многое другое. Пишите лучший код, который только можете, а не самый простой код, который едва работает.
mysql_*
сам по себе небезопасен, но он способствует развитию небезопасного кода из-за плохих руководств и отсутствия надлежащего API подготовки операторов.
Расширение MySQL является самым старым из трех и было оригинальным способом, который разработчики использовали для взаимодействия с MySQL. Это расширение сейчас устарело в пользу другого две альтернативы из-за улучшений сделано в более новых версиях PHP и MySQL.
MySQLi - это «улучшенное» расширение для работы с базами данных MySQL. Он использует преимущества функций, доступных в более новых версиях сервера MySQL, предоставляет разработчику как функционально-ориентированный, так и объектно-ориентированный интерфейс, а также делает несколько других отличных вещей.
PDO предлагает API, который объединяет большую часть функциональности, которая ранее была распространена среди основных расширений доступа к базам данных, т. е. MySQL, PostgreSQL, SQLite, MSSQL и т. Д. Интерфейс предоставляет программисту высокоуровневые объекты для работы с соединениями с базой данных, запросами и наборами результатов, а низкоуровневые драйверы осуществляют связь и обработку ресурсов с сервером базы данных. В PDO ведется много дискуссий и работы, и он считается подходящим методом работы с базами данных в современном профессиональном коде.
Я считаю приведенные выше ответы очень длинными, поэтому резюмирую:
Расширение mysqli имеет ряд преимуществ, основные улучшения по сравнению с расширением mysql:
- Объектно-ориентированный интерфейс
- Поддержка подготовленных отчетов
- Поддержка нескольких утверждений
- Поддержка транзакций
- Расширенные возможности отладки
- Поддержка встроенного сервера
Источник: Обзор MySQLi
Как объяснено в ответах выше, альтернативами mysql являются mysqli и PDO (объекты данных PHP).
- API поддерживает подготовленные операторы на стороне сервера: поддерживается MYSQLi и PDO
- API поддерживает подготовленные операторы на стороне клиента: поддерживается только PDO
- API поддерживает хранимые процедуры: MySQLi и PDO
- API поддерживает несколько выражений и все функции MySQL 4.1+ - поддерживается MySQLi и в основном также PDO
И MySQLi, и PDO были представлены в PHP 5.0, тогда как MySQL был представлен до PHP 3.0. Следует отметить, что MySQL включен в PHP5.x, хотя в более поздних версиях не рекомендуется.
Можно определить почти все функции mysql_*
с помощью mysqli или PDO. Просто включите их поверх своего старого PHP-приложения, и оно будет работать на PHP7. Мое решение здесь.
<?php
define('MYSQL_LINK', 'dbl');
$GLOBALS[MYSQL_LINK] = null;
function mysql_link($link=null) {
return ($link === null) ? $GLOBALS[MYSQL_LINK] : $link;
}
function mysql_connect($host, $user, $pass) {
$GLOBALS[MYSQL_LINK] = mysqli_connect($host, $user, $pass);
return $GLOBALS[MYSQL_LINK];
}
function mysql_pconnect($host, $user, $pass) {
return mysql_connect($host, $user, $pass);
}
function mysql_select_db($db, $link=null) {
$link = mysql_link($link);
return mysqli_select_db($link, $db);
}
function mysql_close($link=null) {
$link = mysql_link($link);
return mysqli_close($link);
}
function mysql_error($link=null) {
$link = mysql_link($link);
return mysqli_error($link);
}
function mysql_errno($link=null) {
$link = mysql_link($link);
return mysqli_errno($link);
}
function mysql_ping($link=null) {
$link = mysql_link($link);
return mysqli_ping($link);
}
function mysql_stat($link=null) {
$link = mysql_link($link);
return mysqli_stat($link);
}
function mysql_affected_rows($link=null) {
$link = mysql_link($link);
return mysqli_affected_rows($link);
}
function mysql_client_encoding($link=null) {
$link = mysql_link($link);
return mysqli_character_set_name($link);
}
function mysql_thread_id($link=null) {
$link = mysql_link($link);
return mysqli_thread_id($link);
}
function mysql_escape_string($string) {
return mysql_real_escape_string($string);
}
function mysql_real_escape_string($string, $link=null) {
$link = mysql_link($link);
return mysqli_real_escape_string($link, $string);
}
function mysql_query($sql, $link=null) {
$link = mysql_link($link);
return mysqli_query($link, $sql);
}
function mysql_unbuffered_query($sql, $link=null) {
$link = mysql_link($link);
return mysqli_query($link, $sql, MYSQLI_USE_RESULT);
}
function mysql_set_charset($charset, $link=null){
$link = mysql_link($link);
return mysqli_set_charset($link, $charset);
}
function mysql_get_host_info($link=null) {
$link = mysql_link($link);
return mysqli_get_host_info($link);
}
function mysql_get_proto_info($link=null) {
$link = mysql_link($link);
return mysqli_get_proto_info($link);
}
function mysql_get_server_info($link=null) {
$link = mysql_link($link);
return mysqli_get_server_info($link);
}
function mysql_info($link=null) {
$link = mysql_link($link);
return mysqli_info($link);
}
function mysql_get_client_info() {
$link = mysql_link();
return mysqli_get_client_info($link);
}
function mysql_create_db($db, $link=null) {
$link = mysql_link($link);
$db = str_replace('`', '', mysqli_real_escape_string($link, $db));
return mysqli_query($link, "CREATE DATABASE `$db`");
}
function mysql_drop_db($db, $link=null) {
$link = mysql_link($link);
$db = str_replace('`', '', mysqli_real_escape_string($link, $db));
return mysqli_query($link, "DROP DATABASE `$db`");
}
function mysql_list_dbs($link=null) {
$link = mysql_link($link);
return mysqli_query($link, "SHOW DATABASES");
}
function mysql_list_fields($db, $table, $link=null) {
$link = mysql_link($link);
$db = str_replace('`', '', mysqli_real_escape_string($link, $db));
$table = str_replace('`', '', mysqli_real_escape_string($link, $table));
return mysqli_query($link, "SHOW COLUMNS FROM `$db`.`$table`");
}
function mysql_list_tables($db, $link=null) {
$link = mysql_link($link);
$db = str_replace('`', '', mysqli_real_escape_string($link, $db));
return mysqli_query($link, "SHOW TABLES FROM `$db`");
}
function mysql_db_query($db, $sql, $link=null) {
$link = mysql_link($link);
mysqli_select_db($link, $db);
return mysqli_query($link, $sql);
}
function mysql_fetch_row($qlink) {
return mysqli_fetch_row($qlink);
}
function mysql_fetch_assoc($qlink) {
return mysqli_fetch_assoc($qlink);
}
function mysql_fetch_array($qlink, $result=MYSQLI_BOTH) {
return mysqli_fetch_array($qlink, $result);
}
function mysql_fetch_lengths($qlink) {
return mysqli_fetch_lengths($qlink);
}
function mysql_insert_id($qlink) {
return mysqli_insert_id($qlink);
}
function mysql_num_rows($qlink) {
return mysqli_num_rows($qlink);
}
function mysql_num_fields($qlink) {
return mysqli_num_fields($qlink);
}
function mysql_data_seek($qlink, $row) {
return mysqli_data_seek($qlink, $row);
}
function mysql_field_seek($qlink, $offset) {
return mysqli_field_seek($qlink, $offset);
}
function mysql_fetch_object($qlink, $class="stdClass", array $params=null) {
return ($params === null)
? mysqli_fetch_object($qlink, $class)
: mysqli_fetch_object($qlink, $class, $params);
}
function mysql_db_name($qlink, $row, $field='Database') {
mysqli_data_seek($qlink, $row);
$db = mysqli_fetch_assoc($qlink);
return $db[$field];
}
function mysql_fetch_field($qlink, $offset=null) {
if ($offset !== null)
mysqli_field_seek($qlink, $offset);
return mysqli_fetch_field($qlink);
}
function mysql_result($qlink, $offset, $field=0) {
if ($offset !== null)
mysqli_field_seek($qlink, $offset);
$row = mysqli_fetch_array($qlink);
return (!is_array($row) || !isset($row[$field]))
? false
: $row[$field];
}
function mysql_field_len($qlink, $offset) {
$field = mysqli_fetch_field_direct($qlink, $offset);
return is_object($field) ? $field->length : false;
}
function mysql_field_name($qlink, $offset) {
$field = mysqli_fetch_field_direct($qlink, $offset);
if (!is_object($field))
return false;
return empty($field->orgname) ? $field->name : $field->orgname;
}
function mysql_field_table($qlink, $offset) {
$field = mysqli_fetch_field_direct($qlink, $offset);
if (!is_object($field))
return false;
return empty($field->orgtable) ? $field->table : $field->orgtable;
}
function mysql_field_type($qlink, $offset) {
$field = mysqli_fetch_field_direct($qlink, $offset);
return is_object($field) ? $field->type : false;
}
function mysql_free_result($qlink) {
try {
mysqli_free_result($qlink);
} catch (Exception $e) {
return false;
}
return true;
}
Функции, которые похожи на этот тип mysql_connect()
, mysql_query()
, являются функциями предыдущей версии PHP i.e (PHP 4) и в настоящее время не используются.
Они заменены mysqli_connect()
, mysqli_query()
аналогично в последней версии PHP5.
Это причина ошибки.
MySQL устарела в PHP 5.5.0 и удалена в PHP 7.0.0. Для большого и старого приложения это трудно найти и заменить каждую функцию.
Мы можем использовать функции MySQL, создав функцию-оболочку для каждого из запущенных ниже кодов. Нажмите здесь
Функции mysql_ * устарели (начиная с PHP 5.5 ), поскольку были разработаны более совершенные функции и структуры кода. Тот факт, что эта функция устарела, означает, что больше не будет предприниматься никаких усилий по ее улучшению с точки зрения производительности и безопасности, что означает, что она менее надежна в будущем .
Если вам нужно больше причин:
- Функции mysql_ * не поддерживают подготовленные операторы.
- Функции mysql_ * не поддерживают привязку параметров.
- Функции mysql_ * не обладают функциональностью для объектно-ориентированного программирования.
- список можно продолжить ...
mysql_
функции:
- устарели - они больше не поддерживаются
- не позволяют легко переходить на другую базу данных
- не поддерживают подготовленные заявления, следовательно
- поощрять программистов использовать конкатенацию для построения запросов, что приводит к уязвимостям внедрения SQL
mysqli_
mysql_*
- это оболочка функций mysqlnd для новых версий PHP. Таким образом, даже если старая клиентская библиотека больше не поддерживается, mysqlnd сохраняется :)
Потому что (среди прочих причин) гораздо сложнее обеспечить очистку входных данных. Если вы используете параметризованные запросы, как в случае с PDO или mysqli, вы можете полностью избежать риска.
Например, кто-то может использовать "enhzflep); drop table users"
в качестве имени пользователя. Старые функции позволят выполнять несколько операторов за запрос, поэтому что-то вроде этого мерзкого баггера может удалить всю таблицу.
Если бы кто-то использовал PDO mysqli, имя пользователя в конечном итоге оказалось бы "enhzflep); drop table users"
.
См. bobby-tables.com.
The old functions will allow executing of multiple statements per query
- нет, не будут. Такая инъекция невозможна с ext / mysql - единственный способ такой инъекции возможен с PHP и MySQL - это использование MySQLi и функции mysqli_multi_query()
. Типичная инъекция, которая возможна с ext / mysql и неэкранированными строками, - это такие вещи, как ' OR '1' = '1
для извлечения данных из базы данных, которые не должны были быть доступны. В определенных ситуациях можно вводить подзапросы, однако по-прежнему невозможно изменить базу данных таким образом.
Не используйте mysql, потому что он устарел, используйте Mysqli.
Что означает устаревание:
Это означает, что не используйте какую-то конкретную функцию / метод / функцию программного обеспечения / конкретную программную практику, это просто означает, что ее не следует использовать, потому что в этом программном обеспечении есть (или будет) лучшая альтернатива, которую следует использовать вместо этого.
При использовании устаревших функций может возникнуть несколько распространенных проблем:
1. Функции просто перестают работать: приложения или сценарии могут полагаться на функции, которые просто больше не поддерживаются, поэтому используйте их улучшенные версии или альтернативу.
2. Отображаются предупреждающие сообщения об устаревании . Обычно эти сообщения не мешают работе сайта. Однако в некоторых случаях они могут нарушить процесс отправки заголовков сервером.
Например: это может вызвать проблемы со входом в систему (файлы cookie / сеансы не устанавливаются должным образом) или проблемы с пересылкой (301/302/303 редиректы).
помните, что:
-Устаревшее программное обеспечение по-прежнему является частью программного обеспечения.
-Устаревший код - это просто статус (метка) кода.
Ключевые различия между MYSQL и MYSQLI mysql *
- старый драйвер базы данных
- MySQL можно использовать только процедурно
- Нет защиты от атак с использованием SQL-инъекций
- Устарела в PHP 5.5.0 и была удалена в PHP 7.
Mysqli
- новый драйвер базы данных
- В настоящее время используется
- подготовленные заявления защищают от атак
Нет необходимости в обновлении, если вы уверены, что не хотите обновлять версию php, но в то же время вы также не будете получать обновления безопасности, что сделает ваш сайт более уязвимым для хакеров, что является основной причиной.
Похожие вопросы
Связанные вопросы
Новые вопросы
php
PHP — это открытый, мультипарадигмальный, динамически типизированный и интерпретируемый язык сценариев, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.