You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>&nbsp;</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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:35:23