【问题标题】:Encoding MySQL text fields into UTF-8 text files - problems with special characters将 MySQL 文本字段编码为 UTF-8 文本文件 - 特殊字符的问题
【发布时间】:2010-04-20 13:27:17
【问题描述】:

我正在编写一个 php 脚本来将 MySQL 数据库行导出到一个 .txt 文件中,该文件格式为 Adob​​e InDesign 的内部标记。

导出工作,但是当我遇到像 é 或变音符号这样的特殊字符时,我会得到奇怪的符号(例如 Chloë Hanslip 而不是 Chloë Hanslip)。我需要一个更好的方法,而不是对每个可能的怪异字符进行搜索和替换。

我已经检查过,当文本进入数据库时​​,它已正确保存 - 在数据库中我看到了特殊字符。我的导出代码基本上会运行一些正则表达式来放入 InDesign 代码标签,而我留下了奇怪的符号。如果我只是将文本输出到浏览器(而不是提示下载文本文件),它会正确显示。当我保存文件时,我使用以下代码:

header("Content-disposition: attachment; filename=test.txt");

header("Content-Type: text/plain; charset=utf-8");

我尝试了utf8_encode()iconv() 的各种组合,但均无济于事。有人可以在这里指出我正确的方向吗?

【问题讨论】:

  • 您是否检查过您的 Adob​​e InDesign 是否将此数据视为 utf-8?

标签: php mysql text encoding utf-8


【解决方案1】:

InDesign 将无法使用标头中指定的任何编码。 (它甚至不会看到它,因为当您在 Windows 中保存到光盘时它不会保留。)相反,您必须在文件开头明确告诉它自己的特殊标记中的编码,例如:

<ANSI-WIN>

不幸的是,它是does not use standard encoding names,并且没有任何 InDesign 理解的标记对应于 UTF-8 编码。您可以使用的唯一允许您包含任何您喜欢的字符的编码标签是:

<UNICODE-WIN>

对应于 UTF-16(带有 BOM 的小端序),带有 Windows CRLF 行尾。 (唯一的其他行尾选项是 MAC,您根本不需要它,因为它是老式的 pre-OSX Mac,行尾字符是 CR。)

所以,给定一个包含 UTF-8 字节序列的 UTF-8 字符串 $s,您已经从数据库中提取了一个普通的(Unix-Linux-OSX-web-style)LF 换行符,您可以这样写:

$s= "<UNICODE-WIN>\r\n".str_replace("\n", "\r\n", $s);
echo iconv('UTF-8', 'UTF-16', $s);

(确保在之前或之后不输出 任何 个空格,因为它会破坏 UTF-16 编码。

【讨论】:

  • 感谢您的回答。我生成的 InDesign 文件都以 开头 - 我不知道其他选项,谢谢。但是,我的问题发生在 之前 代码到达这一点 - 如果我在记事本中打开文本文件,它会显示奇怪的字符 - 理想情况下,它们在导出之前应该是正确的,如果这有意义的话。我尝试了iconv() 代码,但它报告了一个无效字符错误——可能是变音符号?!
  • 你不能真正信任记事本:它也不是编码,它是猜测。如果您在记事本中看到“Chloë”,很可能您已经以 UTF-8 正确输出了它,但记事本猜测它是代码页 1252(系统默认代码页或西方机器上的“ANSI”)。获取更好的测试编辑器(例如 Notepad++),或者如果您想绝对确定您拥有什么,请在十六进制编辑器中查看它(例如 XVI32),它会显示每个该死的字节。
  • 如果 iconv('UTF-8', 'UTF-16', $s) 说无效字符,那么你有 something 那里不是 UTF-8 序列。但是,从“Chloë”来看,我确实认为您很可能获得了 UTF-8。也许您正在将数据库字符串添加到您在 PHP 中创建的具有非 UTF-8 序列的字符串中,因为例如。您在 PHP 源代码中编写了 "ä" 并从记事本中将其保存为 ANSI 而不是 UTF-8-no-BOM。 (再次:更好的文本编辑器。)如果您无法追踪它,请在使用前尝试使用有效的 UTF-8 正则表达式清理 UTF-8 字符串。或者我认为mb_convert_encoding 可能会忽略这些错误?
  • 感觉就像我现在到了某个地方 - 你是对的,我正在向它添加其他字符串。基本上,我有一个“模板”文件,其中包含我的 InDesign 代码的骨架,并插入了相关的数据库字段。我首先尝试使用 mb_convert_encoding,然后转换为 UTF-16 - 这导致我的文本编辑器生成了一个文件仅显示为正方形,但 Notepad++(好记录!)显示它没问题。它也有变音符号,万岁!不过,让 InDesign 识别它时遇到问题,所以现在开始玩吧。
  • 啊,是的,我认为 InDesign 默认会导出为 ANSI-WIN,因此如果您使用基于该模板文件的模板文件,您将拥有非 UTF-8 序列。不幸的是,您不能在此处使用 PHP 本身来模板化 UTF-16 文件,因为 PHP 仅与 ASCII 超集编码兼容。 (一般来说,作为不是 ASCII 超集的编码,UTF-16 是文本文件的一个糟糕且不寻常的选择,但似乎这是 InDesign 一致处理非 ASCII 字符的唯一可能性。)
【解决方案2】:

在导出前你可以使用SET NAMES命令改变传输的编码例如:

SET NAMES utf8;

您可以在您的 mysql 备份软件中进行配置。

【讨论】:

    【解决方案3】:

    只需在数据库连接方法mysql_set_charset('utf8');之后调用PHP

    【讨论】:

      【解决方案4】:

      看起来 ISO-8859-1 字符串以 UTF-8 格式发送...

      确保您的 字段 是 UTF-8 格式,并以 UTF-8 格式连接到数据库。如果您的表和字段是 UTF-8 并且您没有指定 MySQL 字符集,MySQL 将即时将数据转换为 ISO-8859-1 (latin1) - 这是我使用过的所有主机的默认配置远...

      这是我用来执行此操作的方式(向后兼容 PHP 5.2.2 及更低版本):

      $conn = mysql_connect('localhost', 'user', 'pass');
      mysql_select_db('dbname');
      if (mysql_errno())
      {
          //Handle database connection error here
      }
      
      if (function_exists('mysql_set_charset'))
          mysql_set_charset('utf8', $conn); //PHP 5.2.3+ only
      else
      {
          if (mysql_query("SET character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'", $conn) === false)
          {
              //Unable to set database charset! Handle error here...
          }
      }
      

      【讨论】:

      • 我试过了,但无济于事:(我确保数据库和字段设置为 UTF-8,并且我也以 UTF-8 连接到它。这让我很难过。
      【解决方案5】:

      然后转换为 UTF-16 - 这导致我的文本编辑器仅显示为正方形的文件,

      iconv 不能添加必须放在 Unicode 文件开头的 BOM 字节 \xff\xfe。

      试试这个: $out = "\xff\xfe" 。 iconv('UTF-8','UTF-16LE',$out);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-03
        • 2014-07-26
        • 2011-10-27
        • 1970-01-01
        • 2011-05-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多