使用PHP FreeTDS扩展从MSSQL服务器获取UTF-8字符集的数据

时间:2012-11-14 11:19:25

标签: php sql-server utf-8 freetds

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

连接:

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

想法?

8 个答案:

答案 0 :(得分:30)

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

在我的情况下,问题是FreeTDS本身的配置。在Linux上,文件是/etc/freetds/freetds.conf

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

[global]
    # TDS protocol version
    tds version = 7.0

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

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

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

答案 1 :(得分: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实现。

答案 2 :(得分:14)

如果您使用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 charset位于全局[范围]

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

$query = "INSERT INTO dbo.SMSOutbox (StationID, Dest, Text) VALUES ";
   $query .= '(';
   $query .= "'" . $this->stationId . "', ";
   $query .= "'" . $this->destination . "', ";
   $query .= "N'" . $this->text . "'";
   $query .= ')';

答案 3 :(得分:13)

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

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

工作正常无需额外编码。

答案 4 :(得分:2)

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

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

答案 5 :(得分:1)

看起来版本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;
}

答案 6 :(得分:0)

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

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

答案 7 :(得分: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;
}

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