在我们的网站上,一些Mac用户在将PDF文件中的文本复制粘贴到TextArea(由TinyMCE处理)时会遇到麻烦。所有突出显示的字符都已损坏,例如e?
为é
,i?
为î
等。我无法使用Windows计算机重现此问题。
当我在一个文件上写入TextArea的内容时(在将其插入数据库之前),我发现初始é
在视觉上与传统é
不同(在Vim上,见下文)。
确实:
// the corrupted é - first line of the screenshot
echo bin2hex($char); // display 65cc81
// traditionnal é
echo bin2hex('é'); // display c3a9
经过大量搜索,我在这里:
似乎Mac OS将Unicode强调的字符复制为两个字符的组合:在我们的示例中, e + ́
。到目前为止,我没有找到任何解决方案来将损坏的é
替换为真实的,以避免数据库中出现e?
。
我有点绝望。
答案 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) {
...
},
...
});