Вопрос

Мне интересно, что означает объявление типа данных в 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 , либо вмешательство в мою базу данных.Но в моей базе данных у меня есть :

22 Тестаросса Ferrari 23 250 GTO Ferrari

Это значит, что она не изменится, если я есть третий параметр или нет.Или возможно, я что-то упустил.Может кто-нибудь рассказать мне больше?Или просто может кто-нибудь сказал мне, где я могу найти информацию об этом.

С уважением,

Сайрусс

Это именно моя ситуация.Где мои мысли идут не так, как надо?

Это было полезно?

Решение

В других фреймворках абстракции БД на других языках его можно использовать для таких целей, как убедиться, что вы выполняете правильное экранирование для встроенных значений (для драйверов, которые не поддерживают надлежащие связанные параметры) и повысить эффективность сети, убедившись, что числа правильно упакованы в двоичный формат (при условии поддержки протокола).Похоже, в 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 (или если вы вообще ничего не говорите, поскольку это значение по умолчанию), а внутренний тип ваших данных - double, то он превратит их в строку, используя один метод, если это не double, то он преобразует их в строку, используя другой метод.

Если вы скажете, что это int, но на самом деле это bool, то он преобразует его в long .

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

Это действительно все, что я увидел (быстро), просматривая исходный код stmt, я полагаю, что как только вы передадите параметры в драйвер, они могут сотворить дополнительную магию.Итак, я бы предположил, что все, что вы получаете, - это немного правильных действий и множество неоднозначностей в поведении и различий между драйверами.

Другие советы

Поэтому я решил погрузиться в исходный код PHP, и вот что я нашел.

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_STR преобразует все, что вы ему даете, в строку, кроме null .
  • PDO::PARAM_INT преобразует bools в longs
  • PDO::PARAM_BOOL преобразует длинные значения в bools

Вот и все.Ничто другое не преобразуется.PDO использует флаги PARAM для форматирования SQL, а не для приведения типов данных.

Существует по крайней мере один эффект, который PDO::PARAM_INT оказывает на ВСТАВИТЬ запросы:логические значения преобразуются в 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(param->parameter) == IS_BOOL) {
        convert_to_long(param->parameter);
}

Я попробовал то же самое с 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(); 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top