PHP读取Microsoft SQL Server西里尔文显示异常求助
PHP读取SQL Server西里尔文乱码问题
问题现象
使用PHP从Microsoft SQL Server读取并显示西里尔文数据时,仅能正常展示非西里尔文内容,西里尔文无法正常显示。
已尝试的解决措施
- 将表中字段类型设置为
nchar、varchar、text、char - 在HTML代码中添加UTF-8标签
- 使用PHP搭配ODBC驱动连接SQL Server
- 尝试多种排序规则:
Cyrillic_General_100_CI_AI_SC_UTF8、带UTF-8的西里尔文通用规则、搭配西里尔文通用规则的Windows代码页1251
相关代码
<html> <style> table { width: 20em; border-collapse: collapse; } th { border-bottom: 2px solid #000; padding: 0.5em 0 0.1em 0; font-size: 1.2em; } td { border-bottom: 2px solid #ccc; padding: 0.5em 0 0.1em 0; } th:nth-child(n + 2), td:nth-child(n + 2) { text-align: center; } [data-has-link="no"] { background-color: #F77; } [data-has-link="yes"] { background-color: #7F7; } #score, #name { width: 50%; } </style> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="jo.js"></script> <title>AV.31.U</title> </head> <body> <table style="width: 100%; height:50%" border="1" cellpadding="3"> <caption>AV.31.U</caption> <thead> <tr> <td><div id="current_date"></p> <script> $(function() { var $table = $('table'); $table.find('#current_date').text(getCurrentDate()); colorRows($table); // Color the rows! }); function getCurrentDate () { return new Date().toLocaleDateString('en-GB', { year: 'numeric', month: 'numeric', day: 'numeric' }); } function colorRows($table) { var hasLink; $table.find('tbody > tr').each(function(rowIndex) { const $row = $(this); $row.find('td').each(function(colIndex) { const $cell = $(this).removeAttr('data-has-link'); const cellValue = $cell.text().trim(); if (isFinite(cellValue)) { // Color cell based on individual data const hasLink = cellHasLink(parseInt(cellValue, 10)); if (hasLink !== 'maybe') { $cell.attr('data-has-link', hasLink); } } }); // Color row based on 7th column var i = parseInt($row.find('td:nth-child(7)').text(), 10); $row.attr('data-has-link', cellHasLink(i)); }); } function cellHasLink(value) { switch (value) { case 0 : return 'no'; case 1 : return 'yes'; default : return 'maybe'; } } </script></td> <td colspan="6">Home</td> <td> </td> </tr> <tr> <th>Наименование</th> <th>Описание</th> <th>Версия</th> <th>Верс. опис.</th> <th>Модел</th> <th>Видео</th> <th>Видео отвори</th> <th>Снимк.</th> <th>Снимк. отвори</th> <th>Специф.</th> <th>Специф. отвори</th> </tr> </thead> <tbody> <tr> <?php $username = 'censored'; $password = 'censored'; $servername = 'censored'; $database = 'SQL_KASI'; ini_set('display_errors', '1'); error_reporting(E_ALL); $db = odbc_connect("Driver={SQL Server};Server=$servername;Database=$database;", $username, $password) or die ("could not connect<br />"); $stmt = "Select * from machine_vertical"; $result = odbc_exec($db, $stmt); if ($result == FALSE) die ("could not execute statement $stmt<br />"); while (odbc_fetch_row($result)) // while there are rows { print "<tr>\n"; print " <td>" . odbc_result($result, "mach_name") . "\n"; print " <td>" . odbc_result($result, "mach_descr") . "\n"; print " <td>" . odbc_result($result, "mach_version") . "\n"; print " <td>" . odbc_result($result, "mach_version_descr") . "\n"; print " <td>" . odbc_result($result, "mach_model") . "\n"; print " <td>" . odbc_result($result, 'mach_video_yn') . "\n"; print " <td>" . odbc_result($result, "mach_video_open") . "\n"; print " <td>" . odbc_result($result, "mach_pic_yn") . "\n"; print " <td>" . odbc_result($result, 'mach_pic_open') . "\n"; print " <td>" . odbc_result($result, "mach_spec_yn") . "\n"; print " <td>" . odbc_result($result, "mach_spec_open") . "\n"; print "</tr>\n"; } odbc_free_result($result); odbc_close($db); ?> </tr> </tbody> </table> </body> </html>
解决方案
1. 修正数据库字段类型
必须使用Unicode类型字段存储西里尔文,即nvarchar、nvarchar(max)(替代旧版ntext),varchar、char这类非Unicode类型会丢失西里尔文编码信息,导致读取后乱码。
2. 更新ODBC连接配置
使用新版ODBC驱动并指定UTF-8字符集,修改连接字符串:
$db = odbc_connect("Driver={ODBC Driver 17 for SQL Server};Server=$servername;Database=$database;CharSet=UTF-8;", $username, $password) or die ("could not connect<br />");
旧版{SQL Server}驱动对Unicode支持有限,推荐使用ODBC Driver 17及以上版本。
3. 完善页面编码设置
- 在PHP代码最顶部添加强制输出UTF-8的代码:
header('Content-Type: text/html; charset=utf-8');
- 在HTML的
<head>中补充编码meta标签:
<meta charset="UTF-8">
4. 统一排序规则
确保数据库表的排序规则与连接字符集匹配,推荐使用Cyrillic_General_100_CI_AI_SC_UTF8,保证存储和读取时编码一致性。
5. 配置PHP内部编码
在PHP代码中添加以下设置,确保字符串处理使用UTF-8:
mb_internal_encoding('UTF-8'); mb_http_output('UTF-8');
内容的提问来源于stack exchange,提问作者UnixSan
相关产品推荐
相关产品推荐

