thinkphp mssql 中文乱码解决。。。

浏览:3968 发布日期:2014/02/24 分类:技术分享 关键字: mssql tp3.1.3 charset
sqlserver 默认编码是 gb2312 而php或者说thinkphp的默认编码是utf-8那么在数据库中查询出来的数据展示的时候将会乱码

解决方法是在查询出结果后对数据进行转码

找到 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 次 )

最佳答案
评论( 相关
后面还有条评论,点击查看>>