8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

始终使用 UTF-8

ryandra 1月前

58 0

我正在设置一个新服务器,并希望在我的 Web 应用程序中完全支持 UTF-8。我过去曾在现有服务器上尝试过此操作,但似乎总是最终不得不回退到 ISO-8859-1。这...

我正在设置一个新服务器,并希望在我的 Web 应用程序中完全支持 UTF-8。我过去曾在现有服务器上尝试过此操作,但似乎总是最终不得不回退到 ISO-8859-1。

我到底需要在哪里设置编码/字符集?我知道我需要配置 Apache、MySQL 和 PHP 才能做到这一点 — 是否有一些我可以遵循的标准清单,或者可以排除不匹配发生的位置故障?

这是用于新的 Linux 服务器,运行 MySQL 5、PHP 5 和 Apache 2。

帖子版权声明 1、本帖标题:始终使用 UTF-8
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由ryandra在本站《mysql》版块原创发布, 转载请注明出处!
最新回复 (0)
  • Itha 1月前 0 只看Ta
    引用 2

    数据库服务器的时区也是一个重要的设置。我建议使用 UTC(对于 MySQL,`set time_zone='+0:00``)作为服务器默认值。

  • 数据存储

    • p1

    • p2

    数据访问

    • p4

    • p5

      • 【【p6】】

         $dbh = new PDO('mysql:charset=utf8mb4');
      • 【【p7】】

          $mysqli->set_charset('utf8mb4');       // object oriented style  mysqli_set_charset($link, 'utf8mb4');  // procedural style
      • 【【p8】】

    • p9

    • p10

    输出

    • 应在 HTTP 标头中设置 UTF-8,例如 Content-Type: text/html; charset=utf-8 。您可以通过在 php.ini 中设置 default_charset (首选)或手动使用 header() 函数来实现。
    • 如果您的应用程序将文本传输到其他系统,则还需要告知它们字符编码。对于 Web 应用程序,必须告知浏览器发送数据的编码(通过 HTTP 响应标头或 HTML 元数据 )。
    • 当使用对输出进行编码时 json_encode() ,添加 JSON_UNESCAPED_UNICODE 作为第二个参数。

    输入

    • 浏览器将使用为文档指定的字符集提交数据,因此输入时无需进行任何特殊操作。
    • 如果您对请求编码有疑问(以防被篡改),您可以在尝试存储或在任何地方使用它之前验证每个收到的字符串是否为有效的 UTF-8。PHP 的 mb_check_encoding() 可以解决这个问题,但您必须虔诚地使用它。实际上没有办法解决这个问题,因为恶意客户端可以以他们想要的任何编码提交数据,而且我还没有找到让 PHP 可靠地为您完成此操作的技巧。

    其他代码注意事项

    • p14

    • 第15页

    • p16

    • p17

  • 我没有错:COLLATE 意味着 CHARACTER SET。例如,请参阅 dev.mysql.com/doc/refman/5.0/en/charset-database.html。

  • 请注意,MySQL 使用的语言与其他人不同。当 MySQL 说“utf8”时,它实际上意味着“某种奇怪的、弱智的 UTF-8 变体,由于天知道什么荒谬的原因,它被限制为三个字节”。如果您真的想要 UTF-8,您应该告诉 MySQL,您想要这个 MySQL 喜欢称之为 utf8mb4 的奇怪东西。不要费心去想“WTF!”。

  • @chazomaticus 你觉得我应该使用 mbstring 来处理英语吗....或者 strlen 就够了?那希腊语呢?

  • @chazomaticus 我的数据库已经存储了问号而不是希伯来语文本,那么我如何从问号中获取原始文本?

  • 我想对 chazomaticus 的精彩回答 :

    也不要忘记 META 标签(像这样,或者 它的 HTML4 或 XHTML 版本 ):

    <meta charset="utf-8">
    

    这看起来微不足道,但 IE7 之前曾给我带来过这个问题。

    我做的一切都是正确的;数据库、数据库连接和 Content-Type HTTP 标头都设置为 UTF-8,并且它在所有其他浏览器中都运行良好,但 Internet Explorer 仍然坚持使用“西欧”编码。

    原来是页面缺少 META 标签。添加该标签后问题就解决了。

    W3C 实际上有一个相当大的 部分专门用于 I18N 。他们有许多与此问题相关的文章 - 描述了 HTTP,(X)HTML 和 CSS 方面的问题:

    • 常见问题解答:将 (X)HTML 页面编码更改为 UTF-8
    • 在 HTML 中声明字符编码
    • 教程:XHTML、HTML 和 CSS 中的字符集和编码
    • 设置 HTTP 字符集参数

    他们建议同时使用 HTTP 标头和 HTML 元标记(或者在 XHTML 作为 XML 的情况下使用 XML 声明)。

  • 除了在 php.ini 中设置之外 default_charset 在任何输出之前使用代码 header() 发送正确的字符集

    header('Content-Type: text/html; charset=utf-8');
    

    只要您意识到大多数 字符串函数不适用于 Unicode,并且有些函数可能会完全破坏字符串 ,那么在 PHP 中使用 Unicode 就很容易了。PHP 认为 \'字符\' 的长度为 1 个字节。有时这是可以的(例如, explode() 仅查找字节序列并将其用作分隔符 - 因此您查找的实际字符并不重要)。但其他时候,当该函数实际上设计用于处理 characters ,PHP 不知道您的文本具有使用 Unicode 找到的多字节字符。

    一个值得一试的好库是 phputf8 。它重写了所有“坏”函数,因此您可以安全地处理 UTF8 字符串。还有一些扩展,例如 mb_string 扩展,也可以为您完成此操作,但我更喜欢使用该库,因为它更易于移植(但我编写的是大众市场产品,因此这对我来说很重要)。但无论如何,phpputf8 可以在后台使用 mb_string 来提高性能。

  • 引用 10

    警告: 此答案适用于 PHP 5.3.5 及更低版本。请勿将其用于 PHP 版本 5.3.6(2011 年 3 月发布)或更高版本。

    Palec's answer to PDO + MySQL and broken UTF-8 encoding .


    时遇到一个问题 PDO ,答案是将其用于 PDO 连接字符串:

    $pdo = new PDO(
        'mysql:host=mysql.example.com;dbname=example_db',
        "username",
        "password",
        array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
    
  • 进一步研究后发现,只有 5.3.6 之前的 PHP 版本才需要这样做。另请参阅:http://.com/a/4361485/2286722(尽管它们使用单​​独的 $dbh->exec(\'set names utf8\');;但我更喜欢这里介绍的方法)。顺便说一句,PHP 手册中也有类似的注释:php.net/manual/en/pdo.construct.php#96325。

  • 另请参阅 Palec 对 PDO + MySQL 和损坏的 UTF-8 编码的回答。

  • 引用 13

    在我的例子中,我使用的是 mb_split ,它使用正则表达式。因此,我还必须手动确保正则表达式编码为 UTF-8,方法是: mb_regex_encoding('UTF-8');

    附注:我还通过运行发现 mb_internal_encoding() 内部编码不是 UTF-8,我通过运行更改了它 mb_internal_encoding("UTF-8"); .

  • 首先,如果你使用的是 PHP 5.3 之前的版本,那么不行。你有很多问题需要解决。

    我很惊讶没有人提到 intl 库,该库对 Unicode , 字素字符串 , 操作 , 本地化 等有很好的支持,见下文。

    Elizabeth Smith PHPBenelux'14 slides 幻灯片 中关于 PHP 中 Unicode 支持的一些信息

    国际

    好的:

    • ICU 库的包装器
    • 标准化语言环境,按脚本设置语言环境
    • 数字格式
    • 货币格式
    • 消息格式化(替代 gettext)
    • 日历、日期、时区和时间
    • 音译器
    • 欺骗检测工具
    • 资源包
    • 转换器
    • IDN 支持
    • 字素
    • 排序规则
    • 迭代器

    坏的:

    • 不支持 zend_multibyte
    • 不支持HTTP输入输出转换
    • 不支持函数重载

    mb_字符串

    • 启用 zend_multibyte 支持
    • 支持透明 HTTP 输入/输出编码
    • 提供一些功能的包装器,例如 strtoupper

    图标

    • 主要用于字符集转换
    • 输出缓冲区处理程序
    • mime 编码功能
    • 转换
    • 一些字符串助手(len、substr、strpos、strrpos)
    • 流过滤器 stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP')

    数据库

    • MySQL:表和连接上的字符集和排序规则(不是排序规则)。另外,不要使用 mysql - mysqli 或 PDO
    • postgresql: pg_set_client_encoding
    • sqlite(3): 确保它是使用 Unicode 和国际支持进行编译的

    其他一些问题

    • 除非使用第三方扩展,否则您不能在 PHP 和 Windows 中使用 Unicode 文件名。
    • 如果您使用 exec、proc_open 和其他命令行调用,请以 ASCII 格式发送所有内容
    • 纯文本不是纯文本,文件有编码
    • 您可以使用 iconv 过滤器即时转换文件
  • tru 1月前 0 只看Ta
    引用 15

    是的,没错。Mysqli 和 PDO 可以使用其原生驱动程序。如果您使用 --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd 选项编译 php,它们也可以使用 mysqlnd 驱动程序。

  • 引用 16

    我要补充的是,这些令人惊叹的答案强调以 UTF-8 编码保存文件,我注意到浏览器接受此属性,而不是将 UTF-8 设置为代码编码。任何像样的文本编辑器都会向您显示这一点。例如, Notepad++ 有一个文件编码菜单选项,它会显示当前编码并允许您更改它。对于我的所有 PHP 文件,我都使用不带 8 的 UTF- BOM .

    前段时间,有人让我为别人设计的 PHP 和 MySQL 应用程序添加 UTF-8 支持。我注意到所有文件都是用 ANSI 编码的,所以我不得不使用 iconv 转换所有文件,将数据库表更改为使用 UTF-8 字符集和 utf8_general_ci 排序,在连接后将“SET NAMES utf8”添加到数据库抽象层(如果使用 5.3.6 或更早版本。否则,您必须在连接字符串中使用 charset=utf8)并更改字符串函数以使用等效的 PHP 多字节字符串函数。

  • 我最近发现使用 strtolower() 可能会导致特殊字符后数据被截断的问题。

    解决方案是使用

    mb_strtolower($string, 'UTF-8');
    

    mb_ 使用 MultiByte。它支持更多字符,但总体来说速度较慢。

  • 在 PHP 中,您需要使用 多字节函数 ,或者打开 mbstring.func_overload 。这样,如果您有占用多个字节的字符,那么像 strlen 这样的东西就可以工作。

    您还需要确定响应的字符集。您可以像上面一样使用 AddDefaultCharset,也可以编写返回标头的 PHP 代码。(或者,您可以将 META 标记添加到 HTML 文档中。)

  • 需要注意的是,由于上述 @JW 评论中提到的问题,mbstring.func_overload 功能从 PHP 7.2 开始被弃用。因此,最好的建议是:是的,您绝对应该使用 mbstring 函数,但不要使用过载功能让标准函数以多字节方式工作。

  • 我刚刚遇到了同样的问题,并在 PHP 手册中找到了一个很好的解决方案。

    我将所有文件的编码都改为 UTF8,然后将连接的默认编码也改为 UTF8。这解决了所有问题。

    if (!$mysqli->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $mysqli->error);
    } else {
       printf("Current character set: %s\n", $mysqli->character_set_name());
    }
    

    查看源代码

返回
作者最近主题: