Мне интересно, что объявление типа данных в bindParam()
(или bindValue()
) используется для …
Я имею в виду, я думал, что если я определяю целочисленный аргумент ( PDO::PARAM_INT
), аргумент должен быть преобразован в целое число, что-то вроде
$delete->bindParam(1, $kill, PDO::PARAM_INT); // should work like $delete->bindParam(1, (int)$kill);
или, по крайней мере, выдать ошибку, если аргумент не относится к объявленному типу. Но это не так.
Открывая поиски, я обнаружил, что в архиве php.net:
Всем привет,
В настоящее время я работаю над PDO. Именно в функции bindParam (). Третий параметр data_type, похоже, здесь, чтобы заставить тип значения? Но когда я пытаюсь:
$sql = "INSERT INTO produit (idproduit, nom, marque) VALUES (NULL, :nom, :marque)"; $stmt = $dbh->prepare($sql); $nom = 'Testarossa'; $marque = 'Ferrari' ; $stmt->BindValue(':marque',$marque) ; $stmt->BindParam(':nom',$nom,PDO::PARAM_INT) ; $stmt->execute(); $nom = '250 GTO' ; $stmt->execute(); ?>
Я ожидал, что в моей базе данных будет либо PHP-ошибка, либо interger. Но в моей БД я:
22 Testarossa Ferrari 23 250 GTO Ferrari
Это означает, что он не изменился, если у меня есть третий параметр или нет. Или, может быть, я что-то упустил. Может ли кто-нибудь еще мне подружиться? Или просто кто-то сказал мне, где я могу найти информацию об этом.
С Уважением,
Cyruss
Это именно моя ситуация. Где мои мысли идут не так?
В других структурах абстракции БД на других языках его можно использовать для таких вещей, как обеспечение правильного выполнения экранирования для значений внутри оболочки (для драйверов, которые не поддерживают соответствующие связанные параметры), и повышения эффективности сети, убедившись, что числа бинарный упакованный соответствующим образом (с учетом поддержки протокола). Похоже, в PDO это мало что делает.
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { char *p; int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); ZVAL_STRINGL(param->parameter, p, len, 0); } else { convert_to_string(param->parameter); } } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { convert_to_long(param->parameter); } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) { convert_to_boolean(param->parameter); }
Итак, если вы говорите, что это STR (или если вы вообще ничего не говорите, поскольку это значение по умолчанию), а внутренний тип данных – двойной, то он превратит его в строку с использованием одного метода, если он не является двойным, тогда преобразует его в строку, используя другой метод.
Если вы говорите, что это int, но это действительно bool, то он преобразует его в длинный.
Если вы говорите, что это bool, но это действительно номер, он преобразует его в истинное логическое.
Это действительно все, что я видел (быстро), глядя на источник stmt, я представляю, как только вы передадите параметры в драйвер, они могут сделать дополнительную магию. Итак, я бы предположил, что все, что у вас есть, – это немного правильное и многозначительное двусмысленность и различие между драйверами.
Поэтому я решил погрузиться в исходный код PHP, и это то, что я нашел.
static int really_register_bound_param
в static int really_register_bound_param
ext / pdo / pdo_stmt.c в строке 329 версии 5.2.9
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { char *p; int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); ZVAL_STRINGL(param->parameter, p, len, 0); } else { convert_to_string(param->parameter); } } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { convert_to_long(param->parameter); } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) { convert_to_boolean(param->parameter); }
Это PDO конверсий во время привязки.
Вот и все. Больше ничего не преобразуется. PDO использует флаги PARAM для форматирования SQL, чтобы не использовать типы данных.
По крайней мере, один эффект PDO :: PARAM_INT имеет запросы INSERT : логические значения преобразуются в 0 или 1. Как и в
$i = true; $stmt->bindParam(':i', $v, PDO::PARAM_INT);
pdo_stmt.c:
else if (PDO_PARAM_TYPE (param-> param_type) == PDO_PARAM_INT && Z_TYPE_P (параметр-> параметр) == IS_BOOL) { convert_to_long (парамет-> параметр); }
Я попробовал то же самое с BindValue и получил тот же результат, поэтому поведение, которое вы видите, не ограничено bindParam.
$stmt->BindValue(':marque', $marque) ; $stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ; $stmt->execute(); $nom = '250 GTO'; $stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ; $stmt->execute();