【问题标题】:How to handle character encoding in PHP - Codeigniter?如何处理 PHP 中的字符编码 - Codeigniter?
【发布时间】:2011-08-22 18:38:09
【问题描述】:

将用户输入转换为 UTF-8 的最佳方法是什么?

我有一个简单的表单,用户将在其中传递 HTML,HTML 可以是任何语言,也可以是任何字符编码格式。

我的问题是:

  • 是否可以将所有内容都表示为 UTF-8?

  • 我可以使用什么来有效地将任何字符编码转换为 UTF-8,以便我可以使用 PHP 字符串函数对其进行解析并将其保存到我的数据库中,然后使用 htmlentities 回显?

我正在努力研究如何最好地实施这一点 - 建议和链接表示赞赏。

我正在使用 Codeigniter 及其 input class 来检索帖子数据。

我应该提出几点:

  • 我需要将 HTML 特殊字符转换为它们各自的实体
  • 接受编码并以相同的编码返回它可能是个好主意。但是,我的网络应用正在使用:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

这可能会对事情产生不利影响。

【问题讨论】:

    标签: php codeigniter character-encoding


    【解决方案1】:

    在您的<form> 标签中指定accept-charset 以告诉浏览器提交以UTF-8 编码的用户输入数据:

    <form action="foo" accept-charset="UTF-8">...</form>
    

    请参阅此处以获取有关 HOW TO Use UTF-8 Throughout Your Web Stack 的完整指南。

    【讨论】:

    • 如果用户从他们的编辑器中粘贴windows-1252 或某种iso 编码的HTML 会发生什么?浏览器转换它会不会有问题?谢谢你的链接,看起来超级有用/彻底。
    • 浏览器应该自动发送带有正确字符编码的信息...
    • 根据:w3schools.com/tags/att_form_accept_charset.asp,这可能在 IE 中不起作用 - 您是否遇到过任何 IE 问题?
    • @Abs:该属性仅供参考。从技术上讲,它不会阻止将任何类型的数据发送到您的 PHP 脚本。
    • @hakre 从技术上讲是正确的,但你只是 sh*t-outta-luck。 :) 除了指定您的期望之外,您真的无能为力,客户将需要遵守,否则所有赌注都将失败。
    【解决方案2】:

    是否可以将所有内容都表示为 UTF-8?

    是的,UTF-8 是一种 Unicode 编码,因此您可以使用 Unicode 中定义的任何字符。这是迄今为止你用电脑能做的最好的事情。

    我可以使用什么来有效地将任何字符编码转换为 UTF-8

    iconv 让您几乎可以将任何编码转换为任何其他编码。 但是,你必须知道你正在处理什么编码。你不能说iconv,不管它是什么,让它变成UTF-8!”。不幸的是,它不是这样工作的。你只能说iconv,我在BIG5中有这个字符串,请把它转换成UTF-8。”

    如果您只处理 UTF-8 格式的表单数据,您可能永远不需要转换任何东西。

    这样我就可以用 PHP 字符串函数解析它了

    “PHP 字符串函数”作用于字节。他们不关心字符或编码。根据您想要做什么,在 UTF-8 文本上使用简单的 PHP 字符串函数会给您带来不好的结果。使用MB extension 中的编码感知字符串函数进行任何多字节编码字符串操作。

    保存到我的数据库

    只需确保您的数据库以 UTF-8 存储文本,并且您已将数据库连接设置为 UTF-8(即数据库知道您正在向其发送 UTF-8 数据)。您应该可以在 CodeIgniter 数据库连接设置中指定。

    随后使用 htmlentities 回显?

    只需echo htmlentities($text),您无需再做任何事情。

    但是,我的网络应用正在使用:&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;

    这可能会对事情产生不利影响。

    一点也不。它只是向浏览器发出信号,表明您的页面是用 UTF-8 编码的。现在您只需要确保情况确实如此(无论如何您都在尝试这样做)。它还暗示浏览器应该将 UTF-8 发送到服务器。您可以使用表单上的accept-charset 属性来明确说明。

    我可以推荐What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text,这可能会帮助您了解更多。

    【讨论】:

    • @hakre 我想听听您对数据库中 UTF-8 的反对意见。你喜欢什么?
    • +1:做得好,一些 PHP 函数(在 mb 旁边)有不同的编码支持。并避免在不需要时在 MySQL 数据库中使用 UTF-8。但好吧,推迟细节:)。
    • MySQL:有两点:存储要求和字符支持。 MySQL 对 UTF-8 使用每个字符三个字节,这可能导致 a 为某些表消耗更多字节(然后需要),例如可能导致麻烦/性能消耗的临时表。除此之外,并非所有的 Unicode 窗格都受支持,MySQL 支持 Unicode 版本 3.0 的基本多语言平面 (BMP) 中的字符。
    • @hakre 有趣,我从未研究过。 MySQL 5.5+ 支持 Unicode 5.0。 UTF-8 显然还是很浪费的。
    • 5.5 中还有三个字节:"MySQL 5.5 中的 utf8 字符集与 5.5 之前的相同,并且具有完全相同的特性:[...]" @987654324 @。 - 查找 varchar / char 列,char 需要保留每个字符所需的最大字节数,即使不需要也是如此。
    【解决方案3】:

    1) 是否可以将所有内容都表示为 UTF-8?

    是的,所有内容都在 UNICODE 中定义。这是你现在能得到的最多,UNICODE 可以支持的未来还有空间。

    2) 我可以使用什么来有效地将任何字符编码转换为 UTF-8,以便我可以使用 PHP 字符串函数对其进行解析并将其保存到我的数据库中,然后使用 htmlentities 回显?

    您唯一需要知道的是数据的实际编码。如果您希望您的 Web 应用程序支持 UTF-8 进行输入和输出,则前端需要发出信号表明它支持 UTF-8。有关您的应用程序用户界面的指南,请参阅 Character Encodings

    在 PHP 中,您需要使用它支持的编码来提供任何函数。有些需要指定编码,有些则需要转换。如果它支持您的要求,请始终检查功能文档。另外检查您的 PHP 配置。

    相关:

    1. Preparing PHP application to use with UTF-8
    2. How to detect malformed utf-8 string in PHP?

    【讨论】:

    • 我想要一个 [citation-needed] 声称 UTF-8 不能编码所有 Unicode 代码点!
    • @deceze:这对初学者来说足够了吗? "RFC 3629 UTF-8 November 2003 3. UTF-8 定义 UTF-8 由 Unicode 标准 [UNICODE] 定义。描述和公式也可以在 ISO/IEC 10646-1 [ISO. 10646] 在 UTF-8 中,U+0000..U+10FFFF 范围(UTF-16 可访问范围)中的字符使用 1 到 4 个八位字节的序列进行编码。" - UTF-16 范围只是不是全范围。 UTF-8 也不是。
    • 那我问你哪里说UTF-16不是全范围。我正在查看的每篇文档都说当前的 Unicode 范围是 000000 - 10FFFF,并且所有 UTF 编码都可以对所有这些点进行编码。 UTF-8 最初甚至被设计为最多使用六个八位字节,这意味着它可以在必要时编码更多的点。
    • 这确实很挑剔。 :)
    • @deceze:看来我在这里吹毛求疵了。我将更改答案,我所指的窗格尚未定义。目前仅使用 21 位,对于 UTF-8 是安全的。 UTF-8 编码不包括一些代理,但包括一些非字符代码点。
    【解决方案4】:

    如果你想改变一个字符串的编码你可以试试

    $utf8_string = mb_convert_encoding( $yourBadString , 'UTF-8' );
    

    【讨论】:

    • Convert from what 是个问题。如果你不知道这一点,你就无法合理可靠地转换任何东西。
    • 如果您不知道,您可以使用 mb_detect_encoding() 来查找。虽然我从来不需要检测编码来强制它为 UTF-8,但 mb_convert_encoding 的第三个参数是可选的,不需要。
    • 如果不提供第三个参数,则默认为内部设置的编码。自动检测编码介于非常棘手到不可能之间,至少它不是完全可靠的。都只是位,通常一个位序列在许多不同的编码中同样有效,因此“自动检测”通常归结为猜测。
    • 是的,如果您不提供第三个参数,它将默认为内部编码。但是当你说我们在应用程序中一直这样做“非常非常棘手甚至不可能”时,我不同意。与国防部合作使我们有机会处理广泛(全部)不同的语言、货币和编码,因为我们显然在全球都有军队。我们从来没有遇到过这种技术的问题。
    • 那么显然你并没有真正处理很多模棱两可的编码:ideone.com/q2Skp
    【解决方案5】:

    我发现唯一适用于 UTF-8 编码的方法是在我的 config.php 中设置

    putenv('LC_ALL=en_US.utf8'); // or whatever language you need
    setlocale(LC_ALL, 'en_US.utf8');  // or whatever language you need
    bindtextdomain("mydomain", dirname(__FILE__) . "/../language");
    textdomain("mydomain");
    

    【讨论】:

      【解决方案6】:

      编辑:

      Is it possible to represent everything as UTF-8?

      是的,这是您需要确保的:

      • html : headers/meta-header 设置为 utf-8
      • 所有文件保存为 utf-8
      • 数据库整理、表格和数据编码为 utf-8

      What can I use to effectively convert any character encoding to UTF-8

      您可以在将其保存到数据库之前使用utf8_encode(因为对于主要针对西欧语言设置的系统,它通常是 ISO-8859-1 或其密切关系,ref)。

      // eg
      $name = utf8_encode($this->input->post('name'));
      

      正如我之前提到的,您需要确保数据库排序规则、表格和数据编码为 utf-8。在 CI 中,在您的数据库连接配置中

      // Make sure have these lines
      $db['default']['char_set'] = 'utf8';
      $db['default']['dbcollat'] = 'utf8_general_ci';
      

      【讨论】:

      • utf8_encode 仅从 latin-1 转换为 UTF-8。如果用户没有向您发送 latin-1,则此功能无用。如果用户正在给你发latin-1,你只能支持latin-1编码的256个字符。如果您可以指定用户向您发送 latin-1,您也可以直接指定您想要 UTF-8。
      • @deceze,谢谢你提醒我不要太简化问题。我更新了我对您的反对票的回答(耶)。我之前的回答确实过于简化了这个问题。懒惰是我的美德(笑):)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多