Ахахах, интересная точка зрения :)
И если абстрагироваться от ужасной формулировки, то что-то в этом есть :)
Но, на самом деле, такие «минусы» — ничто по сравнению с пользой от отладки, которая в принципе делает возможной написание и поддержку сложных программ. «Из головы», увы, всё предусмотреть невозможно.
Я понимаю, что по комментариям читать проще, но я же обо всём этом написал :)
mysqli — однозначно сырая библиотека. В этом смысле я предпочту старую, но проверенную.
PDO — это лишний уровень абстракции, над которым всё равно надо городить свою — получается две.
Функционал prepare достаточно спорный.
Набор имеющихся placeholder-ов явно недостаточен — то есть, всё равно надо допиливать. Следовательно, парсер всё равно писать — а значит и основные плейсхолдеры реализовать не проблема, даже в mysql ext.
Если функционал проверенный, то давайте, конечно, притащим. Не вижу никакой проблемы в проверенном функционале, если честно. Что в нём плохого?
Плохой функционал, типа magic_quotes, тащить, разумеется, не надо. Но отказываться от хорошего только по той причине, что он был в 3 и 4 версии — это как-то странно.
В принипе, я не защищаю mysql. Но нахожу аргументы запретителей весьма спорными.
Вот буквально в комментариях к предыдущей статье по теме я утверждал, что библиотека для сборки запросов не должна заниматься валидацией данных. Но что-то сейчас гложут меня сомнения.
И если, скажем, кастить ли пустую строку в 0 — это ещё вопрос, то hello world, пожалуй (или, точнее, несовпадение с "-?\d+") — это повод для исключения. Надо посмотреть по коду, но, вроде бы, столь экстремальное приведение типов осознанно нигде не используется.
Я не понимаю вашей приверженности функции htmlspecialchars().
Если уж вы хотите руками форматировать строки, то почему не пользоваться специально предназначенной для этого функцией? Функцией, которая не портит данные?
А после htmlspecialchars в базе останутся все эти html-сущности, которые там даром не нужны.
Опять же, статью вы, судя по всему, не читали. Иначе поняли бы, что «волшебная» функция htmlspecialchars не всегда помогает:
$order = htmlspecialchars("name; DROP TABLE students", ENT_QUOTES);
$req = "SELECT student_id FROM students ORDER BY $order";
Про «программеру просмотреть» и 1мс я, извините, не буду комментировать.
Спасибо за поддержку, Давид!
А ты правда раньше про dbSimple не слышал? Я-то знал давно, но сначала не понимал всей глубины заложенных в неё принципов, а потом уже стал сам себе учёный и начал своё писать :)
Вообще, конечно, «не понимал всей глубины» — это беда, и далеко не только моя. И я наивно надеялся на свой талант популяризатора. Но, судя по имеющемуся фидбеку, что-то мне подсказывает, что mission failed…
Долго чесал репу, откуда я взял про обработку пустого массива в IN
оказалось — из англоязычной версии: en.dklab.ru/lib/DbSimple/#list6
Сейчас посмотрел по коду — так и есть, Котеров поступил совершенно логично — пустой массив тоже является триггером для пропуска плейсхолдера:
case 'a':
if (!$value) $this->_placeholderNoValueFound = true;
Ой.
Во-первых, функция htmlspecialchars(), как видно из её названия, имеет отношение к HTML, а не к SQL. И в SQL она не поможет, а только навредит. Так что строки надо обрабатывать специально предназначенными для этого функциями.
Во-вторых, с числами тоже могут быть проблемы (я о них писал)
В-третьих, кроме строк и чисел есть и другие элементы запроса.
В-четвёртых, самый главный вопрос состоит не в том, какими функциями форматировать части запроса, а кто это будет делать. Если отдавать форматирование данных на откуп программисту, то он когда-нибудь забудет. Поэтому идея состоит в том, что какие бы функции ни использовались — применять их должна программа, а не программист. В этом суть использования плейсхолдеров.
Мне кажется — да, но рекомендовать не возьмусь. Уж очень непредсказуема реакция хабрасаообщества.
Кстати, хороший вариант — посмотреть сначала на оценки комментария!
В любом случае, я бы сначала поправил п 1.2 — «хотя бы escaping» — это решето.
С этим я согласен, но это никак и не противоречит сказанному мной.
Deprecated — это совершенно конкретный статус, который выдает конкретную ошибку при соответствующем уровне отображения.
Discouraged же — некий неформальный термин, который появился в документации по этому расширению буквально на днях.
Но вообще, я имел в виду не терминологию, а скорее тот факт, что расширение mysql на настолько плохо, как его изображают. И основная проблема не в нем самом, а в непонимании и неумении пользоваться. Во всяком случае, с безопасностью при корректном использовании проблем никаких нет.
С тем, что сами же разработчики и хоронят, я тоже не спорю — именно это я и написал. Собственно, мне они же сами и ответили в том смысле, что просто никто не хочет заниматься поддержкой этого расширения. Ну и по второй ссылке между строк читается «и так есть два расширения, зачем ещё с со старым возиться?». Что характерно, никакой другой причины там не написано. «Старое» — и всё. Как будто curl — новое.
Во-первых, это только предложение из мейл-листа. В том же листе и про выход 6.0 писали.
Во-вторых, там как раз написано, что «Not adding E_DEPRECATED errors in 5.4». Текущая версия сейчас — 5.4. То есть, о таком статусе в настоящем времени говорить можно вряд ли.
В-третьих, самая простая проверка показывает нам разницу: www.php.net/manual/en/function.mysql-list-dbs.php — стоит плашка «Deprecated» (ниже на странице). www.php.net/manual/en/function.mysql-query.php — стоит плашка «Use of this extension is discouraged», но про Deprecated ничего нет.
Было бы очень интересно взглянуть.
Возможно, речь не о динамической сборке запроса?
Дело в том, что плейсхолдеры, как раз, и служат для сокращения чек-листа для этой операции. «Добавил через плейсхолдер — и забыл». Разве что тип надо указывать. Но для родных препаредов и это не нужно.
Так чеклист же и состоит всего из двух пунктов? Плейсхолдеры для данных и белый список для всего остального.
Вы считаете, что этого недостаточно? А можете привести какую-то конкретную ситуацию, в которой
данные рекомендации окажутся неприменимыми или двусмысленными?
На конкретных примерах всегда лучше видно проблему.
Ну, во-первых, из личного опыта, а во-вторых, исходя из принципа построения всех публичных фреймфорков, о котором говорил Расмус на конфе — максимальная перестраховка :) А режим эмуляции по определению более совместим.
Увы, судя по комментариям, так думают, похоже, многие.
Не читав, при этом, саму статью, и не имея, следовательно, возможности судить — действительно ли это «опять» или же что-то новое.
Похоже, убеждённость в собственном всезнайстве сослужит плохую службу тем, кому эта статья действительно могла бы помочь.
Вся надежда остаётся на комментарии по существу, в ответ на которые я могу аргументированно переубеждать заблуждающихся.
Для вставки это NULL, тут просто. А при сравнении — что?
И если абстрагироваться от ужасной формулировки, то что-то в этом есть :)
Но, на самом деле, такие «минусы» — ничто по сравнению с пользой от отладки, которая в принципе делает возможной написание и поддержку сложных программ. «Из головы», увы, всё предусмотреть невозможно.
mysqli — однозначно сырая библиотека. В этом смысле я предпочту старую, но проверенную.
PDO — это лишний уровень абстракции, над которым всё равно надо городить свою — получается две.
Функционал prepare достаточно спорный.
Набор имеющихся placeholder-ов явно недостаточен — то есть, всё равно надо допиливать. Следовательно, парсер всё равно писать — а значит и основные плейсхолдеры реализовать не проблема, даже в mysql ext.
Если функционал проверенный, то давайте, конечно, притащим. Не вижу никакой проблемы в проверенном функционале, если честно. Что в нём плохого?
Плохой функционал, типа magic_quotes, тащить, разумеется, не надо. Но отказываться от хорошего только по той причине, что он был в 3 и 4 версии — это как-то странно.
В принипе, я не защищаю mysql. Но нахожу аргументы запретителей весьма спорными.
И ведь работает однако! :)
Прям сегодня внесу изменения в либу :)
И если, скажем, кастить ли пустую строку в 0 — это ещё вопрос, то hello world, пожалуй (или, точнее, несовпадение с "-?\d+") — это повод для исключения. Надо посмотреть по коду, но, вроде бы, столь экстремальное приведение типов осознанно нигде не используется.
Если уж вы хотите руками форматировать строки, то почему не пользоваться специально предназначенной для этого функцией? Функцией, которая не портит данные?
А после htmlspecialchars в базе останутся все эти html-сущности, которые там даром не нужны.
Опять же, статью вы, судя по всему, не читали. Иначе поняли бы, что «волшебная» функция htmlspecialchars не всегда помогает:
Про «программеру просмотреть» и 1мс я, извините, не буду комментировать.
А ты правда раньше про dbSimple не слышал? Я-то знал давно, но сначала не понимал всей глубины заложенных в неё принципов, а потом уже стал сам себе учёный и начал своё писать :)
Вообще, конечно, «не понимал всей глубины» — это беда, и далеко не только моя. И я наивно надеялся на свой талант популяризатора. Но, судя по имеющемуся фидбеку, что-то мне подсказывает, что mission failed…
Долго чесал репу, откуда я взял про обработку пустого массива в IN
оказалось — из англоязычной версии: en.dklab.ru/lib/DbSimple/#list6
Сейчас посмотрел по коду — так и есть, Котеров поступил совершенно логично — пустой массив тоже является триггером для пропуска плейсхолдера:
Во-первых, функция htmlspecialchars(), как видно из её названия, имеет отношение к HTML, а не к SQL. И в SQL она не поможет, а только навредит. Так что строки надо обрабатывать специально предназначенными для этого функциями.
Во-вторых, с числами тоже могут быть проблемы (я о них писал)
В-третьих, кроме строк и чисел есть и другие элементы запроса.
В-четвёртых, самый главный вопрос состоит не в том, какими функциями форматировать части запроса, а кто это будет делать. Если отдавать форматирование данных на откуп программисту, то он когда-нибудь забудет. Поэтому идея состоит в том, что какие бы функции ни использовались — применять их должна программа, а не программист. В этом суть использования плейсхолдеров.
Кстати, хороший вариант — посмотреть сначала на оценки комментария!
В любом случае, я бы сначала поправил п 1.2 — «хотя бы escaping» — это решето.
Deprecated — это совершенно конкретный статус, который выдает конкретную ошибку при соответствующем уровне отображения.
Discouraged же — некий неформальный термин, который появился в документации по этому расширению буквально на днях.
Но вообще, я имел в виду не терминологию, а скорее тот факт, что расширение mysql на настолько плохо, как его изображают. И основная проблема не в нем самом, а в непонимании и неумении пользоваться. Во всяком случае, с безопасностью при корректном использовании проблем никаких нет.
С тем, что сами же разработчики и хоронят, я тоже не спорю — именно это я и написал. Собственно, мне они же сами и ответили в том смысле, что просто никто не хочет заниматься поддержкой этого расширения. Ну и по второй ссылке между строк читается «и так есть два расширения, зачем ещё с со старым возиться?». Что характерно, никакой другой причины там не написано. «Старое» — и всё. Как будто curl — новое.
Во-вторых, там как раз написано, что «Not adding E_DEPRECATED errors in 5.4». Текущая версия сейчас — 5.4. То есть, о таком статусе в настоящем времени говорить можно вряд ли.
В-третьих, самая простая проверка показывает нам разницу:
www.php.net/manual/en/function.mysql-list-dbs.php — стоит плашка «Deprecated» (ниже на странице).
www.php.net/manual/en/function.mysql-query.php — стоит плашка «Use of this extension is discouraged», но про Deprecated ничего нет.
Возможно, речь не о динамической сборке запроса?
Дело в том, что плейсхолдеры, как раз, и служат для сокращения чек-листа для этой операции. «Добавил через плейсхолдер — и забыл». Разве что тип надо указывать. Но для родных препаредов и это не нужно.
Путём выполнения вот такого кода
try {
$dsn = 'mysql:dbname=test;host=127.0.0.1;charset=GBK';
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sth = $dbh->prepare(«SELECT id FROM users WHERE name LIMIT ?,?»);
$sth->execute(array(«1»,«2»));
} catch (PDOException $e) {
echo $e->getMessage();
}
И прочтения сообщения об ошибке, в котором переданные параметры оказались подставлены на место плейсхолдеров.
Возможно, он недостаточный/устаревший, но это именно практический опыт, а не предположение.
Если у вас есть опровержение, я с удовольствием его выслушаю и исправлю статью.
Вы считаете, что этого недостаточно? А можете привести какую-то конкретную ситуацию, в которой
данные рекомендации окажутся неприменимыми или двусмысленными?
На конкретных примерах всегда лучше видно проблему.
Я там как раз чуть ниже привёл под спойлером код, который это наглядно демонстрирует.
Запрос SET NAMES влияет только на сервер, а «правильные» способы — и на сервер, и на клиент.
Не читав, при этом, саму статью, и не имея, следовательно, возможности судить — действительно ли это «опять» или же что-то новое.
Похоже, убеждённость в собственном всезнайстве сослужит плохую службу тем, кому эта статья действительно могла бы помочь.
Вся надежда остаётся на комментарии по существу, в ответ на которые я могу аргументированно переубеждать заблуждающихся.