2010-08-12 205 views
7

使用PDO_ODBC使用以下代码从PHP访问Microsoft SQL数据库时,存在编码问题。当输出数据库中的文本出现乱码时。PDO_ODBC的字符编码问题

$dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;charset=UTF-8"; 
$pdo = new PDO($dsn,$username,$password); 
$sql = "SELECT text FROM atable"; 
$result = $PDO->query($sql); 
while($data = $result->fetchObject()){ 
    $values[] = $data->text; 
} 
dpm($values); 

garbled output http://image.bayimg.com/naomcaacd.jpg

这是从一个Drupal模块来完成。 Drupal中的所有东西都可以与UTF-8一起工作。最简洁的解决方案是能够以UTF-8格式从数据库中检索数据或在输出之前将其转换为UTF-8格式。

我想这些没有任何成功

  • $dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;charset=utf-8"
  • $pdo->exec('SET NAMES utf8')

    • $dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;client_charset=utf-8"
    • new PDO(...)
    • $pdo->exec('SET CHARACTER SET utf8');new PDO(...)

    PS:代码当前developped在Windows,但它具有也可以在GNU/Linux上工作。

  • 回答

    5

    在Linux上运行并使用FreeTDS驱动程序时,可以使用freetds.conf文件中的client charset设置来配置客户端的字符集。为了在使用PDO ODBC和unixODBC时使用freetds.conf文件,需要使用ODBC-combined configuration来配置ODBC数据源。当使用ODBC-only configuration来配置ODBC数据源时,不使用文件freetds.conf。有了这个,我能够从MS SQL Server数据库中检索并插入UTF-8数据。

    作为一名Linux/Unix家伙,我无法理解/发现如何配置在Windows上使用PDO ODBC时使用的字符集。我的模糊认识是,在系统级配置时,可以将ODBC数据源配置为使用de SQL Server数据库的字符集或转换为客户端计算机字符集。

    +0

    如果我使用的唯一的ODBC的配置和使用PHP PDO ODBC进行连接,我不能让UTF-8的数据。 – 2016-11-14 23:32:09

    2

    将字符编码设置为UTF-8时,还需要将查询编码为UTF-8并对结果进行解码。 charset正在告诉驱动程序,你自己说的是UTF8。因此,您需要将UTF8转换回PHP可以理解的内容(ASCII或mbstring)。

    $dsn = "odbc:DRIVER={SQL Server};SERVER=$hostname;DATABASE=$database;charset=UTF-8"; 
    $pdo = new PDO($dsn,$username,$password); 
    $sql = utf8_encode("SELECT text FROM atable"); 
    $result = $PDO->query($sql); 
    while($data = $result->fetchObject()){ 
        $values[] = utf8_decode($data->text); 
        // possibly also: $values[] = utf8_decode($data[utf8_encode('text')]); 
    } 
    dpm($values); 
    
    +0

    那么,如上所述,这是从一个Drupal模块完成的。 Drupal期望所有的字符串都是UTF-8编码的,它也会输出其编码设置为UTF-8的页面。一旦将ODBC数据源配置为使用UTF-8(请参阅我的答案),PDO就会返回正确使用dpm()函数输出的UTF-8编码数据。对来自PDO的数据调用utf8_decode()会产生乱码,因为该字符串将以UTF-8编码的页面显示。 – 2011-12-06 10:08:38

    +0

    谢谢,我的工作很完美。 – Dharmavir 2012-07-30 07:42:40

    0

    您可以使用此代码来解决您的问题:

    $result = odbc_exec($this->con, $sql);  
    $data = fetch2Array($result); 
    
    private function fetch2Array($result){  
        $rows = array(); 
    
        while($myRow = odbc_fetch_array($result)){ 
         $rows[] = $this->arrayToUTF($myRow); 
        } 
        return $rows; 
    } 
    
    private function arrayToUTF($arr){ 
        foreach ($arr as $key => $value) { 
         $arr[$key] = utf8_encode($value); 
        } 
        return $arr; 
    } 
    
    +0

    PDO解决方案的问题请求,此答案不使用PDO。另外,建议的解决方案在Veggivore的一年前也是多余的(也就是将值转换为utf8_encode())。 – 2016-06-02 17:42:27

    0

    您可以使用此代码来解决您的问题:

    首先 后的数据转换

    '$word = iconv("UTF-8","Windows-1254",$_POST['search']);' 
    

    而 读取数据转换

    while($data = $result->fetchObject()){ 
        $values[] = iconv("Windows-1254", "UTF-8",$data->text)); 
    } 
    

    SQL字符串

    $sql = "SELECT * FROM yourtables WHERE text LIKE '%{$word}%'"; 
    or 
    $sql = "SELECT * FROM yourtables";