Подтвердить что ты не робот

Почему PDO лучше избегать запросов и запросов MySQL, чем mysql_real_escape_string?

Мне сказали, что лучше использовать PDO для ускорения MySQL, а не mysql_real_escape_string.

Может быть, у меня день смерти мозга (или это может быть тот факт, что я не являюсь воображением естественным программистом, и я все еще очень нахожусь на стадии новичка, когда речь идет о PHP), но, проверив руководство по PHP и прочитав запись в PDO, я все еще не понимаю, что такое PDO и почему это лучше чем при использовании mysql_real_escape_string. Возможно, это связано с тем, что я еще не справился с сложностями ООП (я предполагаю, что это что-то связано с ООП), но кроме факта, что переменные и значения массива, похоже, Я все еще не уверен, что это на самом деле и как вы его используете (и почему это лучше, чем mysql_real_escape_string. (Это также может иметь отношение к тому факту, что у меня нет четкого представления о том, что такое классы "есть, поэтому, когда я читаю" класс PDO ", я на самом деле не самый мудрый).

Прочитав статью или две в бит 'Developer Zone' на веб-сайте MySQL, я все еще не понимаю. Поскольку я не могу даже понять, что это на данный момент, я думаю, что, вероятно, использование этого немного вне меня сейчас, но меня все еще интересует расширение моего образования и выяснение того, как я могу улучшить ситуацию.

Может ли кто-нибудь объяснить мне на "простом английском", что такое PDO (или указать мне в сторону чего-то на предмет, написанный на простом английском языке), и как вы собираетесь его использовать?

4b9b3361

Ответ 1

Как только текущие ответы вникают в детали, а ваш вопрос больше нацелен на общий обзор, я попробую:

Классы PDO нацелены на инкапсуляцию всех функций, необходимых для взаимодействия с базой данных. Они делают это, определяя "методы" (OO-салон для функций) и "свойства" (OO-комната для переменных). Вы использовали бы их как полную замену для всех стандартных функций, которые вы используете сейчас для разговора с базой данных.

Поэтому вместо вызова серии функций mysql_doSomething(), сохраняя свои результаты в ваших собственных переменных, вы будете "создавать экземпляр" объекта из класса PDO ( "класс" = абстрактное определение, "объект" = конкретный, пригодный для использования экземпляр класса) и методы вызова для этого объекта, чтобы сделать то же самое.

В качестве примера, без PDO, вы бы сделали что-то вроде этого:

// Get a db connection
$connection = mysql_connect('someHost/someDB', 'userName', 'password');
// Prepare a query
$query = "SELECT * FROM someTable WHERE something = " . mysql_real_escape_string($comparison) . "'";
// Issue a query
$db_result = mysql_query($query);
// Fetch the results
$results = array();
while ($row = mysql_fetch_array($db_result)) {
  $results[] = $row;
}

тогда как это будет эквивалент с использованием PDO:

// Instantiate new PDO object (will create connection on the fly)
$db = new PDO('mysql:dbname=someDB;host=someHost');
// Prepare a query (will escape on the fly)
$statement = $db->prepare('SELECT * FROM someTable WHERE something = :comparison');
// $statement is now a PDOStatement object, with its own methods to use it, e.g.
// execute the query, passing in the parameters to replace
$statement->execute(array(':comparison' => $comparison));
// fetch results as array
$results = $statement->fetchAll();

Итак, с первого взгляда нет большой разницы, кроме синтаксиса. Но версия PDO имеет некоторые преимущества, самая большая из которых - независимость базы данных:

Если вам нужно поговорить с базой PostgreSQL, вы должны изменить только mysql: на pgsql: в экземпляре вызова new PDO(). С помощью старого метода вам придется пройти весь свой код, заменив все функции mysql_doSomething() на их "pg_doSomthing()" (всегда проверяя потенциальные различия в обработке параметров). То же самое было бы для многих других поддерживаемых движков базы данных.

Итак, чтобы вернуться к вашему вопросу, PDO в основном просто дает вам другой способ добиться того же самого, предлагая некоторые ярлыки/улучшения/преимущества. Например, экранирование будет происходить автоматически надлежащим образом, необходимым для используемого вами механизма базы данных. Также подстановка параметров (предотвращает SQL Injections, не показанные в примере) намного проще, что делает ее менее подверженной ошибкам.

Вы должны прочитать некоторые основы ООП, чтобы получить представление о других преимуществах.

Ответ 2

Я не очень хорошо знаком с PDO, но существует различие между "подготовленными операциями" и экранированными строками. Escaping - это удаление запрещенных строк символов из запроса, но подготовленные операторы примерно сообщают базе данных, какой запрос ожидать.

Запрос имеет несколько частей

Подумайте об этом так: когда вы даете запрос в базу данных, вы говорите ему несколько отдельных вещей. Одно может быть, например, "я хочу, чтобы вы сделали выбор". Другой может быть "ограничить его строками WHERE, имя пользователя - следующее значение".

Если вы создаете запрос в виде строки и передаете ее в базу данных, она не знает ни о какой части, пока не получит заполненную строку. Вы можете сделать это:

'SELECT * FROM transactions WHERE username=$username'

Когда он получает эту строку, он должен проанализировать ее и решить, что "это SELECT с WHERE".

Приведение деталей в замешательство

Предположим, что злонамеренный пользователь вводит свое имя пользователя как billysmith OR 1=1. Если вы не будете осторожны, вы можете поместить это в свою строку, в результате чего:

'SELECT * FROM transactions WHERE username=billysmith OR 1=1'

..., который возвратит все транзакции для всех пользователей, потому что 1 всегда равно 1. Упс, вы были взломаны!

Посмотрите, что произошло? База данных не знала, какие части ожидать в вашем запросе, поэтому она просто разбирает строку. Не удивительно, что WHERE имел OR, с двумя условиями, которые могли бы его удовлетворить.

Сохранение частей прямо

Если бы он знал , что ожидать, а именно SELECT, у которого WHERE было только одно условие, злоумышленник не мог обмануть его.

С подготовленным выражением вы можете дать ему правильное ожидание. Вы можете сообщить базе данных "Я собираюсь отправить вам SELECT, и она будет ограничена строками WHERE username = строкой, которую я собираюсь вам дать. Все это - нет других частей для запрос. Готовы ли вы? ОК, здесь идет строка для сравнения с именем пользователя."

С этим ожиданием база данных не будет обманута: она вернет строки, где столбец username содержит фактическую строку "billysmith OR 1 = 1". Если никто не имеет этого имени пользователя, он ничего не вернет.

Другие преимущества подготовленных операторов

В дополнение к преимуществам безопасности подготовленные заявления имеют несколько преимуществ скорости:

  • Их можно повторно использовать с разными параметрами, которые должны быть быстрее, чем создавать новый запрос с нуля, потому что база данных уже знает, в чем вы хотите спросить. Он уже построил "план запроса".
  • Некоторые базы данных (Postgres - это один, я думаю) начнут составлять план запроса, как только они получат подготовленный оператор - прежде чем вы действительно отправите параметры для использования с ним. Таким образом, вы можете увидеть ускорение даже по первому запросу.

Для другого объяснения см. Ответ Тео здесь.

Ответ 3

В отличие от mysql_real_escape_string, PDO позволяет вам применять тип данных.

<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>

Обратите внимание, что в приведенном выше примере первый параметр, калории, должен быть целым числом (PDO:: PARAM_INT).

Во-вторых, мне, PDO параметризованные запросы легче читать. Я бы предпочел прочитать:

SELECT name FROM user WHERE id = ? AND admin = ? 

чем

SELECT name FROM user WHERE id = mysql_real_escape_string($id) AND admin = mysql_real_escape_string($admin);

В-третьих, вам не обязательно обязательно указывать параметры. PDO заботится об этом. Например, mysql_real_query_string:

SELECT * FROM user WHERE name = 'mysql_real_escape_string($name)' //note quotes around param

против

SELECT * FROM user WHERE name = ?

Наконец, PDO позволяет вам переносить ваше приложение на другой db, не изменяя ваши вызовы данных PHP.

Ответ 4

Представьте, что вы пишете что-то по строкам:

$query = 'SELECT * FROM table WHERE id = ' . mysql_real_escape_string($id);

это не спасет вас от инъекций, потому что $id может быть 1 OR 1=1, и вы получите все записи из таблицы. youd должен придать $id правильному типу данных (int в этом случае)

pdo имеет еще одно преимущество, и это взаимозаменяемость баз данных.

Ответ 5

В дополнение к предотвращению SQL-инъекции PDO позволяет вам подготовить запрос один раз и выполнить его несколько раз. Если ваш запрос выполняется несколько раз (например, в цикле), этот метод должен быть более эффективным (я говорю "должно быть", потому что похоже, что это не всегда относится к более старым версиям MySQL). Метод prepare/bind также больше соответствует другим языкам, с которыми я работал.

Ответ 6

Почему PDO лучше для ускорения запросов/запросов MySQL, чем mysql_real_escape_string?

Просто потому, что "побега" само по себе не имеет смысла.
Кроме того, имеет значение несравнимый.

Единственная проблема с экранированием заключается в том, что все ошибаются,, считая это своего рода "защитой".
Все говорят: "Я избежал моих переменных" со значением "Я защитил свой запрос".
Хотя экранирование не имеет ничего общего с защитой.

Защита может быть примерно достигнута в случае Я экранировал и процитировал мои данные, но он неприменим везде, например, для идентификаторов (а также PDO).

Итак, ответ:

  • PDO при выполнении экранирования привязанных значений применяется не только к экранированию, но и к цитированию - почему это лучше.
  • "escaping" не является синонимом "защиты". "ускользание + цитирование" примерно есть.
  • но для некоторых частей запроса оба метода неприменимы.