PDO_ODBC 的字符编码问题

发布于 2024-09-14 09:02:31 字数 1215 浏览 5 评论 0 原文

当使用 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') < 之后code>new PDO(...)
  • $pdo->exec('SET CHARACTER SET utf8');new PDO(...) 之后

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

When accessing a Microsoft SQL Database from PHP using PDO_ODBC with the following code, I have an encoding issue. When outputed the text from the DB is garbled.

$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
(source: bayimg.com)

This is done from a Drupal module. Everything in Drupal is made to work with UTF-8. The cleanest solution would be to able to retrieve the data from the database in UTF-8 or to convert it UTF-8 before outputting.

I tried these without any success

  • $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') after new PDO(...)
  • $pdo->exec('SET CHARACTER SET utf8'); after new PDO(...)

PS: The code is currently developped on Windows but it has to work on GNU/Linux too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

触ぅ动初心 2024-09-21 09:02:31

在 Linux 上运行并使用 FreeTDS 驱动程序时,可以使用 客户端字符集 设置来配置客户端的字符集.htm" rel="noreferrer">freetds.conf 文件。为了在使用 PDO ODBC 和 unixODBC 时使用 freetds.conf 文件,需要使用 ODBC 组合配置。当使用 仅限 ODBC 配置 来配置 ODBC 数据源时,文件 freetds .conf 未使用。这样我就能够从 MS SQL Server 数据库中检索和插入 UTF-8 数据。

作为一名 Linux/Unix 人员,我无法理解/找到如何配置在 Windows 上使用 PDO ODBC 时使用的字符集的方法。我的模糊理解是,当在系统级别配置时,ODBC 数据源可以配置为使用 SQL Server 数据库的字符集或转换为客户端计算机的字符集。

When running on Linux and using the FreeTDS driver, the charset for the client can be configured with the client charset setting in the freetds.conf file. In order for the freetds.conf file to be used when using PDO ODBC and unixODBC, one needs to configure the ODBC datasource using ODBC-combined configuration. When ODBC-only configuration is used to configure the ODBC datasource, the file freetds.conf is not used. With this I was able to retrieve and insert UTF-8 data from/into the MS SQL Server database.

Being a Linux/Unix guy, I was unable to understand/find a way how to configure the charset used when PDO ODBC is used on Windows. My vague understanding is that when configured at the system level, an ODBC datasource can be configured to use either de SQL Server database's charset or convert to the client computer charset.

心碎的声音 2024-09-21 09:02:31

将字符编码设置为 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);

When setting the character encoding to UTF-8, you will also need to encode your queries as UTF-8 and decode the results. The charset is telling the driver that you speak UTF8 natively. As such, you need to convert the UTF8 back to what PHP understands (ASCII or 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);
没企图 2024-09-21 09:02:31

您可以使用连接字符串中的 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

You can set desired character encoding with ClientCharset attribute (without a space) in connection string.
In my case it was UTF-8.

$connection_string = "DRIVER={FreeTDS};SERVER={$serverip};Port=1433;DATABASE={$dbname};ClientCharset={UTF-8}";

$conn = odbc_connect($connection_string,$username,$pwd);

Please refer to following page for details..

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

苍暮颜 2024-09-21 09:02:31

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

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

You can use this code to fix your problem:

$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;
}
对不⑦ 2024-09-21 09:02:31

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

首先
发布数据转换

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

You can use this code to fix your problem:

First
Post Data Convert

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

And
Read Data Convert

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

SQL String

$sql = "SELECT * FROM yourtables WHERE text LIKE '%{$word}%'";
or
$sql = "SELECT * FROM yourtables";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文