2009-08-24 51 views
20

我想通过php在SQL Server数据库中存储一些数据。PHP + SQL Server - 如何设置连接字符集?

问题是特殊字符没有正确转换。我的应用的字符集是iso-8859-1 ,服务器使用的是windows-1252。

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

运行SQL查询'set char_convert off'也没有帮助。

任何人有任何想法我可以得到这个工作?编辑:

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

+0

mssql.charset仅适用于FreeTDS。此配置参数是否显示在服务器上的phpinfo()中? – VolkerK 2009-08-24 14:12:49

+0

是的,它确实显示出来。 Phpinfo还声明MSSQL Library版本是FreeTDS。 本地值:windows-1252 主值:无值 – Maurice 2009-08-24 14:58:45

回答

19

客户端字符集是必要但不充分:: 然而,在大写的工作

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

我搜索了两天如何插入UTF-8的数据(从网页表格)进入2008年MSSQL通过PHP。我在任何地方都能看到你不能,你需要先转换成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

+0

节省我的一天,非常感谢。 – 2017-11-17 10:42:52

0

你就不能转换你的表到您的应用程序编码?或者在两者中使用utf-8?

虽然我不知道MSSQL是否支持表级别的编码。

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

+0

不幸的是,我不能。因为它不是我的数据库,也不是我的框架。将特殊字符转换为实体也不是一个选项,因为还有一些非网络软件连接到这个数据库。 我习惯使用iconv进行转换,但我会给MB试一试。 – Maurice 2009-08-24 16:52:29

+0

与mb相同的结果。发送数据到数据库似乎有一些自动转换完成。 – Maurice 2009-08-25 11:07:34

2

我已经在类似情况的运气(使用PDO ODBD连接)使用下面的代码打印输出前向编码转换:

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

我不得不手动设置源编码,因为它错误地被mb_detect_encoding()报告为“ISO-8859-1”。

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

4

我建议看以下几点:

  1. 确保您要存储的信息的列是的ncharnvarchar的为char和nvarchar不支持UCS-2(SQLServer的不BTW UTF-8格式存储)
  2. 如果你与mssql library/extension为PHP连接,运行:ini_set('mssql.charset', 'utf-8');因为有一个字符集参数无功能(连接,查询等)
  3. 确保您的浏览器的字符集也被设置为UTF-8
+0

另外,如果您使用的是Zend_Db,那么在初始化连接时不要忘记charset参数:... params.charset =“utf8” – 2012-02-13 12:20:36

5

我有同样的问题,ini_set('mssql.charset', 'utf-8')没有为我工作。

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

如果您使用的是TDS协议版本7或更高版本,则线路上的所有通信都将转换为UCS2。除非列是nvarchar或ntext,否则服务器将从UCS2转换为设置为表或列的排序规则。您可以 UTF-8到正规的varchar或文本,你就必须使用TDS协议版本低于7,如6.0或4.2。用这种方法唯一的缺点是你不能查询任何数据类型为nvarchar,ntext或SYS *表(我想你也不会做任何CAST()荷兰国际集团) - 作为服务器拒绝发送任何有可能会被转换为UTF-8使用协议版本低于7.

这是不可能的,以避免使用TDS协议版本7或更高(大约相当于2005或更新MSSQL)时转换的字符集的任何客户端。

+3

在Linux系统上,您可以在'freetds.conf'中通过在参数分组'[global]'下指定以下选项来设置此TDS协议版本 - 'tds version = 8.0' 'client charset = UTF-8'请参阅:https://gist.github.com/johnkary/6643856 – 2013-09-20 21:03:04

2

对我来说,编辑这个文件:
/etc/freetds/freetds.conf
...和改变/设置 'TDS版本' 参数 '7.0' 的帮助。编辑您的freetds.conf并尝试更改您的服务器配置(或全局)的此参数。

它甚至没有工作的Apache重新启动。

1

如果ini_set('mssql.charset', 'UTF-8');不帮助你,你没有root访问权限修改系统范围freetds.conf文件,这里是你可以做什么:

设置/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 

让freetds的通过ENV变量使用本地freetds.conf文件从PHP脚本未经授权的用户:

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

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

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')));