I have a table field in a MySQL database:
userid INT(11)
So I am calling it to my page with this query:
\"SELECT userid FR
If prepared statements are used, the type will be int where appropriate. This code returns an array of rows, where each row is an associative array. Like if fetch_assoc()
was called for all rows, but with preserved type info.
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;
}
I like mastermind's technique, but the coding can be simpler:
function cast_query_results($result): array
{
if ($result === false)
return null;
$data = array();
$fields = $result->fetch_fields();
while ($row = $result->fetch_assoc()) {
foreach ($fields as $field) {
$fieldName = $field->name;
$fieldValue = $row[$fieldName];
if (!is_null($fieldValue))
switch ($field->type) {
case 3:
$row[$fieldName] = (int)$fieldValue;
break;
case 4:
$row[$fieldName] = (float)$fieldValue;
break;
// Add other type conversions as desired.
// Strings are already strings, so don't need to be touched.
}
}
array_push($data, $row);
}
return $data;
}
I also added checking for query returning false rather than a result-set.
And checking for a row with a field that has a null value.
And if the desired type is a string, I don't waste any time on it - its already a string.
I don't bother using this in most php code; I just rely on php's automatic type conversion. But if querying a lot of data, to then perform arithmetic computations, it is sensible to cast to the optimal types up front.
My solution is to pass the query result $rs
and get a assoc array of the casted data as the return:
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;
}
Example usage:
$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
No. Regardless of the data type defined in your tables, PHP's MySQL driver always serves row values as strings.
You need to cast your ID to an int.
$row = $result->fetch_assoc();
$id = (int) $row['userid'];
Easiest Solution I found:
You can force json_encode to use actual numbers for values that look like numbers:
json_encode($data, JSON_NUMERIC_CHECK)
(since PHP 5.3.3).
Or you could just cast your ID to an int.
$row = $result->fetch_assoc();
$id = (int) $row['userid'];
For mysqlnd only:
mysqli_options($conn, MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
Otherwise:
$row = $result->fetch_assoc();
while ($field = $result->fetch_field()) {
switch (true) {
case (preg_match('#^(float|double|decimal)#', $field->type)):
$row[$field->name] = (float)$row[$field->name];
break;
case (preg_match('#^(bit|(tiny|small|medium|big)?int)#', $field->type)):
$row[$field->name] = (int)$row[$field->name];
break;
}
}