Почему PDO лучше для выхода из MySQL, queries/querystrings, чем mysql_real_escape_string?

Для вопроса было бы нужно больше деталей.
Вы хотите только посмотреть на файл (например, файл журнала) или отредактировать его?
у Вас есть больше памяти, чем размер файла, который Вы хотите загрузить или меньше?
, Например, TheGun, очень маленький текстовый редактор, записанный в ассемблере, требует к" не, имеют эффективный предел размера файла и максимальный размер, который может быть загружен в него, определяется доступной памятью и загружающейся скоростью файла. [...] Это была скорость, оптимизированная и для файла, загружают и сохраняют. "

Для абстракции предела памяти я предполагаю, что можно использовать расширенную память. Но тогда, если необходимо отредактировать файл, некоторый умный метод должен использоваться, как хранение в памяти локальные изменения и применение их блок блоком при сохранении. Могло бы быть неэффективным в некоторых случаях (большой поиск/замена, например).

48
задан BlissC 16 November 2009 в 03:01
поделиться

5 ответов

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

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

Таким образом, вместо вызова серии функций 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: в вызове нового PDO () . При использовании старого метода вам пришлось бы пройти весь свой код, заменив все функции mysql_doSomething () их аналогом pg_doSomthing () (всегда проверяя возможные различия в обработке параметров). То же самое и со многими другими поддерживаемыми механизмами баз данных.

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

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

]
57
ответ дан 7 November 2019 в 12:10
поделиться

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

3
ответ дан 7 November 2019 в 12:10
поделиться

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

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

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

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

'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) начнут составлять план запроса, как только получат подготовленный оператор - до того, как вы фактически отправите параметры для использования с ним. . Таким образом, вы можете увидеть ускорение даже по первому запросу.
40
ответ дан 7 November 2019 в 12:10
поделиться

В отличие от 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

vs

SELECT * FROM user WHERE name = ?

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

16
ответ дан 7 November 2019 в 12:10
поделиться

Согласно Расширенное программирование в среде UNIX Стивенса , глава 13, это процедура для создания хорошо работающего демона Unix:

  1. Форк и родительский выход. Это заставляет оболочку или сценарий загрузки думать, что команда выполнена. Также гарантируется, что дочерний процесс не будет лидером группы процессов (предварительное условие для setsid next)
  2. Вызов setsid для создания нового сеанса. Это делает три вещи: Это заставляет оболочку или сценарий загрузки думать, что команда выполнена. Кроме того, гарантируется, что дочерний процесс не будет лидером группы процессов (предварительное условие для setsid next)
  3. Вызов setsid для создания нового сеанса. Это делает три вещи: Это заставляет оболочку или сценарий загрузки думать, что команда выполнена. Также гарантируется, что дочерний процесс не будет лидером группы процессов (предварительное условие для setsid next)
  4. Вызов setsid для создания нового сеанса. Это делает три вещи:
    1. Процесс становится лидером сеанса нового сеанса
    2. Процесс становится лидером группы процессов для новой группы процессов
    3. У процесса нет управляющего терминала
  5. Необязательно снова выполнить ответвление и иметь родительский выход. Это гарантирует, что демон не является лидером сеанса и не может получить управляющий терминал (в SVR4)
  6. Измените текущий рабочий каталог на / , чтобы не мешать монтированию и размонтированию
  7. Установить режим файла маска создания на 000, чтобы в дальнейшем разрешить создание файлов с любыми необходимыми разрешениями.
  8. Закройте ненужные файловые дескрипторы, унаследованные от родителя (в любом случае управляющего терминала нет): stdout , stderr , и stdin .

В настоящее время существует файл для отслеживания PID, который активно используется сценариями загрузки дистрибутива Linux.

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

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

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

14
ответ дан 7 November 2019 в 12:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: