PHP + SQL Server - 如何设置charset进行连接?

时间:2009-08-24 13:29:27

标签: php sql-server database character-encoding

我正在尝试通过php将一些数据存储在SQL Server数据库中。

问题是特殊字符未正确转换。我的应用程序的字符集是iso-8859-1 而服务器使用的是windows-1252。

在插入之前手动转换数据没有帮助,似乎有一些 正在进行转换。

运行SQL查询'set char_convert off'也无济于事。

任何人都知道如何才能让它发挥作用?

编辑:我试过ini_set('mssql.charset','windows-1252');同样,但也没有结果。

13 个答案:

答案 0 :(得分:23)

客户端字符集是必要的,但还不够:

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

我搜索了两天如何通过PHP将UTF-8数据(从Web表单)插入到MSSQL 2008中。我到处读到你不能,你需要先转换为UCS2(就像cypher的解决方案推荐的那样)。 在Windows上,SQLSRV被认为是一个很好的解决方案,我无法尝试,因为我在Mac OSX上进行开发。

但是,FreeTDS手册(PHP mssql在OSX上使用的内容)说在开头引号之前添加一个字母“N”:

mssql_query("INSERT INTO table (nvarcharField) VALUES (N'űáúőűá球最大的采购批发平台')", +xon);

根据此讨论,N字符告诉服务器转换为Unicode。 https://softwareengineering.stackexchange.com/questions/155859/why-do-we-need-to-put-n-before-strings-in-microsoft-sql-server

答案 1 :(得分:5)

我建议看看以下几点:

  1. 确保您存储信息的列为 nchar nvarchar ,因为char和nvarchar不支持 UCS-2 (SQLServer不以UTF-8格式存储btw)
  2. 如果您正在使用mssql library/extension连接PHP,请运行:ini_set('mssql.charset', 'utf-8');,因为没有带charset参数的函数( connect,query 等)
  3. 确保您的浏览器字符集也设置为 UTF-8

答案 2 :(得分:5)

我遇到了同样的问题而ini_set('mssql.charset', 'utf-8')对我不起作用。 但是,它以大写形式工作:

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

答案 3 :(得分:4)

如果您使用的是TDS协议版本7或更高版本,则通过线路的所有通信都将转换为UCS2。除非列是nvarchar或ntext,否则服务器将从UCS2转换为表或列排序规则设置的任何内容。您可以将UTF-8存储到常规varchar或文本中,您只需使用低于7的TDS协议版本,如6.0或4.2。这种方法的唯一缺点是你不能查询任何nvarchar,ntext或sys。*表(我认为你也不能做任何CAST()ing) - 因为服务器拒绝发送任何可能转换为UTF-8使用协议版本低于7的任何客户端。

使用TDS协议版本7或更高版本(大致相当于MSSQL 2005或更高版本)时,无法避免转换字符集。

答案 4 :(得分:4)

如果ini_set('mssql.charset', 'UTF-8');没有帮助,并且您没有root权限来修改系统范围的freetds.conf文件,请执行以下操作:

1。设置/your/local/freetds.conf文件:

[sqlservername]
    host=192.168.0.56
    port=1433
    tds version=7.0
    client charset=UTF-8

2. 确保您的连接DSN使用的是服务器名,而不是IP:

'dsn' => 'dblib:host=sqlservername;dbname=yourdb

3. 使FreeTDS使用本地freetds.conf文件作为非虚拟用户从php脚本通过env变量:

putenv('FREETDSCONF=/your/local/freetds.conf');

答案 5 :(得分:2)

我在类似的情况下运行(使用PDO ODBD连接),使用以下代码在打印输出之前转换编码:

$data = mb_convert_encoding($data, 'ISO-8859-1', 'windows-1252');

我不得不手动设置源编码,因为mb_detect_encoding()错误地将其报告为'ISO-8859-1'。

我的数据也被另一个应用程序存储在数据库中,所以我可能处于一种独特的情况,虽然我希望它有所帮助!

答案 6 :(得分:2)

编辑此文件:
/etc/freetds/freetds.conf
...以及更改/设置版本'参数为' 7.0'帮助。编辑freetds.conf并尝试为服务器配置(或全局)更改此参数
即使没有重启apache也能正常工作。

答案 7 :(得分:1)

在我的情况下,在我将“ CharacterSet”参数添加到sqlsrv_connect()连接的选项中后,它起作用了。

$connectionInfo = array( 
        "Database"=>$DBNAME,
        "ConnectionPooling"=>0,
        "CharacterSet"=>"UTF-8"
);
$LAST_CONNECTION = sqlsrv_connect($DBSERVER, $connectionInfo);

在此处查看文档: https://docs.microsoft.com/en-us/sql/connect/php/connection-options?view=sql-server-2017

答案 8 :(得分:0)

您不能只将表格转换为应用程序编码吗?或者在两者中使用utf-8?

我不知道MSSQL是否支持表级编码。

此外,如果上述操作失败,请尝试MB(多字节)字符串函数。

答案 9 :(得分:0)

您应该在连接之前使用 ini_set('mssql.charset','windows-1252')设置charset。如果你在 mssql_connect 之后使用它它没有效果。

答案 10 :(得分:0)

在我的案例中添加ini_set('mssql.charset', 'UTF-8');并没有帮助我。我必须在列上指定UTF-8字符集:

$age = 30;  
$name = utf8_encode("Joe");    

$select = sqlsrv_query($conn, "SELECT * FROM Users WHERE Age = ? AND Name = ?",
    array(array($age), array($name, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8')));

答案 11 :(得分:0)

我没有注意到有人提到从MSSQL数据库转换结果的另一种方法。好用的旧iconv()函数:

iconv (string $in_charset, string $out_charset, string $str): string;

就我而言,除获得结果外,其他所有方法都无法提供有意义的转换。当然,这是在解析查询结果的循环内完成的-从CP1251到UTF-8:

foreach ($records as $row=>$col) {
    $array[$row]['StatusName'] = iconv ('CP1251', 'UTF-8' , $records[$row]['StatusName']);
}

丑陋,但是可行。

答案 12 :(得分:-4)

您可以使用mysql_set_charset函数: http://it2.php.net/manual/en/function.mysql-set-charset.php