Pregunta

Me pregunto cuál es la declaración del tipo de datos en bindParam ( ) (o bindValue () ) se usa para ...

Quiero decir, pensé que si definía un argumento entero ( PDO :: PARAM_INT ), el argumento debe convertirse a un entero, algo así como

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

o al menos arrojar un error si el argumento no es del tipo declarado. Pero este no es el caso.

Buscando en Google, encontré eso en el archivo php.net:

  

Hola a todos,

     

Actualmente estoy trabajando en PDO. Exactamente   en la función bindParam (). El tercero   el parámetro data_type parece estar aquí   para forzar el tipo del valor? Pero   cuando lo intento:

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

Esperaba tener un PHP   error o un número entero en mi base de datos.   Pero en mi DB tengo:

     

22 Testarossa Ferrari 23 250 GTO   Ferrari

     

Significa que no cambió si yo   tener el tercer parámetro o no. O   Quizás extraño algo. Puede alguien   me toleras mas? O simplemente alguien puede   me dijo donde puedo encontrar información   al respecto.

     

Saludos,

     

Cyruss

Esa es exactamente mi situación. ¿Dónde van mis pensamientos mal?

¿Fue útil?

Solución

En otros marcos de abstracción de bases de datos en otros idiomas, se puede usar para cosas como asegurarse de que está haciendo el escape adecuado para los valores en línea (para controladores que no admiten parámetros enlazados adecuados) y mejorar la eficiencia de la red haciendo ciertos números están empaquetados binariamente de manera apropiada (dado el soporte de protocolo). Parece que en DOP, no hace mucho.

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

Entonces, si dices que es un STR (o si no dices nada, ya que ese es el valor predeterminado) y el tipo interno de tus datos es un doble, lo convertirá en una cadena usando un método, si no es un doble y luego lo convertirá en una cadena usando un método diferente.

Si dice que es un int pero realmente es un bool, entonces lo convertirá en un largo.

Si dice que es un bool pero es realmente un número, lo convertirá en un verdadero booleano.

Esto es realmente todo lo que vi (rápidamente) mirando la fuente stmt, imagino que una vez que pasas los parámetros al controlador, pueden hacer magia adicional. Entonces, supongo que todo lo que obtienes es un poco de hacer lo correcto y mucha ambigüedad de comportamiento y variación entre los controladores.

Otros consejos

Así que decidí sumergirme en el código fuente de PHP y esto es lo que encontré.

static int really_register_bound_param en ext / pdo / pdo_stmt.c en la línea 329 de la versión 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 son las conversiones que hace PDO durante la unión.

  • PDO :: PARAM_STR convierte lo que le dé a una cadena, excepto nulo.
  • PDO :: PARAM_INT convierte bools en largos
  • PDO :: PARAM_BOOL convierte largos en bools

Eso es todo. Nada más se convierte. PDO usa los indicadores PARAM para formatear SQL para no emitir tipos de datos.

Hay al menos un efecto que PDO :: PARAM_INT tiene en las consultas INSERT : los valores booleanos se convierten en 0 o 1. Como en

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

Intenté lo mismo con BindValue y obtuve el mismo resultado, por lo que el comportamiento que está viendo no se limita 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top