【问题标题】:Stuck writing UTF-8 file via PHP's fwrite卡住通过 PHP 的 fwrite 写入 UTF-8 文件
【发布时间】:2016-02-22 06:10:59
【问题描述】:

我不知道我做错了什么。我正在从数据库中获取文件内容。当我回显内容时,一切都显示得很好,当我将其写入文件 (.html) 时,它会中断。我尝试了 iconv 和其他一些解决方案,但我只是不明白我应该为第一个参数输入什么,我尝试了空白,但效果也不是很好。我认为如果回显正确,它会以 UTF-8 形式从数据库中出来。现在卡了一段时间,运气不好。

function file($fileName, $content) {
    if (!file_exists("out/".$fileName)) {
        $file_handle = fopen(DOCROOT . "out/".$fileName, "wb") or die("can't open file");
        fwrite($file_handle, iconv('UTF-8', 'UTF-8', $content));
        fclose($file_handle);
        return TRUE;
    } else {
        return FALSE;
    }
}

html文件的源代码如下。

像这样从数据库中出来:

<h5>Текущая стабильная версия CMS</h5>

像这样进入文件

<h5>Ð¢ÐµÐºÑƒÑ‰Ð°Ñ ÑÑ‚Ð°Ð±Ð¸Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ CMS</h5>

编辑:

原来问题的根源是 Apache 错误地提供文件。添加

AddDefaultCharset utf-8

对我的 .htaccess 文件进行了修复。浪费时间……不过至少我学到了一些东西。

【问题讨论】:

  • 将您的输出 HTML 放在某处。您可能尚未将 UTF-8 标记标头添加到 HTML。
  • @Dean 即使查看源代码也会很重要吗?
  • Ðа форуме чаÑто упоминаеÑ,ÑÑ ÐºÐ¾Ð´Ð¾Ð³ÐµÐ½ÐµÑ€Ð°Ñ,ор。
  • 我敢打赌 Ð¢ÐµÐºÑƒÑ‰Ð°Ñ ÑÑ‚Ð°Ð±Ð¸Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ 是 Текущая стабильная версия 的 UTF-8 被视为 ISO-8859 -1,也是因为字符 Ð 在 ISO-8859-1 中是 0xD0,而 0xD0 是西里尔字母的 2 个 UTF-8 字节中的第一个。这意味着您正在编写 UTF-8,但将其视为 ISO-8859-1(或 ISO-8859-15)。
  • @Martin 您指向我的 Walter Tross 评论。他说是读者。因此,当我通过 cat 输出文件后,我得到了很好的结果,并且认为我的阅读器,即 Apache,有问题。接下来我做的是 google Apache 和 UTF-8 并得到了stackoverflow.com/questions/913869/…
  • 很高兴我能帮上忙。不过,我必须更正我的评论:Unicode 的西里尔字母块中的字符在编码为 UTF-8 时以 0xD0、0xD1、0xD2、0xD3 之一开头(因为它们在 U+0400 到 U+04FF 的范围内)。这 4 个起始字节在 ISO-8859-1 中显示为 Ð、Ñ、Ò 和 Ó(频率递减)。
  • 标签: php utf-8 fwrite


    【解决方案1】:

    编辑:这里的数据库编码似乎不是问题,因此保留这部分答案仅供参考

    我假设它以 UTF-8 格式从数据库中出来

    这很可能是您的问题,您使用什么数据库类型?您是否为数据库、表、连接传输设置了字符编码和排序规则细节。

    如果我冒险猜测,我会说您的表是 MySQL,并且您的数据库/表/列的 MySQL 排序规则都应该是 UTF8_general_ci

    但是,由于某种原因,MySQL UTF8 实际上并不是 UTF8,因为它以 3 位而不是 4 位存储数据,因此无法存储整个 UTF-8 字符集,请参阅UTF-8 all the way through

    因此,您需要遍历 MySQL 上的每个表、列,并将其从 UTF8_ 更改为 UTF8mb4_(注意:因为 MySQL 5.5.3),它是 UTF8_multibyte_4,它涵盖了整个 UTF-8 字符范围。

    此外,如果您对数据字符串进行任何 PHP 工作,请注意您应该使用mb_ PHP 函数进行多字节编码。

    最后,您需要为数据库指定一个连接字符集,不要使用默认字符集,因为它几乎肯定不会是 UTF8mb4,因此您可以获得正确的数据在数据库中,但随后该数据被重新打包为 3bit UTF8,然后在另一端被 PHP 视为 4bit UTF8。

    希望这会有所帮助,如果您的数据库不是 MySQL,请告诉我们它是什么!

    编辑:

    function file($fileName, $content) {
        if (!file_exists("out/".$fileName)) {
            $file_handle = fopen(DOCROOT . "out/".$fileName, "wb") or die("can't open file");
            fwrite($file_handle, iconv('UTF-8', 'UTF-8', $content));
            fclose($file_handle);
            return TRUE;
        } else {
            return FALSE;
        }
    }
    
    • 您的$file_handle 正试图在if 语句中打开一个文件,该语句仅在文件不存在时运行。

    • 你的iconv在这里一文不值,从“utf-8”变成呃,“utf-8”。字符检测非常随意,程序很难正确执行,因此通常建议不要尝试解决 / 猜测它是什么字符编码,你需要知道它是什么并告诉函数它是什么。

    【讨论】:

    • Arg,仍然失败,将表/连接切换为UTF8mb4,重新插入数据以确保以防万一,将str_replace注释掉,取出iconv,将“wb”设为"w" 仍然失败。
    • 你需要检查 PHP 和 MySQL 之间的连接也是 utf8mb4,比如$dbconnection-&gt;set_charset("utf8mb4");
    • 如果这也对您没有帮助,那么我们需要查看代码在屏幕输出上的样子(如果没问题),并将其与文件上的样子进行比较(您已经提出了问题)。此外,如果您已将数据库更改为使用 UTF8mb4,那么理想情况下您需要将代码重新添加到数据库中,以便可以将其保存为 4 位而不是 3 位 UTF8。 @Serhiy
    • 是的,重新插入数据,有 set_charset 的东西,当我回显时,一切都很完美,当我写入文件时,它不是。老实说,我觉得它一定是文件写入部分。我最初是从 CURL 获取数据,但由于它进入数据库并且很好,所以这不可能是罪魁祸首吗? pastebin.com/raw.php?i=EshBmV77
    • 如果您的输出 HTML 文件正常工作,它的字符编码是什么?我认为它是 UTF-8(我只是打勾,因为它不是 :-D)
    【解决方案2】:

    Dean 的评论其实很重要。 HTML 应该在 &lt;head&gt; 内有一个 &lt;meta charset="UTF-8"&gt;

    iconv 调用实际上没有用,如果您正确地以 UTF-8 格式获取内容,则没有必要。

    您应该检查数据库连接的字符集。您的数据库可以使用 UTF-8 编码,但连接可以使用另一个字符集。

    祝你好运!

    【讨论】:

    • 浏览器应该在没有元数据的情况下检测 UTF-8,这不是 必要的 要求。我认为问题出在数据库编码上。
    • 是的,我觉得 Dean 的评论是切线的。该文件很糟糕,当我在文本编辑器中打开它时,不需要浏览器。
    • @Serhiy 我认为这是你 fopen 上的 binary 标记的问题。查看我的答案(在底部)
    • @Martin,谢谢,我正在通读它,一次有点多的内容,通读一遍,感谢您提供这些详细信息。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签