PHP:Unicode强调char和变音符号

时间:2012-11-27 14:10:59

标签: php unicode encoding tinymce

在我们的网站上,一些Mac用户在将PDF文件中的文本复制粘贴到TextArea(由TinyMCE处理)时会遇到麻烦。所有突出显示的字符都已损坏,例如e?éi?î等。我无法使用Windows计算机重现此问题。

当我在一个文件上写入TextArea的内容时(在将其插入数据库之前),我发现初始在视觉上与传统é不同(在Vim上,见下文)。

Visual example of the problem

确实:

// the corrupted é - first line of the screenshot
echo bin2hex($char); // display 65cc81

// traditionnal é
echo bin2hex('é');   // display c3a9

经过大量搜索,我在这里: 似乎Mac OS将Unicode强调的字符复制为两个字符的组合:在我们的示例中, e + ́ 。到目前为止,我没有找到任何解决方案来将损坏的é替换为真实的,以避免数据库中出现e?

我有点绝望。

3 个答案:

答案 0 :(得分:8)

normalizing the representation to one form or the other的过程被称为,正常化。在PHP中有Normalizer class,通过它发送所有输入是一个好主意:

$input = Normalizer::normalize($input);

你可能想要标准化形成C,Canonical Decomposition,然后是Canonical Composition。

如果您的系统上没有该课程,那就是Patchwork UTF-8 library

答案 1 :(得分:4)

这只是@deceze已经回答的补充。 Unicode中有多种方法可以指定相同的(在等价意义上)字符。

这里有一个常见的例子:

65cc81

这是Utf-8编码中的两个Unicode代码点。 65 e LATIN SMALL LETTER E (U + 0065)和cc81 ́ 组合ACUTE ACCENT ( U + 0301)(它不能由您的浏览器单独显示,因此我使用了HTML实体)。

在Unicode中,这称为组合序列。但是,出于某种原因,您的数据库不支持它。可能是因为列的编码不是UTF-8或数据库连接有麻烦。

它在规范上等同于

c3a9

这是Utf-8编码中的单个Unicode代码点。 c3a9é 拉丁文小写字母E,有急促(U + 00E9)。看起来您的数据库没有问题可以处理它,可能是因为它已成功通过数据库连接重新编码为Latin-1 / ISO-8859-1。

因此,我想到了两种处理数据的方法。这是数据重新编码中的问题或存储数据的问题。

只要您对组合的unicode代码点序列的分解感兴趣,就应该使用Deceze's answer中列出的规范化器。

您也可以允许将UTF-8存储到数据库中,然后您也不应该遇到问题。

此外,您可能应该正常化,以便排序和比较数据库或程序中的数据更好。正如您所看到的,二进制序列不同,这可能会导致在二进制级别上比较的所有内容出现问题。

当然,你节省了一些流量:)

答案 2 :(得分:0)

有一个tinymce配置参数,允许您在插入编辑器之前定义一个处理粘贴内容的函数:paste_preprocessing

使用该功能,您可以使用所需的格式替换特殊字符

tinyMCE.init({
        ...
        paste_preprocess : function(pl, o) {
            // Content string containing the HTML from the clipboard
            o.content = o.content.replace(/\u2020/, 'x'); // example
        },
        paste_postprocess : function(pl, o) {
            ...
        },
        ...
});