按照 上的研究所得,以及MYSQL文档上关于C API的介绍,测试了如下代码,
可以让PDO_MYSQL驱动返回正确的bool、整型、浮点数据。
先看测试:
1、测试表结构:
2、测试表数据:
3、测试程序输出:
下面是代码:
1、由diff得到的代码差异(PHP v5.3.2,MYSQL v5.1.42):
*** mysql_statement.c 2010-04-15 16:31:01.000000000 +0800
--- mysql_statement.c.new 2010-04-15 16:30:47.000000000 +0800
***************
*** 712,718 ****
} else
#endif
{
! cols[i].param_type = PDO_PARAM_STR;
}
}
PDO_DBG_RETURN(1);
--- 712,737 ----
} else
#endif
{
! // cols[i].param_type = PDO_PARAM_STR;
! // TODO: PDO_PARAM_ZVAL, PDO_PARAM_STMT, PDO_PARAM_LOB
! if(IS_NUM_FIELD(&(S->fields[i])) || S->fields[i].type == MYSQL_TYPE_NEWDECIMAL) {
! // IS_NUM(S->fields[i].type) && S->fields[i].type != MYSQL_TYPE_TIMESTAMP
! /*if(S->fields[i].type == MYSQL_TYPE_NULL) {
! cols[i].param_type = PDO_PARAM_NULL;
! else*/ if(S->fields[i].type == MYSQL_TYPE_TINY && S->fields[i].length == 1) {
! cols[i].param_type = PDO_PARAM_BOOL;
! } else if(S->fields[i].type == MYSQL_TYPE_LONGLONG) { // long long
! cols[i].param_type = PDO_PARAM_STR;
! } else if(S->fields[i].type == MYSQL_TYPE_FLOAT || S->fields[i].type == MYSQL_TYPE_DOUBLE) {
! cols[i].param_type = PDO_PARAM_ZVAL;
! } else {
! cols[i].param_type = PDO_PARAM_INT;
! }
! } /*else if(IS_LONGDATA(S->fields[i].type)) {
! cols[i].param_type = PDO_PARAM_LOB;
! }*/ else {
! cols[i].param_type = PDO_PARAM_STR;
! }
}
}
PDO_DBG_RETURN(1);
***************
*** 769,776 ****
PDO_DBG_RETURN(1);
}
#endif /* PDO_USE_MYSQLND else HAVE_MYSQL_STMT_PREPARE */
! *ptr = S->current_data[colno];
! *len = S->current_lengths[colno];
PDO_DBG_RETURN(1);
} /* }}} */
--- 788,826 ----
PDO_DBG_RETURN(1);
}
#endif /* PDO_USE_MYSQLND else HAVE_MYSQL_STMT_PREPARE */
! // *ptr = S->current_data[colno];
! // *len = S->current_lengths[colno];
! // TODO: PDO_PARAM_ZVAL, PDO_PARAM_STMT, PDO_PARAM_LOB
! if(IS_NUM_FIELD(&(S->fields[colno])) || S->fields[colno].type == MYSQL_TYPE_NEWDECIMAL) {
! // IS_NUM(S->fields[colno].type) && S->fields[colno].type != MYSQL_TYPE_TIMESTAMP
! /*if(S->fields[colno].type == MYSQL_TYPE_NULL) {
! cols[colno].param_type = PDO_PARAM_NULL;
! else*/ if(S->fields[colno].type == MYSQL_TYPE_TINY && S->fields[colno].length == 1) {
! *ptr = emalloc(sizeof(zend_bool));
! *(zend_bool*)*ptr = atol(S->current_data[colno]);
! *len = sizeof(zend_bool);
! *caller_frees = 1;
! } else if(S->fields[colno].type == MYSQL_TYPE_LONGLONG) { // long long
! *ptr = S->current_data[colno];
! *len = S->current_lengths[colno];
! } else if(S->fields[colno].type == MYSQL_TYPE_FLOAT || S->fields[colno].type == MYSQL_TYPE_DOUBLE) {
! zval *zv = emalloc(sizeof(zval));
! ZVAL_DOUBLE(zv, strtod(S->current_data[colno], NULL));
! *ptr = &zv;
! *len = sizeof(zval);
! *caller_frees = 0; // 因为fetch_value中自动析构了。
! } else {
! *ptr = emalloc(sizeof(long));
! *(long*)*ptr = atol(S->current_data[colno]);
! *len = sizeof(long);
! *caller_frees = 1;
! }
! } /*else if(IS_LONGDATA(S->fields[colno].type)) {
! cols[colno].param_type = PDO_PARAM_LOB;
! }*/ else {
! *ptr = S->current_data[colno];
! *len = S->current_lengths[colno];
! }
PDO_DBG_RETURN(1);
} /* }}} */
|
2、测试代码:
// 省略连接数据库代码。。。
$sql = "select * from $table limit 1";
$sth = $dbh->query($sql);
$sth->columnCount();
$row = $sth->fetch(PDO::FETCH_BOTH);
for($i = 0; $i < $sth->columnCount(); $i++) {
echo "************ col $i ************\n";
$meta = $sth->getColumnMeta($i);
echo "field: {$meta['name']}\n";
$native_type = (isset($meta['native_type']) ? $meta['native_type'] : 'NONE');
echo "native_type: {$native_type}\n";
$pdo_type = (isset($meta['pdo_type']) ? $meta['pdo_type'] : -1);
switch($pdo_type) {
case PDO::PARAM_BOOL: $pdo_type = 'BOOL'; break;
case PDO::PARAM_NULL: $pdo_type = 'NULL'; break;
case PDO::PARAM_INT : $pdo_type = 'INT'; break;
case PDO::PARAM_STR : $pdo_type = 'STR'; break;
case PDO::PARAM_LOB : $pdo_type = 'LOB'; break;
case PDO::PARAM_STMT: $pdo_type = 'STMT'; break;
case PDO::PARAM_INPUT_OUTPUT: $pdo_type = 'INPUT_OUTPUT'; break;
default: $pdo_type = 'NONE'; break;
}
echo "pdo_type: {$pdo_type}\n";
echo "value: ";
var_dump($row[$i]);
}
|
阅读(1138) | 评论(0) | 转发(0) |