【问题标题】:Character encoding issue with PDO_ODBCPDO_ODBC 的字符编码问题
【发布时间】:2011-03-28 21:14:07
【问题描述】:

当使用 PDO_ODBC 和以下代码从 PHP 访问 Microsoft SQL 数据库时,我遇到了编码问题。从数据库输出的文本是乱码。

$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);


(来源:bayimg.com

这是通过 Drupal 模块完成的。 Drupal 中的所有内容都可以使用 UTF-8。最干净的解决方案是能够以 UTF-8 从数据库中检索数据,或者在输出之前将其转换为 UTF-8。

我试过这些都没有成功

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

PS:代码目前是在 Windows 上开发的,但它也必须在 GNU/Linux 上运行。

【问题讨论】:

    标签: php drupal odbc pdo


    【解决方案1】:

    在 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 数据库的字符集或转换为客户端计算机字符集。

    【讨论】:

    • 如果我使用 ODBC-only 配置并连接 PHP PDO odbc,我无法获取 UTF-8 数据。
    【解决方案2】:

    将字符编码设置为 UTF-8 时,您还需要将查询编码为 UTF-8 并对结果进行解码。该字符集告诉驱动程序您本机使用 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);
    

    【讨论】:

    • 好吧,如前所述,这是通过 Drupal 模块完成的。 Drupal 期望所有字符串都是 UTF-8 编码的,它还输出其编码设置为 UTF-8 的页面。一旦将 ODBC 数据源配置为使用 UTF-8(请参阅我的答案),PDO 就会返回使用 dpm() 函数正确输出的 UTF-8 编码数据。对来自 PDO 的数据调用 utf8_decode() 会产生乱码输出,因为字符串将显示在 UTF-8 编码的页面中。
    【解决方案3】:

    您可以在连接字符串中使用 ClientCharset 属性(不带空格)设置所需的字符编码。 就我而言,它是 UTF-8。

    $connection_string = "DRIVER={FreeTDS};SERVER={$serverip};Port=1433;DATABASE={$dbname};ClientCharset={UTF-8}";
    
    $conn = odbc_connect($connection_string,$username,$pwd);
    

    详情请参考以下页面..

    https://www.freetds.org/userguide/dsnless.html

    【讨论】:

      【解决方案4】:

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

      $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;
      }
      

      【讨论】:

      • 关于 PDO 解决方案的问题请求,此答案未使用 PDO。此外,建议的解决方案与 Veggivore 几年前的解决方案是多余的(即使用 utf8_encode() 转换值)。
      【解决方案5】:

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

      第一 发布数据转换

      '$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";
      

      【讨论】:

        猜你喜欢
        • 2016-07-22
        • 2011-03-24
        • 1970-01-01
        • 1970-01-01
        • 2012-04-02
        • 1970-01-01
        • 2012-06-20
        • 1970-01-01
        相关资源
        最近更新 更多