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

使用PHP FreeTDS扩展从MSSQL服务器获取具有UTF-8字符集的数据,php,sql-server,utf-8,freetds,Php,Sql Server,Utf 8,Freetds,我似乎无法使用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 我已尝

我似乎无法使用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

想法?

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实现。

我遇到了类似的问题,并尝试了在web上找到的所有设置,但都没有成功

在我的例子中,问题是FreeTDS本身的配置。在Linux上,文件是/etc/freetds/freetds.conf

[global]
client charset = UTF-8
我不得不把版本改成7.0(也许其他数字也可以,我只是试了7.0)

在这之后,司机似乎接受了字符集的变化

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

顺便说一句:更改立即生效,以后无需重新启动任何操作

您也可以通过在连接到DB之前在$connectionInfo中添加字符集UTF-8来解决此问题

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

工作正常,无需额外编码。

似乎需要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;
}

如果使用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 .= ')';

我遇到了这个问题,通过在连接到MSSQL服务器之前将这一行添加到我的php脚本中解决了这个问题:

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

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


我使用了与上述相同的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;
}

然后它成功了,但我使用了波兰字符,感谢@user1903844。这个解决方案帮助我使用Ubuntu+MS SQL+PHPVersion>=7.0来设置配置选项
client charset=UTF-8
,这可能就是为什么OP Marius Grigaitis使用它的解决方案不起作用的原因。参见
freetds.conf
示例的要点:是的,最后是一个有效的答案!未注释的行,将值更改为7.0,它工作正常。不需要
ini\u集合
part。太好了。工作可能FreeTDS 7.0版支持客户端格式(UTF-8、ISO-8859-1或其他格式)和UCS2-LE(MSSQL字符集)之间的自动转换,因此这对程序员来说是透明的。这在Xenial Xerus、PHP7、MSSQL 2008、FreeTDS v0.91MS SqlServer使用UCS2-LE编码,而不是CP1252上对我来说仍然不起作用。也不是ISO8859-1(CP1252的子集)。也不是UTF-16(在UCS2之后)或“Unicode”(Win上的WideChar/UTF-16)。你救了我的命。我将回答我关于如何使用CodeIgnite的问题,我不敢相信这不是公认的答案,它工作得很好,而且很容易做到。如果我能给你的不仅仅是+1,我会非常棒的,谢谢你的回答,我到处寻找解决方案,这是完美的。我完全同意;这应该是公认的答案!这个答案对于Microsoft的SQLSRV库是正确的,但对于作者特别询问的FreeTDS库则不正确。这为我解决了这个问题,再加上@louis-huppenbauer的转换。这很有效!我这样说是因为有时候人们忽略了答案而没有太多的选票。