使用一个函数将ASCII和UTF-8转换为非特殊字符

5
所以我正在构建一个网站,该网站使用已经设置并由客户用于其所有其他网站相当长一段时间的数据库提要。
他们通过外部程序填充此数据库,我无法改变获取数据的方式。
现在我有以下问题,有时我会得到UTF-8字符串,有时我会得到ASCII字符串(希望我弄清了这些术语,有时它们仍然有点模糊)。
所以我可能会得到这个:ScénicScénic
现在的问题是,我必须将其转换为非特殊字符(因此它将变成Scenic)用于URL。
我不认为有一个将é转换为e的函数(如果有,请告诉我),因此我可能需要创建一个包含所有源和目标的数组,但更大的问题是在不破坏该函数时将é转换为é
或者我应该创建一个包含“一切”的数组
(例如:array('é'=>'e','é'=>'e');等)。
我知道如何将é转换为é,方法是执行utf8_encode(html_entity_decode('é')),但是将é放入同一函数中将返回é
也许我正在错误地处理这个问题,但在那种情况下,我很想知道我应该如何处理它。

2
html_entity_decode("éé",ENT_COMPAT,"UTF-8") 对我来说是正确的 - 它输出 "éé"。也许你只是忘记设置编码了?这应该在 UTF-8 上工作,并且在前 128 个 ASCII 位(纯文本)上也应该工作,因为它们在 UTF-8 中具有相同的值 - 这似乎正是你的情况。 - XzKto
iconv("UTF-8","ASCII//TRANSLIT","ééé") 能解决第二部分吗? - XzKto
html_entity_decode('éeé',ENT_COMPAT,"UTF-8"); 在我的情况下实际上产生了 �eé(使用 DOCTYPE html 和 meta charset UTF-8)。但是在 codepad.org 上,它返回 éeé。如果我对其执行 iconv("UTF-8","ASCII//TRANSLIT",$input);,我会得到一个空字符串。而且 iconv 在 codepad 上不起作用,所以我无法在那里测试它。 - Kokos
我肯定在其他地方做错了什么,如果我在我的网站上运行这个:http://ideone.com/QjoQk,我会得到以下输出:`string(4) "�eé" string(0) "" string(13) "ccc�aaadfgdfg" string(3) "ccc" string(7) "Citro�n" string(5) "Citro"`。 - Kokos
还可以尝试使用 ßæıLJ。它应该变成 ssaeiLJ - MSalters
显示剩余2条评论
1个回答

12

感谢@XzKto以及这篇在PHP.net上的评论,我将我的slug函数改为以下内容:

static function slug($input){

    $string = html_entity_decode($input,ENT_COMPAT,"UTF-8");

    $oldLocale = setlocale(LC_CTYPE, '0');  

    setlocale(LC_CTYPE, 'en_US.UTF-8');
    $string = iconv("UTF-8","ASCII//TRANSLIT",$string);

    setlocale(LC_CTYPE, $oldLocale);

    return strtolower(preg_replace('/[^a-zA-Z0-9]+/','-',$string));

}

我觉得setlocale部分有点不太好,但这个方案可以完美地将特殊字符翻译成它们的“正常”等价物。

输入a áñö ïß éèé返回a-ano-iss-eee


1
之后应该重置区域设置。 - Alex
更新了!感谢您的提示 :) - Kokos
4
应该写成 $oldLocal = setlocale(LC_CTYPE, '0');。只使用一个参数调用 setlocale 会导致错误。如果你想获取当前的区域设置,应该将字符串 '0' 作为第二个参数传入。参考链接:http://php.net/manual/zh/function.setlocale.php - Sandyandi N. dela Cruz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接