Вопрос по php, mysql – MySQL PHP PDO подготовил заявления - проблемы производительности против безопасности

7

Я думаю о переписывании некоторых приложений с открытым исходным кодом для моих целей в PDO и транзакциях с использованием InnoDB (mysql_query и MyISAM сейчас).

Мой вопрос: в каких случаях целесообразно использовать подготовленные заявления?

Потому что везде, где я читаю, указано (даже во многих постах здесь), что я должен использовать подготовленные утверждения каждый раз и везде из-за 1. безопасности и 2. производительности. Даже руководство по PHP рекомендует использовать подготовленные операторы и не упоминать о побеге.

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

Так как это преодолеть? Могу ли я подготовить свои заявления для всей заявки и назвать их конкретно? Могу ли я подготовить несколько разных заявлений и использовать их по имени? Потому что это единственное разумное решение, о котором я думаю (кроме 1000x).

Я обнаружил, что есть также mysql_real_escape, называемый $ pdo- & gt; quote, для цели одного запроса. Почему бы не использовать это? Зачем беспокоиться о подготовке?

А что вы думаете об этой прекрасной статье? http://blog.ulf-wendel.de/2008/pdo_mysqlnd-prepared-statements-again/

Согласны ли вы с накладными расходами, вызванными подготовкой заявлений?

Спасибо

Возможный дубликатShould I use prepared statements for MySQL in PHP PERFORMANCE-WISE? e4c5
А такжеwhich проблема производительности. Такой же теоретический, как и «открытый исходный код»; приложение или вы сталкиваетесь с реальными проблемами? hakre
Which приложение с открытым исходным кодом? hakre

Ваш Ответ

4   ответа
7

My question is: Which cases are reasonable for using prepared statements?

Все они. Сообщество открыто выступает против использованияmysql_* функции.

Примечание: предлагаемые альтернативы

Использование этого расширения не рекомендуется. Вместо этого следует использовать расширение MySQLi или PDO_MySQL. Смотрите также MySQL: выбор API для получения дополнительной информации.

Альтернативы этой функции включают в себя:

источник

But thinking it over and over it comes to mind that having to prepare the statement every time and then use it once.. It doesn't make sense

Вы меняете Geo на Jaguar, и вы жалуетесь, что вам не нравится Jaguar, потому что вы не всегда используете обогреватели сидений. Вам не нужно последовательно использовать каждую функцию библиотеки, чтобы это означало, что это хорошо.

I found there is this mysql_real_escape called $pdo->quote as well for the purpose of single query. Why not to use this? Why to bother with preparing?

Если вы используете эту функцию для построения операторов SQL, настоятельно рекомендуется использовать PDO :: prepare () для подготовки операторов SQL со связанными параметрами вместо использования PDO :: quote () для интерполяции ввода пользователя в оператор SQL. Подготовленные операторы со связанными параметрами не только более переносимы, более удобны, невосприимчивы к SQL-инъекциям, но часто намного быстрее выполняются, чем интерполированные запросы, поскольку и на стороне сервера, и на стороне клиента могут кэшировать скомпилированную форму запроса.источник

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded nemozny
Error: User Rate Limit Exceeded
@MikeB Что вы думаете о посте отorrd101 at gmail dot com 30-Apr-2012 12:46Error: User Rate Limit Exceededcz.php.net/manual/en/pdo.prepare.phpError: User Rate Limit Exceeded nemozny
Error: User Rate Limit Exceeded
0

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

Подводя итог всему ниже:

  • Yes always use prepare statements
  • Yes use PDO over mysqli over mysql. This way if you switch database systems all you need to do is update the queries instead of queries, function calls, and arguments given it supports prepared statements.
  • Always sanitize user supplied data despite using prepared statements with parameters
  • Look into a DBAL (Database Abstraction Layer) to ease working with all of these factors and manipulating queries to suit your needs.

Существует тема PDO :: ATTR_EMULATE_PREPARES, которая повысит производительность вызова кэшированных запросов в MySQL & gt; = 5.1.21, когда эмуляция отключена, что по умолчанию включено. Это означает, что PHP будет эмулировать подготовку перед тем, как выполнить отправит ее в фактическую базу данных. Время между эмулированным и неэмулированным обычно незначительно, если только вы не работаете с внешней базой данных (не локальной), такой как в облаке, которая может иметь аномально высокую частоту пинга.

Кэширование также зависит от ваших настроек MySQL в my.cnf, но оптимизация MySQL выходит за рамки этого поста.

<?php
$pdo = new \PDO($connection_string); 
$pdo->setAttribute( \PDO::ATTR_EMULATE_PREPARES, false );
?>

Так что имейте это в виду, поскольку mysqli_ не предоставляет API для эмуляции на стороне клиента и всегда собирается использовать MySQL для подготовки операторов. http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php

Несмотря на наличие схожих функций, есть различия, и вам могут понадобиться функции, которые один API предоставляет, а другой нет. См. Справку PHP по выбору одного API над другим:http://www.php.net/manual/en/mysqlinfo.api.choosing.php

Таким образом, это в значительной степени согласуется с тем, что вы просили, с определением ваших операторов для всего приложения, поскольку кэшируемые запросы будут кэшироваться на сервере MySQL и не должны быть подготовлены для всего приложения. Другое преимущество заключается в том, что исключения в вашем запросе будут выдаваться при методе prepare (), а не execute (), что помогает в разработке обеспечить правильность ваших запросов.

Независимо от того, нет ли в мире практической выгоды от использования подготовки или нет.

Еще одно преимущество готовых операторов - работа с транзакциями, если вы используете InnoDB для MySQL. Вы можете начать транзакцию, вставить запись, получить последний идентификатор вставки, обновить другую таблицу, удалить из другой, и, если что-то не получится, вы можете выполнить RollBack () до выполнения транзакции. В противном случае внесите изменения, если вы решите. Например, работа с новым заказом и установка для столбца последнего заказа пользователя нового идентификатора заказа, а также удаление отложенного заказа, но предоставленный тип оплаты не соответствует критериям для размещения заказов из таблицы order_flags, поэтому вы можете выполнить rollBack () и покажет пользователю дружественное сообщение об ошибке.

Что касается безопасности, я довольно озадачен, никто не коснулся этого. При отправке любых предоставленных пользователем данных в ЛЮБУЮ систему, включая PHP и MySQL, очистите и стандартизируйте их. Да, подготовленные заявления действительно обеспечивают некоторую безопасность, когда дело доходит до экранирования данных, но это НЕ 100% -ное доказательство.

Таким образом, всегда использовать подготовленные операторы гораздо выгоднее, чем реальную потерю производительности, а также некоторые преимущества кэширования, но вы все равно должны очищать предоставленные пользователем данные. Одним из шагов является приведение переменных к нужному типу данных, с которым вы работаете. Использование объектов еще больше упростит эту задачу, поскольку вы работаете в единой модели для типов данных, а не вспоминаете ее каждый раз, когда работаете с одними и теми же данными.

Чтобы добавить к вышесказанному, вы должны взглянуть на уровень абстракции базы данных, который использует PDO. Например, доктрина DBAL:http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html

Дополнительные преимущества работы с DBAL + PDO заключаются в том, что

  • You can standardize and shorten the amount of work you have to do.
  • Aid in sanitization of user supplied data
  • Easily manipulate complex queries
  • Use nested transactions
  • Easily switch between databases
  • Your code becomes more portable and usable in other projects

Например, я расширил PDO и переопределил методы query (), fetchAll () и fetch (), чтобы они всегда использовали подготовленные операторы и чтобы я мог писать операторы SQL внутри fetch () или fetchAll () вместо необходимости писать все снова. НАПРИМЕР:

<?php
$pdo = new PDOEnhanced( $connection );
$pdo->fetchAll( "SELECT * FROM foo WHERE bar = 'hi'", PDO::FETCH_OBJ ); 

//would automatically provide
$stmt = $pdo->prepare( "SELECT * FROM foo WHERE bar=?" );
$stmt->execute( array( 'hi' ) );
$resultSet = $stmt->fetchAll( PDO::FETCH_OBJ )
?>

Что касается людей, предполагающих, что стиль mysql_ *, то его гораздо проще просто заменить на mysqli_ * API. Это не тот случай. Большая часть функций mysql_ * была исключена или аргументы были изменены с помощью mysqli_ * Увидеть:http://php.net/manual/en/mysqli.summary.php

Однако вы можете получить конвертер, выпущенный Oracle, чтобы упростить процесс:https://wikis.oracle.com/display/mysql/Converting+to+MySQLi

Имейте в виду, что это анализатор исходного текста файла, и он не на 100% точен, поэтому проверьте изменения перед их объединением. Это также добавит значительное количество накладных расходов для глобалов, которые он создает.

2

My question is: Which cases are reasonable for using prepared statements?

Ну, на самом деле, это трудно сказать. Тем более, что вы даже не сказали, о каком приложении с открытым исходным кодом вы говорите здесь.

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

Так как база данных не является неважной для приложения, она также является противоположной: приложение не является неважным для базы данных.

Таким образом, вам либо нужно больше рассказать об этом «таинственном» приложение с открытым исходным кодом, о котором вы спрашиваетеor Вы должны сказать нам, что именно вы хотели бы знать. Потому что, как правило, все просто: возьмите PDO. Но, в частности, есть различия, поэтому вы должны сообщить нам, что конкретно представляет собой приложение, в противном случае на ваш вопрос уже дан ответ.

И, между прочим, если приложение имеет стиль mysql_ *, его гораздо проще просто заменить на интерфейс mysqli_ *. Если бы вы действительно переписали текст, даже просто для удовольствия, вы бы это увидели.

Так что лучше добавьте больше мяса сюда или живите с не очень точными ответами.

9

Я думаю, что это относится к «преждевременной оптимизации» категория.

Насколько значительны накладные расходы? Вы измерили это? Влияет ли это на производительность вашего сервера вообще?

Скорее всего, это не так.


С положительной стороны, у вас есть неоспоримый выигрыш в плане безопасности (что должно быть серьезной проблемой для любого интернет-магазина).

С другой стороны, у вас есть риск, что это может повлиять на производительность. В приведенной вами ссылке показано, что плохо выполненная подготовка PDO в некоторых случаях приводит к несколько более низкой производительности, чем не подготовленная инструкция. Разница в производительности на 5000 трасс составляет 0,298 секунды.

Незначительный. Тем более, когда вы понимаете, что «не подготовлен» запросы выполняютсяwithout входные санитарные процедуры, которые потребуются для обеспечения их безопасности в реальной среде. Если вы не используете подготовленные запросы, вам потребуется некоторая форма очистки входных данных для предотвращения атак SQL, и в зависимости от того, как это делается, вам может понадобиться восстановить наборы результатов.

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

В своем вопросе вы говорите о «общем интернет-магазине». «Общий интернет-магазин» никогда не будет достаточно трафика, чтобы беспокоиться о проблеме производительности, если таковая имеется. Проблема безопасности на другом конце ...

Error: User Rate Limit Exceeded
Спасибо за ваш вклад, но пока вы чувствуете, что это ответ на вопрос, который я задал .. Нет. На самом деле я ищу разумную аргументацию. nemozny
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded$dbh->prepare("DELETE FROM x WHERE ?"); $dbh->execute($value);Error: User Rate Limit Exceeded$dbh->query("DELETE FROM x WHERE " . $dbh->quote($value));Error: User Rate Limit Exceeded nemozny
Error: User Rate Limit Exceeded

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