PHP:修复数据库内容的编码问题 - 从字符中删除重音符号

时间:2010-08-07 18:56:41

标签: php encoding diacritics

我正在尝试制作字符串的URL安全版本。

在我的数据库中,我有一个值medúlla - 我希望将其转换为medulla

我发现有很多函数可以执行此操作,但是当我从数据库中检索值时,它会以medúlla的形式返回。

我试过了:

  • 设置为utf_8编码
  • 设置为utf_8编码
  • 整个数据库设置为utf_8编码
  • 在查询之前在数据库上运行`SET NAMES utf8`

当我将值回显到屏幕上时,它会按照我想要的那样显示,但转换功能看不到ú字符(即使简单的str_replace()也不起作用)。

有人知道如何强制系统将其识别为UTF-8并允许我运行转换吗?

谢谢, 马特

2 个答案:

答案 0 :(得分:2)

要将UTF-8字符串转换为URL安全字符串,您应该使用:

$str = iconv('UTF-8', 'ASCII//IGNORE//TRANSLIT', $strt);

IGNORE部分告诉iconv()在面对无法管理的字符时不要引发异常,并且TRANSLIT部分将UTF-8字符转换为其最近的ASCII等效字符('ú'转换为'u'等等。

下一步是将preg_replace()空格转换为下划线,并用preg_replace()urlencode()替换或删除unsafe within an URL的任何字符。

至于数据库的东西,你真的应该在插入UTF-8内容之前完成所有这些设置。将charset更改为现有表有点像在Windows中更改文件扩展名 - 它不会将JPEG转换为GIF。但不要担心并记住数据库将逐字节地返回您存储在其中的内容,无论已声明哪个charset。只需保留INSERTing时使用的设置,并将返回的字符串视为UTF-8。

答案 1 :(得分:1)

  

我正在尝试制作字符串的URL安全版本。

虽然在URL中使用仅ASCII的'slugs'是常见的,但实际上可以使用包含非ASCII字符的Web地址。例如:

http://en.wikipedia.org/wiki/Medúlla

这是一个有效的IRI。要包含在 U RI中,您应该使用UTF-8和%编码:

http://en.wikipedia.org/wiki/Med%C3%BAlla

无论哪种方式,大多数浏览器(除了有时不是IE)都会在地址栏中显示IRI版本。像维基百科这样的网站使用它来获得漂亮的地址。

  

转换功能没有看到ú字符

什么转换功能? rawurlencode()%C3%BA ú正确地为urlencode()吐出htmlentities(),如果您认为是这样的话,则可以使用UTF-8编码。这是在URL的路径组件中包含文本的正确方法。 ($charset也提供相同的结果,但它只应用于查询组件。)

如果您的意思是htmlspecialchars() ... ,请使用此功能。它将所有非ASCII字符转换为HTML字符引用,这会使您的输出不必要地变大,并且意味着它必须知道您传入的字符串的编码是什么。除非你给它一个UTF-8 $charset参数,它将使用ISO-8859-1,因此搞砸了所有非ASCII字符。

除非您专门创作一个破坏非ASCII字符的环境,否则最好使用<。这会产生较小的输出,如果您忘记包含&参数,则无关紧要(*),因为所有更改都是<str_replace()等几个字符。< / p>

(实际上,对于某些东亚多字节字符集可能很重要,其中str_replace(..., 'ú', ...)可能是多字节序列的一部分,因此不应该被转义。但一般来说,您希望避免这些遗留编码,如UTF-8不那么可怕。)

  

(即使是简单的'\xc3\xba'也不起作用。)

如果您在PHP源代码中编写了SET NAMES utf8,则必须确保使用与处理相同的编码保存源代码,否则它将无法匹配。

不幸的是,大多数Windows文本编辑器仍然保存在(误导性命名的)“ANSI”代码页中,该代码页是特定于语言环境的,而不是仅使用UTF-8。但应该可以将文件保存为UTF-8,然后替换应该工作。或者,写mysql_set_charset()以避免问题。

  

在查询之前在数据库上运行{{1}}

优先使用{{1}}。