Использование подготавливаемых запросов для SQL в php

Хотелось бы уточнить один момент - когда в SQL - запросах стоит использовать конструкции типа:

$sql = "SELECT name FROM users WHERE name = :name";
		$st= $conn->prepare($sql);
		$st->bindValue( ":name", $login, PDO::PARAM_STR );
		$st->execute();

вместо простой:

$sql = "SELECT name FROM users WHERE name =  $name";
$st = $conn->query( $sql );

?

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

melisa's picture

вы правы,

первый вариант надежнее, во время "привязки" значения производится приведение типа данных
  1. Насчёт ситуации, когда мы уверены в правильности данных - лучше взять за аксиому, что мы никогда не уверены в правильности данных. По множеству причин:
    • проверка данных может проходить на другом уровне абстракции и быть пропущенна из-за ошибок в архитектуре приложения или невнимательности разработчика
    • сама валидация проведена некорректно
    • в конце концов, при намеренном взломе кода sql-инъекция может быть внедрена прямо перед запросом в БД

    prepare() и bindValue() позволяют сделать дополнительную проверку тогда, когда скрипт ничего уже изменять не будет.

  2. Насчёт ситуации, когда не нужно приводить их к верному формату если они не совпадают. Лучше опять же избегать любых неопределённостей в коде. Чем жёсче рамки в Вашем коде, тем лучше.
    • так разработчикам, поддерживающим Ваш код легче его читать. Они будут в курсе того, что Ваш метод в один прекрасный момент не попросит у них одежду и мотоцикл.
    • опять же, при некорректном поведении скрипта, будет выдана ошибка или предупреждение на более высоком уровне (например, если метод ожидает, например, int, он не примет string, и не начнёт "ломать" своей логикой что-либо)

    Ситуаций, когда может прийти один формат, а может другой, в идеале быть не должно.

Voronve's picture

Ахах! )) Шутка про одежду и мотоцикл - зачёт! :) Вспомнилась, новость, которую прочитал недавно о том, что в одной из IT компаний программа уволила программиста без ведома начальства ) А пояснение ваше понял, спасибо. Тогда, получается, второй вариант, с простым подставлением переменной при работе с sql лучше вообще не применять?

melisa's picture

IT компаний программа уволила программиста без ведома начальства )

- самое смешное, что именно в IT))))

Тогда, получается, второй вариант, с простым подставлением переменной при работе с sql лучше вообще не применять?

да, думаю, что так. методы содержат внутри себя какой-то позитивный функционал (можно, кончено, ознакомиться с ним во избежании увольнений "неугодных")))). а вообще чаще всего, что если уж методы / функции созданы, то с ними лучше, чем без них. недавно разбирала похожую историю с foreach и array_map()

Voronve's picture

самое смешное, что именно в IT))))

Ну, вполне возможно, её там как раз и разработали ) Что-то типа: "Программа по оптимизации рабочего процесса и кадровой политики" ) Ещё раз спасибо )