解决方法是在查询出结果后对数据进行转码
找到 ThinkPHP/Lib/Core/Db.class.php
在其中添加如下转码函数
public function iconv2utf8($Result) {
$Row = array();
$key1=array_keys($Result);
$key2 = array_keys($Result[$key1[0]]);
for($i=0;$i<count($key1);$i++) {
for( $j=0; $j<count( $key2 ); $j++ ) {
$Row[ $key1[ $i ] ][ $key2[ $j ] ] = iconv( 'gb2312', 'utf-8', $Result[ $key1[ $i ] ][ $key2[ $j ] ] );
}
}
return $Row;
}
utf8 转 gbk public function iconv2gbk($string) {
return iconv( 'utf-8','gb2312' ,$string );
}
之后找到 select 函数在
$result = $this->query($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:array()));
行下面添加if ( C( 'DB_TYPE' ) == 'mssql' ) {
$result = self::iconv2utf8($result);
}
对数据进行转码完整函数如下
/**
* 查找记录
* @access public
* @param array $options 表达式
* @return mixed
*/
public function select($options=array()) {
$this->model = $options['model'];
$sql = $this->buildSelectSql($options);
$cache = isset($options['cache'])?$options['cache']:false;
if($cache) { // 查询缓存检测
$key = is_string($cache['key'])?$cache['key']:md5($sql);
$value = S($key,'',$cache);
if(false !== $value) {
return $value;
}
}
$result = $this->query($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:array()));
if ( C( 'DB_TYPE' ) == 'mssql' ) {
$result = self::iconv2utf8($result);
}
if($cache && false !== $result ) { // 查询缓存写入
S($key,$result,$cache);
}
return $result;
}
插入 以及 更新数据乱码解决找到 parseSet 函数
在 foreach 循环下添加
if ( C( 'DB_TYPE' ) == 'mssql' ) {
$val = $this->iconv2gbk( $val );
}
完整代码如下: /**
* set分析
* @access protected
* @param array $data
* @return string
*/
protected function parseSet($data) {
foreach ($data as $key=>$val){
if ( C( 'DB_TYPE' ) == 'mssql' ) {
$val = $this->iconv2gbk( $val );
}
if(is_array($val) && 'exp' == $val[0]){
$set[] = $this->parseKey($key).'='.$val[1];
}elseif(is_scalar($val) || is_null(($val))) { // 过滤非标量数据
if(C('DB_BIND_PARAM') && 0 !== strpos($val,':')){
$name = md5($key);
$set[] = $this->parseKey($key).'=:'.$name;
$this->bindParam($name,$val);
}else{
$set[] = $this->parseKey($key).'='.$this->parseValue($val);
}
}
}
return ' SET '.implode(',',$set);
}
找到 insert 函数在 foreach 下添加
if ( C( 'DB_TYPE' ) == 'mssql' ) {
$val = $this->iconv2gbk( $val );
}
完整代码如下: /**
* 插入记录
* @access public
* @param mixed $data 数据
* @param array $options 参数表达式
* @param boolean $replace 是否replace
* @return false | integer
*/
public function insert($data,$options=array(),$replace=false) {
$values = $fields = array();
$this->model = $options['model'];
foreach ($data as $key=>$val){
if ( C( 'DB_TYPE' ) == 'mssql' ) {
$val = $this->iconv2gbk( $val );
}
if(is_array($val) && 'exp' == $val[0]){
$fields[] = $this->parseKey($key);
$values[] = $val[1];
}elseif(is_scalar($val) || is_null(($val))) { // 过滤非标量数据
$fields[] = $this->parseKey($key);
if(C('DB_BIND_PARAM') && 0 !== strpos($val,':')){
$name = md5($key);
$values[] = ':'.$name;
$this->bindParam($name,$val);
}else{
$values[] = $this->parseValue($val);
}
}
}
$sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')';
$sql .= $this->parseLock(isset($options['lock'])?$options['lock']:false);
$sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:'');
return $this->execute($sql,$this->parseBind(!empty($options['bind'])?$options['bind']:array()));
}
做完这些 基本上和mssql交互就不会乱码了当然 如果怕动了那源码导致查询出现问题 可以将原Db.class.php 改名为 DbSrc.class.php 并且 修改 class 为
class DbSrc { ... }
然后新建个名为 Db.class.php 的文件 继承 DbSrc 将上述的几个函数放进去就可以了
但是效率。。。
坑爹。。
thinkphp_mssql_charset.tar.gz
( 8.5 KB 下载:56 次 )
最佳答案
