Pergunta

Eu estou querendo saber o que a declaração do tipo de dados em bindParam() (ou bindValue() ) é usado para ...

Quer dizer, eu pensei que se eu definir um argumento inteiro (PDO::PARAM_INT), o argumento deve ser convertido para um inteiro, algo como

$delete->bindParam(1, $kill, PDO::PARAM_INT);
// should work like
$delete->bindParam(1, (int)$kill);

ou pelo menos lançar um erro se o argumento não é do tipo declarado. Mas este não é o caso.

pesquisando por aí, descobri que no arquivo php.net:

Oi tudo,

Atualmente, estou trabalhando em PDO. Exatamente na função bindParam (). O terceiro parâmetro data_type parece ser aqui para forçar o tipo do valor? Mas quando tento:

$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(); ?>

Eu estava esperando para ter tanto um PHP erro ou um inteiro no meu banco de dados. Mas no meu DB eu tenho:

22 Testarossa Ferrari 23 250 GTO Ferrari

Ele significa que ele não se alterou, se eu tem o terceiro parâmetro ou não. Ou talvez eu perca alguma coisa. Alguem pode tole-me mais? Ou apenas alguém pode disse-me onde posso encontrar informações sobre isso.

Saudações,

Cyruss

Isso é exatamente minha situação. Onde estão os meus pensamentos indo errado?

Foi útil?

Solução

Em outras estruturas DB abstração em outros idiomas ele pode ser usado para coisas como ter certeza que você está fazendo o escape apropriado para valores em revestimento (para os motoristas que não suportam parâmetros vinculados próprios) e melhorar a eficiência da rede, fazendo certo números são binários embalados de forma apropriada (dado suporte de protocolo). Parece que no DOP, não faz muito.

   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);
        }

Então, se você diz que é um STR (ou se você não dizer absolutamente nada, que é o padrão) e tipo interno dos seus dados é uma dupla, então ele irá transformá-lo em uma string usando um método, se não é um dobrar, em seguida, ele irá convertê-lo para uma string usando um método diferente.

Se você diz que é um int, mas é realmente um booleano, então ele irá convertê-lo para um longo.

Se você diz que é um booleano, mas é realmente um número, então ele irá convertê-lo em um verdadeiro booleano.

Este é realmente tudo o que vi (rapidamente) olhando para a fonte stmt, imagino uma vez que você passar os parâmetros para o motorista que pode fazer mágica adicional. Então, eu acho que tudo que você recebe é um pouco de fazer o certo e um monte de ambiguidade comportamento e variação entre os motoristas.

Outras dicas

Então eu decidi mergulhar no código-fonte PHP e é isso que eu encontrei.

static int really_register_bound_param em ext / DOP / pdo_stmt.c na linha 329 da versão 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);
}

Estas são as conversões DOP faz durante vinculativo.

  • convertidos PDO :: PARAM_STR o que quer que você dá para uma string, exceto nulo.
  • PDO :: converte PARAM_INT bools em longs
  • PDO :: converte PARAM_BOOL anseia em bools

É isso. Nada mais é convertido. DOP usa as bandeiras Param para formato SQL não aos tipos de dados elenco.

Há pelo menos um efeito PDO :: PARAM_INT tem sobre Inserir consultas: valores booleanos são convertidos para 0 ou 1. Como em

$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);
}

Eu tentei a mesma coisa com bindValue e obteve o mesmo resultado até o comportamento que você está vendo não é limitado a 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(); 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top