php - UTF-8贯穿始终

标签 php mysql linux apache utf-8

我正在安装一个新服务器,并希望在我的web应用程序中完全支持UTF-8。过去我曾在现有服务器上尝试过这种方法,但最终似乎不得不退回ISO-859-1。
我到底需要在哪里设置编码/字符集?我知道我需要配置Apache、MySQL和PHP来做到这一点-是否有一些标准的检查表可以遵循,或者可能排除不匹配的地方?
这是一个新的Linux服务器,运行MySQL 5、PHP、5和Apache 2。

最佳答案

数据存储:
在数据库中的所有表和文本列上指定utf8mb4字符集。这使得MySQL能够物理地存储和检索UTF-8中本机编码的值。注意,如果指定了utf8mb4排序规则(没有任何显式字符集),MySQL将隐式使用utf8mb4_*编码。
在旧版本的MySQL(<5.5.3)中,不幸的是,您将被迫使用只支持Unicode字符子集的简单utf8。我真希望我是在开玩笑。
数据访问:
在应用程序代码(例如PHP)中,无论使用何种DB访问方法,都需要将连接字符集设置为utf8mb4。这样,当MySQL将数据交给应用程序时,它不会从它的本机UTF-8进行转换,反之亦然。
一些驱动程序提供了自己的机制来配置连接字符集,这两种机制都会更新自己的内部状态,并通知MySQL要在连接上使用的编码这通常是首选方法。在PHP中:
如果在PHP≥5.3.6的情况下使用PDO抽象层,可以在DSN中指定charset

$dbh = new PDO('mysql:charset=utf8mb4');

如果您正在使用mysqli,您可以拨打set_charset()
$mysqli->set_charset('utf8mb4');       // object oriented style
mysqli_set_charset($link, 'utf8mb4');  // procedural style

如果你被普通的mysql困住了,但是碰巧运行的是PHP≥5.2.3,你可以调用mysql_set_charset
如果驱动程序没有提供自己的机制来设置连接字符集,则可能需要发出一个查询来告诉MySQL应用程序希望如何对连接上的数据进行编码:SET NAMES 'utf8mb4'
关于utf8mb4/utf8的同样考虑适用于上述情况。
输出:
如果应用程序将文本传输到其他系统,则还需要通知它们字符编码。对于web应用程序,必须通知浏览器发送数据的编码(通过HTTP响应头或HTML metadata)。
在PHP中,您可以使用default_charsetPHP.ini选项,或者自己手动发出Content-TypeMIME头,这只是更多的工作,但具有相同的效果。
使用json_encode()对输出进行编码时,将JSON_UNESCAPED_UNICODE作为第二个参数添加。
输入:
不幸的是,在尝试存储或在任何地方使用之前,您应该验证每个接收到的字符串都是有效的UTF-8。PHP的mb_check_encoding()起到了作用,但您必须虔诚地使用它。真的没有办法解决这个问题,因为恶意客户端可以以他们想要的任何编码提交数据,我还没有找到一个让PHP可靠地为您做到这一点的诀窍。
从我对当前HTML spec的阅读来看,以下子项目符号对于现代HTML来说不再是必需的,甚至不再有效。我的理解是浏览器将使用并提交文档指定字符集中的数据。但是,如果您的目标是较旧版本的HTML(XHTML、HTML4等),这些要点可能仍然有用:
仅适用于HTML5之前的HTML:您希望浏览器发送给您的所有数据都是UTF-8格式的。不幸的是,如果要可靠地执行此操作,唯一的方法是将accept-charset属性添加到所有<form>标记:<form ... accept-charset="UTF-8">中。
对于HTML5之前的HTML:请注意,W3CHTML规范指出,客户端“应该”默认以服务器提供的任何字符集将表单发送回服务器,但这显然只是一个建议,因此需要在每个<form>标记上显式显示。
其他代码注意事项:
显然,您要提供的所有文件(PHP、HTML、JavaScript等)都应该用有效的UTF-8编码。
您需要确保每次处理UTF-8字符串时都是安全的。不幸的是,这是最困难的部分。您可能希望广泛使用PHP的mbstring扩展。
默认情况下,PHP的内置字符串操作不是UTF-8安全的。使用普通的PHP字符串操作(比如连接)可以安全地完成一些事情,但是对于大多数事情,应该使用等效的mbstring函数。
要知道你在做什么(读:不要搞砸了),你真的需要知道UTF-8以及它是如何在尽可能低的水平上工作的。查看utf8.com中的任何链接,以获取一些好的资源,了解您需要了解的一切。

关于php - UTF-8贯穿始终,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40808131/

相关文章:

mysql - MediumText 和 ASP/MySQL 的数据损坏

php - 统计ID数量

php - 调用未定义函数 dl() php

PHP Session 变量自动分配给常规变量

php - SQL=INSERT INTO `#__user_usergroup_map` (`user_id` ,`group_id` ) VALUES (, 2) -- 数据库未更新

linux - 多作业 make 中的 GNU Makefile 依赖

mysql - 如何使用列名将 SQL 查询导出到 Excel

mysql - 对所有数据使用内联 View 时遇到问题

linux - 无法在 Linux 上确定正确的 MIME 类型

python pip升级中断