-
- // 自动转换字符集 支持数组转换
- function auto_charset($fContents, $from='gbk', $to='utf-8') {
- $from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
- $to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
- if (strtoupper($from) === strtoupper($to) || empty($fContents) || (is_scalar($fContents) && !is_string($fContents))) {
- //如果编码相同或者非字符串标量则不转换
- return $fContents;
- }
- if (is_string($fContents)) {
- if (function_exists('mb_convert_encoding')) {
- return mb_convert_encoding($fContents, $to, $from);
- } elseif (function_exists('iconv')) {
- return iconv($from, $to, $fContents);
- } else {
- return $fContents;
- }
- } elseif (is_array($fContents)) {
- foreach ($fContents as $key => $val) {
- $_key = auto_charset($key, $from, $to);
- $fContents[$_key] = auto_charset($val, $from, $to);
- if ($key != $_key)
- unset($fContents[$key]);
- }
- return $fContents;
- }
- else {
- return $fContents;
- }
- }
复制代码
这时可能会想到直接用iconv来进行转码,但iconv这个函数需要提供的两个参数为输入编码和输出编码,而现在根本不知道接受的字符串是什么编码,如果此时能得到接收字符是什么编码就好了。
对于这个问题,有以下两种方案供参考。
方案一
要客户端提交数据时,指定所提交的编码,这时就需要多给一个用来指定编码的变量。
$string = $_GET['charset'] === 'gbk' ? iconv('gbk','utf-8',$_GET['str']) : $_GET['str'];
对于这种情况,如果在没有约定或者我们不能控制客户端的情况下,似乎这种方案使用不是很好。
方案二
直接由服务器端来检测所接收的数据编码。
这种方案当然是最理想了的了,现在问题是怎么检测一个字符的编码吗?对于这种情况,在php里,mb_string这个扩展中的mb_check_encoding提供了我们所需要的功能。
$str = mb_check_encoding($_GET['str'],'gbk') ? iconv('gbk','utf-8',$_GET['str']) : $_GET['str'];
但这需要打开mb_string这个扩展,有些时候可能我们的生产服务器中没有打开这个扩展。对于这种情况,需要自己借助如下函数来判断编码。
-
- function isGb2312($string) {
- for($i=0; $i 127) {
- if( ($v >= 228) && ($v < = 233) )
- {
- if( ($i 2) >= (strlen($string) - 1)) return true;
- $v1 = ord( $string[$i 1] );
- $v2 = ord( $string[$i 2] );
- if( ($v1 >= 128) && ($v1 < =191) && ($v2 >=128) && ($v2 < = 191) )
- return false;
- else
- return true;
- }
- }
- }
- return true;
- }
- function isUtf8($string) {
- return preg_match('%^(?:
- [x09x0Ax0Dx20-x7E] # ASCII
- | [xC2-xDF][x80-xBF] # non-overlong 2-byte
- | xE0[xA0-xBF][x80-xBF] # excluding overlongs
- | [xE1-xECxEExEF][x80-xBF]{2} # straight 3-byte
- | xED[x80-x9F][x80-xBF] # excluding surrogates
- | xF0[x90-xBF][x80-xBF]{2} # planes 1-3
- | [xF1-xF3][x80-xBF]{3} # planes 4-15
- | xF4[x80-x8F][x80-xBF]{2} # plane 16
- )*$%xs', $string);
- }
复制代码
这里我们就可以使用以上任何一个函数来实现编码的检测,并将其转换为指定的编码了。
$str = isGb2312($_GET['str'],'gbk') ? iconv('gbk','utf-8',$_GET['str']) : $_GET['str'];
|