我正在为拥有完全不同的字母表的国际客户工作,因此我试图最终概述PHP和MySQL之间的完整工作流程,以确保正确插入所有字符编码。我已经阅读了很多这方面的教程,但仍然有问题(有很多东西需要学习),并且我想我可以把它们放在一起然后问。
PHP
header('Content-Type:text/html; charset=UTF-8');
mb_internal_encoding('UTF-8');
HTML
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<form accept-charset="UTF-8"> .. </form>
(虽然后者是可选的,而是一个建议,但我相信我宁愿建议不要做任何事情)
的MySQL
CREATE database_name DEFAULT CHARACTER SET utf8;
或ALTER database_name DEFAULT CHARACTER SET utf8;
和/或使用utf8_general_ci
作为MySQL连接排序规则。
(这里important to note如果使用varchar,这会增加数据库大小)
连接
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER_SET utf8");
业务逻辑
使用mb_detect_encoding()
检测是否不是UTF8并使用ivon()
进行转换
验证过长的UTF8和UTF16序列
$body=preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]|(?<=^|[\x00-\x7F])[\x80-\xBF]+|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/','�',$body);
$body=preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]|\xED[\xA0-\xBF][\x80-\xBF]/S','?', $body);
问题
是mb_internal_encoding('UTF-8')
必需的,如果是这样,这意味着我必须使用所有多字节函数而不是其核心函数,如mb_substr()
而不是substr()
是否仍然需要检查输入错误的输入,如果是,那么可靠的功能/类是什么?我可能不想删除不良数据,也不太了解音译。
应该是utf8_general_ci
还是utf8_bin
?
上述工作流程中是否缺少某些内容?
http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/
http://webcollab.sourceforge.net/unicode.html
http://stackoverflow.com/a/3742879/1043231
http://www.adayinthelifeof.nl/2010/12/04/about-using-utf-8-fields-in-mysql/
http://akrabat.com/php/utf8-php-and-mysql/
答案 0 :(得分:6)
mb_internal_encoding('UTF-8')
本身不做任何事情,它只为每个mb_
函数设置默认编码参数。如果您没有使用任何mb_
功能,则没有任何区别。如果是,那么设置它是有意义的,这样您就不必每次都单独传递$encoding
参数。mb_detect_encoding
几乎没用,因为从根本上不可能准确地检测未知文本的编码。您应该知道文本blob的编码是什么,因为您有关于它的规范,或者您需要解析适当的元数据,如标题或元标记,其中指定了编码。mb_check_encoding
检查您希望它所在的编码中的文本块是否有效通常就足够了。如果不是,请丢弃它并抛出适当的错误。关于:
这是否意味着我必须使用所有多字节函数而不是其核心函数
如果您正在操作包含多字节字符的字符串,那么是的,您需要使用mb_
函数来避免错误的结果。核心字符串函数仅适用于字节级别,而不是字符级别,这是您在处理字符串时通常需要的。
utf8_general_ci
与utf8_bin
仅在整理时有所不同,即排序和比较字符串。使用utf8_bin
数据以二进制形式处理,即只有相同的数据是相同的。使用utf8_general_ci
时会应用一些逻辑,例如“é”与“e”一起排序,大写被认为等于小写。答案 1 :(得分:1)
它真的应该是utf8_general_ci还是utf8_bin?
您必须使用utf8_bin进行区分大小写搜索,否则使用utf8_general_ci
是PHP 5.3及更高版本中必需的mb_internal_encoding('UTF-8'),如果是这样,这意味着我必须使用所有多字节函数而不是其核心函数,如mb_substr()而不是substr()?
是的当然,如果你有一个多字节字符串,你需要使用mb_ * family函数,除了二进制安全php标准函数,如str_replace(); (以及其他一些人)
嗯,不,你不能检查它。是否仍然需要检查输入错误的输入,如果是,那么可靠的功能/类是什么?我可能不想删除不良数据,也不太了解音译。