19

我似乎无法使用 FreeTDS 扩展从编码为 UTF-8 的 MSSQL 获取数据。

连接:

ini_set('mssql.charset', 'UTF-8');
$this->_resource = mssql_connect($config['servername'], $config['username'], $config['password']);

我无法使用任何其他扩展。

我试过创建 ~/.freetds.conf

[global]
client charset = UTF-8

我试过将参数传递给php:

php -d mssql.charset="UTF-8" index.php

数据仍然不是 UTF-8。

php -i

mssql

MSSQL Support => enabled
Active Persistent Links => 0
Active Links => 0
Library version => FreeTDS

Directive => Local Value => Master Value
mssql.allow_persistent => On => On
mssql.batchsize => 0 => 0
mssql.charset => no value => no value
mssql.compatability_mode => Off => Off
mssql.connect_timeout => 5 => 5
mssql.datetimeconvert => On => On
mssql.max_links => Unlimited => Unlimited
mssql.max_persistent => Unlimited => Unlimited

想法?

4

8 回答 8

31

我有一个类似的问题,并尝试了我可以在网上找到的所有设置 - 徒劳无功。

就我而言,问题在于 FreeTDS 本身的配置。在 Linux 上,该文件是 /etc/freetds/freetds.conf

我不得不将版本更改为 7.0(也许其他数字也可以。我刚试过 7.0)

[global]
    # TDS protocol version
    tds version = 7.0

在此之后,驱动程序似乎接受了字符集的更改。

ini_set('mssql.charset', 'UTF-8');

顺便说一句:更改立即生效,之后无需重新启动任何内容

于 2012-12-14T11:25:34.800 回答
16

MSSQL 和 UTF-8 有时是相当痛苦的。我不得不手动转换它。问题:MSSQL 实际上并不了解和支持 UTF-8。

从数据库值转换为 UTF-8:

mb_detect_encoding($value, mb_detect_order(), true) === 'UTF-8' ? $value : mb_convert_encoding($value, 'UTF-8');

从 UTF-8 转换为数据库值:

mb_convert_encoding($value, 'UCS-2LE', mb_detect_encoding($value, mb_detect_order(), true));

幸运的是,我使用的是 Doctrine,所以我所要做的就是创建一个自定义的 StringType 实现。

于 2012-11-14T11:27:36.543 回答
16

如果您使用 freeTDS,您应该更改以下行/etc/freetds/freetds.conf

[global]
# TDS protocol version
tds version = 4.2

对此:

[global]
# TDS protocol version
tds version = 8.0
;tds version = 4.2

最后添加这一行:

# set charset
client charset = UTF-8

** clinet 字符集在全局 [范围]

在您的查询中,您应该使用 N 个字符。像这样:

$query = "INSERT INTO dbo.SMSOutbox (StationID, Dest, Text) VALUES ";
   $query .= '(';
   $query .= "'" . $this->stationId . "', ";
   $query .= "'" . $this->destination . "', ";
   $query .= "N'" . $this->text . "'";
   $query .= ')';
于 2015-02-26T11:58:39.693 回答
15

您还可以通过在连接到数据库之前在 $connectionInfo 中添加 CharacterSet UTF-8 来解决此问题。

$serverName = "MyServer";
$connectionInfo = array( "Database"=>"AdventureWorks", "CharacterSet" => "UTF-8");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

工作正常不需要额外的编码。

于 2014-06-17T14:07:23.073 回答
2

似乎需要 7.0 或更高版本。iconv() 似乎也很好用,但是很乏味。

$query = $this->db->query($sql);
$result = $query->fetchAll(PDO::FETCH_OBJ);
foreach ($result as $row) {
    foreach (get_object_vars($row) as $key => $value) {
    $row->$key = (mb_detect_encoding($value, mb_detect_order(), true) === 'UTF-8') 
            ? $value : iconv('iso-8859-1', 'utf-8', $value);
    }
    $results[] = $row;
}
于 2014-08-14T18:23:16.853 回答
2

我遇到了这个问题,并通过在连接到 MSSQL Server 之前将此行添加到我的 php 脚本中来解决:

ini_set('mssql.charset', 'UTF-8');
于 2015-07-25T07:21:52.200 回答
0

您应该根据您使用的 SQL Server 版本更改您的 TDS 版本。查看安装指南了解详细信息。

http://www.freetds.org/userguide/choosingtdsprotocol.htm

于 2017-11-02T17:40:07.943 回答
0

我使用与上面相同但Windows 1250,所以:

$query = $this->db->query($sql);
$result = $query->fetchAll(PDO::FETCH_OBJ);
foreach ($result as $row) {
    foreach (get_object_vars($row) as $key => $value) {
    $row->$key = (mb_detect_encoding($value, mb_detect_order(), true) === 'UTF-8') 
            ? $value : iconv('windows-1250', 'utf-8', $value);
    }
    $results[] = $row;
}

然后它起作用了,但我使用波兰语字符

于 2020-01-21T12:12:32.890 回答