Подтвердить что ты не робот

PHP PDO:: bindParam() типы данных.. как это работает?

Мне интересно, что объявление типа данных в 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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Итак, я решил погрузиться в исходный код 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 преобразует longs в bools

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

Ответ 3

Там, по крайней мере, один эффект 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(param->parameter) == IS_BOOL) {
        convert_to_long(param->parameter);
}

Ответ 4

Я попробовал то же самое с 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();