Добавить PDO::PARAM_INT
или PDO::PARAM_STR
имеют какое-либо значение в запросе Mysql?
$sql = 'SELECT TagId FROM tagthread WHERE ThreadId = :ThreadId'; $stmt = $this->db->prepare($sql); $stmt->bindParam(':ThreadId', $threadid, PDO::PARAM_INT); $stmt->execute();
Да, используйте его.
Я сделал несколько тестов (с PDO :: ATTR_EMULATE_PREPARES false
), и я узнал, что кавычки вокруг значений будут разными.
Когда вы связываете целочисленное значение с PARAM_INT
не будет кавычек (строковое значение с PARAM_INT имеет кавычки). Если вы связываете целочисленное значение с PDO::PARAM_STR
будут кавычки, а mysql должен быть PDO::PARAM_STR
для integer.
Примеры:
$stmt->bindParam(':ThreadId', $threadid, PDO::PARAM_INT); $threadid = 123; // SELECT TagId FROM tagthread WHERE ThreadId = 123 $threadid = '123test'; // SELECT TagId FROM tagthread WHERE ThreadId = '123test' // mysql will cast 123test to 123
РЕДАКТИРОВАТЬ:
Я также проверил и прочитал эту тему. Вывод: Implicit casting is dangerous and can lead to unexpected results.
Подробнее об этом читайте здесь . Другим недостатком всегда использования PDO::PARAM_STR
является производительность. Подробнее о производительности Недостатки цитирования целых чисел в запросе Mysql?
Поэтому, если ваша колонка имеет тип [TINY|SMALL|MEDIUM|BIG]INT
чем использовать PARAM_INT
. И в случае, если это предложение LIMIT
, чем отличное от целого, если тип переменной в PHP не является целым.
Изменить: зависит! См. Комментарий к своему здравому смыслу ниже.
Если значение является целым числом, оно должно рассматриваться как целое число. Примените это как можно больше типов данных.
Если вы не установите для атрибута PDO :: ATTR_EMULATE_PREPARES значение false, вы получите неприятную ошибку.
Твердый пример:
$stmt = $dbh->prepare("SELECT * FROM table123 WHERE raw_field = :field LIMIT 1 OFFSET :offset;"); $stmt->bindParam(':field', $field); $stmt->bindParam(':offset', $offset); if ($map_stmt->execute()) { $data = stmt->fetch(PDO::FETCH_ASSOC); } else { echo 'Error :'; echo '<pre>'; print_r($map_stmt->errorInfo()); print_r($map_stmt->debugDumpParams()); echo '</pre>'; }
Вернет обратно неприятную ошибку, содержащую:
Код ошибки: 1064 У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '' 0 '' в строке 1
Запрос: SELECT * FROM table123 WHERE raw_field = 'home' LIMIT 1 OFFSET '0'
Бесполезно, что вы рассматриваете его как целое, и оно удалит строку (например: '').
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
В двух словах:
Твой выбор! Строгие данные или нет.
Я не могу сказать, для всех драйверов, поддерживаемых PDO, но для mysql нормально вообще не использовать PDO::PARAM_INT
.
Таким образом, нормально обходить bindParam
и отправлять вашу переменную непосредственно в execute()
:
$sql = 'SELECT TagId FROM tagthread WHERE ThreadId = ?'; $stmt = $this->db->prepare($sql); $stmt->execute([$threadid]);
Здесь ваша переменная $threadid
будет бесшумно привязана как строка, но для mysql не будет единой проблемой сравнивать ее с целым значением, хранящимся в базе данных.
Единственная проблема с строковым типом bindnig – это предложение LIMIT
в вашем SQL-запросе, где это приведет к ошибке, если режим эмуляции включен. Но это не должно быть проблемой, так как вы всегда можете отключить его.
Обратите внимание, что PDO::PARAM_INT
не PDO::PARAM_INT
ваше значение . Если вы пытаетесь связать значение типа строки с помощью этого режима, оно будет привязано как строка , даже если вы явно задали тип PDO::PARAM_INT
. Этот режим будет использоваться только для целочисленных значений.
Все остальные проблемы являются общими для свободной печати, и ни mysql, ни привязка PDO не имеют в них особого эффекта.
Кроме того, чтобы избежать возможных проблем, вы должны выбрать правильные типы столбцов для своих данных. Скажем, для больших целых чисел вы должны использовать BIGINT
, тогда как для любых ценовых данных это должно быть DECIMAL
. И сравнение не будет проблемой.