PHP PDO :: tipos de datos bindParam () ... ¿cómo funciona?
-
08-07-2019 - |
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?
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();