php - mysql_real_escape_string - mysqli
El campo entero de MySQL se devuelve como una cadena en PHP (13)
Tengo un campo de tabla en una base de datos MySQL:
userid INT(11)
Así que lo estoy llamando a mi página con esta consulta:
"SELECT userid FROM DB WHERE name=''john''"
Entonces, para manejar el resultado, lo hago:
$row=$result->fetch_assoc();
$id=$row[''userid''];
Ahora si lo hago:
echo gettype($id);
Recibo una cadena. ¿No debería ser esto un número entero?
Cuando selecciona datos de una base de datos MySQL utilizando PHP, el tipo de datos siempre se convertirá en una cadena. Puede convertirlo a un número entero utilizando el siguiente código:
$id = (int) $row[''userid''];
O usando la función intval()
:
$id = intval($row[''userid'']);
En mi caso, se había instalado la extensión mysqlnd.so
. PERO no tuve pdo_mysqlnd.so
. Entonces, el problema se resolvió reemplazando pdo_mysql.so
con pdo_mysqlnd.so
.
En mi proyecto usualmente uso una función externa que "filtra" datos recuperados con mysql_fetch_assoc
.
Puede cambiar el nombre de los campos en su tabla para que sea intuitivo comprender qué tipo de datos se almacena.
Por ejemplo, puede agregar un sufijo especial a cada campo numérico: si userid
es un INT(11)
, puede cambiarle el nombre userid_i
o si es UNSIGNED INT(11)
puede renombrar userid_u
. En este punto, puede escribir una función PHP simple que reciba como entrada la matriz asociativa (recuperada con mysql_fetch_assoc
), y aplique la conversión al "valor" almacenado con esas "claves" especiales.
Esto sucede cuando PDO::ATTR_EMULATE_PREPARES
se establece en true
en la conexión.
Me gusta la respuesta de Chad, especialmente cuando los resultados de la consulta se pasan a javascript en un navegador. Javascript trata limpiamente con entidades similares numéricas como números, pero requiere un trabajo adicional para tratar entidades numéricas como cadenas. es decir, debe usar parseInt o parseFloat en ellos.
Sobre la base de la solución de Chad, uso esto y a menudo es exactamente lo que necesito y crea estructuras que pueden ser codificadas en JSON para que sean fáciles de manejar en javascript.
while ($row = $result->fetch_assoc()) {
// convert numeric looking things to numbers for javascript
foreach ($row as &$val) {
if (is_numeric($val))
$val = $val + 0;
}
}
Agregar una cadena numérica a 0 produce un tipo numérico en PHP e identifica correctamente el tipo para que los números de coma flotante no se trunquen en enteros.
Mi solución es pasar el resultado de la consulta $rs
y obtener una matriz assoc de los datos casted como la devolución:
function cast_query_results($rs) {
$fields = mysqli_fetch_fields($rs);
$data = array();
$types = array();
foreach($fields as $field) {
switch($field->type) {
case 3:
$types[$field->name] = ''int'';
break;
case 4:
$types[$field->name] = ''float'';
break;
default:
$types[$field->name] = ''string'';
break;
}
}
while($row=mysqli_fetch_assoc($rs)) array_push($data,$row);
for($i=0;$i<count($data);$i++) {
foreach($types as $name => $type) {
settype($data[$i][$name], $type);
}
}
return $data;
}
Ejemplo de uso:
$dbconn = mysqli_connect(''localhost'',''user'',''passwd'',''tablename'');
$rs = mysqli_query($dbconn, "SELECT * FROM Matches");
$matches = cast_query_results($rs);
// $matches is now a assoc array of rows properly casted to ints/floats/strings
MySQL tiene controladores para muchos otros idiomas, la conversión de datos a cadenas "estandariza" los datos y deja que el usuario los escriba a valores int u otros
No. Independientemente del tipo de datos definido en sus tablas, el controlador MySQL de PHP siempre sirve los valores de fila como cadenas.
Necesitas lanzar tu ID a un int.
$row = $result->fetch_assoc();
$id = (int) $row[''userid''];
Poner un plus antes de la variable también hace el truco,
$a = "120";
$b = +$a;
echo gettype($b);
Obviamente no es la mejor manera, pero funciona cuando no tienes acceso al entorno para instalar un mejor controlador.
Puedes hacer esto con ...
... dependiendo de la extensión que quieras usar. El primero no se recomienda porque la extensión mysql está en desuso. El tercero es aún experimental.
Los comentarios en estos hipervínculos hacen un buen trabajo al explicar cómo establecer su tipo desde una cadena antigua simple a su tipo original en la base de datos.
Algunos marcos también resumen esto (CodeIgniter proporciona $this->db->field_data()
).
También podría hacer conjeturas, como recorrer las filas resultantes y usar is_numeric() en cada una. Algo como:
foreach($result as &$row){
foreach($row as &$value){
if(is_numeric($value)){
$value = (int) $value;
}
}
}
Esto convertiría cualquier cosa que se parece a un número en uno ... definitivamente no perfecto.
Si se utilizan declaraciones preparadas, el tipo será int cuando corresponda. Este código devuelve una matriz de filas, donde cada fila es una matriz asociativa. Me gusta si se llamó a fetch_assoc()
para todas las filas, pero con la información de tipo preservado.
function dbQuery($sql) {
global $mysqli;
$stmt = $mysqli->prepare($sql);
$stmt->execute();
$stmt->store_result();
$meta = $stmt->result_metadata();
$params = array();
$row = array();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
call_user_func_array(array($stmt, ''bind_result''), $params);
while ($stmt->fetch()) {
$tmp = array();
foreach ($row as $key => $val) {
$tmp[$key] = $val;
}
$ret[] = $tmp;
}
$meta->free();
$stmt->close();
return $ret;
}
Use el mysqlnd (controlador nativo) para php.
Si estás en Ubuntu:
sudo apt-get install php5-mysqlnd
sudo service apache2 restart
Si estás en Centos:
sudo yum install php-mysqlnd
sudo service httpd restart
El controlador nativo devuelve los tipos enteros de forma apropiada.
Editar:
Como @Jeroen ha señalado, este método solo funcionará de inmediato para PDO.
Como @LarsMoelleken ha señalado, este método funcionará con mysqli si también establece la opción MYSQLI_OPT_INT_AND_FLOAT_NATIVE en verdadero.
Ejemplo:
$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);
La solución más fácil que encontré:
Puede forzar que json_encode use números reales para valores que se parecen a números:
json_encode($data, JSON_NUMERIC_CHECK)
(desde PHP 5.3.3).
O podrías simplemente lanzar tu ID a un int.
$row = $result->fetch_assoc();
$id = (int) $row[''userid''];