PHP PDO:: bindParam () tipos de datos.. ¿cómo funciona?


Me pregunto lo que la declaración del tipo de datos en bindParam() (o bindValue()) se utiliza para...

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

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

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

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

Hola a todos,

Actualmente estoy trabajando en PDO. Exactamente en la función bindParam (). Tercero 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 interger 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 tal vez me he perdido algo. Puede alguien ¿me pegas más ? O simplemente puede alguien me dijo dónde puedo encontrar información respecto.

Saludos,

Cyruss

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

Author: Shi, 2009-05-07

4 answers

En otros frameworks de abstracción de BD en otros lenguajes, se puede usar para cosas como asegurarse de que está haciendo el escape adecuado para los valores internos (para controladores que no admiten parámetros enlazados adecuados) y mejorar la eficiencia de la red asegurándose de que los números estén empaquetados binarios adecuadamente (dado el soporte del protocolo). Parece que en la 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);
        }

Por lo tanto, si dice que es un STR (o si no dice nada en absoluto, ya que es el valor predeterminado) y los datos internos type es un double entonces lo convertirá en una cadena usando un método, si no es un double entonces lo convertirá en una cadena usando un método diferente.

Si usted dice que es un int pero es realmente un bool entonces lo convertirá a un largo.

Si dices que es un bool pero es realmente un número, entonces lo convertirá a un verdadero booleano.

Esto es realmente todo lo que vi (rápidamente) mirando la fuente stmt, imagino que una vez que pase los parámetros en el controlador pueden hacer magia adicional. Por lo tanto, supongo que todo lo que obtienes es un poco de hacer lo correcto y un montón de ambigüedad de comportamiento y varianza entre los conductores.

 32
Author: Trey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-14 21:43:19

Así que decidí sumergirme en el código fuente 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 el enlace.

  • PDO::PARAM_STR convierte lo que se le da a una cadena excepto null.
  • PDO:: PARAM_INT convierte bolos en largos
  • PDO:: PARAM_BOOL convierte longs en bools

Eso es todo. Nada más se convierte. PDO utiliza las banderas PARAM para formatee SQL para no convertir tipos de datos.

 20
Author: gradbot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-26 17:28:14

Hay al menos un efecto que tiene PDO::PARAM_INT en las consultas INSERT: los valores booleanos se convierten a 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);
}
 6
Author: VolkerK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-07 10:49:17

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(); 
 3
Author: gradbot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-14 20:38:57