《PHP中的字符串、编码、UTF-8》讲述了一系列基础知识,比较枯燥,现在有用——PHP字符串处理最佳实践。本文为《PHP、字符串、编码、UTF-8》相关知识的第二部分。结论先行——在PHP的各个方面都使用UTF-8编码。PHP语言层面不支持Unicode字符集,但可以通过UTF-8编码处理大部分问题。最好的做法是清楚知道输入编码(不知道就检测),内部转为UTF-8编码,输出编码也统一为UTF-8编码。PHP层面如何处理UTF-8在操作Unicode字符集时,一定要安装mbstring扩展并使用相应的函数,而不是原生的字符串函数。例如,如果一个文件编码为UTF-8PHP代码,如果使用strlen()函数是错误的,请改用mb_strlen()函数。mbstring扩展的大部分功能都需要基于一种编码(内部编码)进行处理,请务必统一使用UTF-8编码,大部分可以在PHP.INI中配置。从PHP5.6开始,default_charset配置可以替代mbstring.http_input、mbstring.http_output。另一个重要的配置是mbstring.language,默认值是Neutral(UTF-8)。注意文件编码和mbstring扩展的内部编码不是同一个概念。一言以蔽之:PHP.INI中涉及mbstring扩展的部分尽量使用UTF-8编码。请使用mbstring扩展函数而不是本机字符串操作函数。在使用相关功能时,请务必了解您所操作的字符的编码是什么。使用相应功能时,在显示屏上写入UTF-8编码参数。例如,htmlentities()函数的第三个参数显示UTF-8。文件IO操作如何处理UTF-8这里举个例子,如果你想打开一个文件,但是你不知道文件内容的编码,怎么处理呢?最好的做法是打开的时候统一转成UTF-8,修改完内容后再转回原来的编码保存到文件中。看代码:if(mb_internal_encoding()!="UTF-8"){mb_internal_encoding("UTF-8");}$file="文件.txt";//编码为gbk的中文文件$str=file_get_contents($file);//无论源是什么编码,统一显示时都会转为UTF-8if(mb_check_encoding($str,"GBK"))$str=mb_convert_encoding($str,"UTF-8","GBK");$str="修改内容";$str=mb_convert_encoding($str,$srcbm,"UTF-8");//原样转换回来file_put_contents($file,$str);Mysql和UTF-8***这个比较简单,先保证你的Mysql是UTF-8。然后Mysql客户端在连接的时候也维护UTF-8。具体来说,在PHP中,当imysql或PDO扩展连接Mysql时,设置UTF-8作为连接编码。如果双方一致,一般不会有问题。浏览器和UTF-8的最佳实践比较简单,就是如果你的输出内容是网页,那么你的字符串处理输出应该始终是UTF-8;同时在PHP.INI中也明确设置了default_charset为UTF-8;HTMLMetaTag也明确标识为UTF-8。现在一切都好吗?不可以,虽然服务器和浏览器允许用户使用UTF-8编码,但是用户的行为不具有约束力。他可能输入了其他编码的字符,或者上传的文件名是其他编码的字符,那么该怎么办?可以通过mb_http_input()和mb_check_encoding()函数检测用户的编码,然后在内部转换为UTF-8。确保在任何级别,最终处理都是UTF-8编码。也就是说,你需要手段能够知道你的输入是什么编码,处理后的控制输出的编码是UTF-8。mbstring.encoding_translation指令和mb_detect_encoding()函数已弃用。折磨我好久。操作系统和UTF-8的最佳实践由于操作系统的不同,PHP以不同方式处理Unicode文件名。在Linux下,文件名总是UTF-8编码,在中文Windows环境下,文件名总是GBK编码,记住这一点即可。通过例子来说明下面的命令行程序功能,运行在Windows10中文版操作系统上,文件编码为UTF-8functionfilenameexample(){$filename="test.txt";$gbk_filename=iconv("UTF-8","GBK",$filename);file_put_contents($gbk_filename,"test");echofile_get_contents($gbk_filename);}functionscandirexample(){$arr=scandir("./tmp");foreach($arras$v){if($v=="."||$v=="..")继续;$filename=iconv("GBK","UTF-8",$v);$content=file_get_contents("./tmp/".$v);}}如果不想写兼容Windows和Linux的程序,可以对文件名进行urlencode,例如:functionurlencodeexample(){$filename="Test2.txt";$urlencodefilename=urlencode($filename);file_put_contents($urlencodefilename,"test");echofile_get_contents($urlencodefilename);}使用PHP通过header()函数下载文件时,还要考虑浏览器和操作系统(大多数人使用Windows),对于Chrome,输出文件名编码可以是UTF-8,Chrome会自动将文件名转换为GBK编码。对于低版本的IE,它继承了操作系统的环境,所以如果下载的文件名是中文,则必须转换为UTF-8编码,否则用户在下载时会看到乱码文件名。用代码来说明:
