我曾经尝试使用mysql_fetch_row()
和mysql_result()
来获取MySQL查询结果,但是数字值以字符串的形式返回。
有没有办法按照表中存储的数据类型获取数据?
该应用程序将查询许多不同的查询,因此我无法逐个将值转换为预期的数据类型。
我认为在PHP 5.2中无法以原生数据类型获取数据(即除了字符串以外的任何内容)...
在PHP 5.3中,如果我没记错的话,当您使用新的mysqlnd(MySQL Native Driver)驱动程序时,这就成为可能。
在查找我的书签时,我找到了关于mysqlnd的这篇文章:PDO_MYSQLND: PHP 5.3中PDO_MYSQL的新功能
它说(引用):
使用mysqlnd for PDO的优势
使用服务器端准备语句时,mysqlnd会返回本机数据类型, 例如,INT列将作为整数变量返回而不是字符串。 这意味着内部进行的数据转换更少。
但这仅适用于PHP 5.3(前提是您的PHP 5.3版本已编译mysqlnd(而不是旧的libmysql)),似乎只适用于准备好的语句 :-(
在您的情况下,这并没有太大帮助,我猜...
这里还有一篇关于mysqlnd新特性的文章,不仅涉及到预处理语句: PHP:使用mysqlnd实现网络流量、CPU和内存的节省。
不确定这是否已经合并到官方的mysqlnd驱动程序中,最好的方法是尝试;但无论如何,它仍然只适用于PHP >= 5.3...
另一种解决方案是,在PHP端使用一种映射系统(如ORM),将从数据库返回的结果转换为PHP数据类型...
如果您想使用像 ===
和!==
这样的运算符,那么这是不好的,因为它们是类型敏感的...
如果使用 mysqli 而不是 PDO,请尝试这个
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')");
$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));
?>
id = 1 (integer)
label = a (string)
/**
* Converts columns from strings to types according to
* PDOStatement::columnMeta
*
* @param PDOStatement $st
* @param array $assoc returned by PDOStatement::fetch with PDO::FETCH_ASSOC
* @return copy of $assoc with matching type fields
*/
function convertTypes(PDOStatement $statement, $assoc)
{
for ($i = 0; $columnMeta = $statement->getColumnMeta($i); $i++)
{
$type = $columnMeta['native_type'];
switch($type)
{
case 'DECIMAL':
case 'TINY':
case 'SHORT':
case 'LONG':
case 'LONGLONG':
case 'INT24':
$assoc[$columnMeta['name']] = (int) $assoc[$columnMeta['name']];
break;
case 'DATETIME':
case 'DATE':
case 'TIMESTAMP':
$assoc[$columnMeta['name']] = strtotime($assoc[$columnMeta['name']]);
break;
// default: keep as string
}
}
return $assoc;
}
当然,类型列表并不完整,转换也过于简化,但对于入门可能会有所帮助。