关于PHP在数组对象与JSON数据之间的转换问题(编码问题)
PHP在 5.x以后提供json_ecode 与 json_decode 两个函数来处理 数组与JSON数据之间的转换。但是它们并未很好的处理存在UTF-8或者GBK中文字符的数组,常常会返回NULL值。下面有两个函数可以代替它们来使用:
//数组转换成JSON格式核心函数
function array2json($arr) { // if(function_exists('json_encode')) return json_encode($arr); //Lastest versions of PHP already has this functionality. $parts = array(); $is_list = false;//Find out if the given array is a numerical array
$keys = array_keys($arr); $max_length = count($arr)-1; if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {//See if the first key is 0 and last key is length - 1 $is_list = true; for($i=0; $i<count($keys); $i++) { //See if each key correspondes to its position if($i != $keys[$i]) { //A key fails at position check. $is_list = false; //It is an associative array. break; } } }foreach($arr as $key=>$value) {
if(is_array($value)) { //Custom handling for arrays if($is_list) $parts[] = array2json($value); /* :RECURSION: */ else $parts[] = '"' . $key . '":' . array2json($value); /* :RECURSION: */ } else { $str = ''; if(!$is_list) $str = '"' . $key . '":';//Custom handling for multiple data types
if(is_numeric($value)) $str .= $value; //Numbers elseif($value === false) $str .= 'false'; //The booleans elseif($value === true) $str .= 'true'; else $str .= '"' . addslashes($value) . '"'; //All other things // :TODO: Is there any more datatype we should be in the lookout for? (Object?)$parts[] = $str;
} } $json = implode(',',$parts); if($is_list) return '[' . $json . ']';//Return numerical JSON return '{' . $json . '}';//Return associative JSON }
//下面是将JSON转换成数组,分为UTF-8格式的和GBK格式,用法如下:
/*$array_gbk = jsonDecode( $jsonString );
$array_utf8 = jsonDecode( $jsonString , 'utf-8' ); */
function unicode_encode($name)
{ $name = iconv('UTF-8', 'UCS-2', $name); $len = strlen($name); $str = ''; for ($i = 0; $i < $len - 1; $i = $i + 2) { $c = $name[$i]; $c2 = $name[$i + 1]; if (ord($c) > 0) { //两个字节的文字 $str .= '/u'.base_convert(ord($c), 10, 16).base_convert(ord($c2), 10, 16); } else { $str .= $c2; } } return $str; } //将UNICODE编码后的内容进行解码 function unicode_decode($name) { //转换编码,将Unicode编码转换成可以浏览的utf-8编码 $pattern = '/(///u([/w]{4}))/i'; $name = preg_replace_callback( $pattern , '_unicode_decode' , $name ); return $name; } function _unicode_decode( $str ) { $str = $str[0]; $name = ''; $code = base_convert(substr($str, 2, 2), 16, 10); $code2 = base_convert(substr($str, 4), 16, 10); $c = chr($code).chr($code2); $c = iconv('UCS-2', 'UTF-8', $c); $name .= $c; return $name; } function jsonDecode( $json , $to_encode = 'gbk' , & $i = 0 ) { if ( null === $i ) { $i = 0; } for( ; $i < strlen( $json ) ; $i ++ ) { $chr = $json[$i]; switch( $chr ) { case '"' : case "'" : //字符串 $i ++; $val = ''; while( $json[$i] != $chr || $lastChr == '//' ) { $lastChr = $json[$i]; $val .= $lastChr; $i ++; } ++ $i; //字符串处理 //unicode 转汉字 $val = unicode_decode( $val ); if ( strtolower( str_ireplace( '-' , '' , $to_encode ) ) !== 'utf8' ) { $val = mb_convert_encoding( $val , $to_encode , 'utf-8' ); } $val = stripslashes( $val ); return $val; break; case 'a' : case 'b' : case 'c' : case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A' : case 'B' : case 'C' : case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': //字符串 if ( trim( $chr ) === '' ) { continue; } $val = $chr; while( preg_match( '#^[a-zA-Z0-9/.]$#' , $json[++$i] ) ) { $val .= $json[$i]; } $lVal = strtolower( $val ); if ( $lVal == 'true' ) { return true; } if ( $lVal == 'false' ) { return false; } if ( preg_match( '#^[0-9/.]+$#' , $lVal ) ) { return $val + 0; } return $val; case '{' : $val = array(); $i ++; $key = ''; while( $json[$i] != '}' ) { $key .= $json[$i]; $i ++; if ( $json[$i] == ':' ) { $key = ltrim( $key ); $key = ltrim( $key , ',' ); //去除, $key = trim( $key );//去两边的空白 if ( preg_match( '#^"(.+?)"$#' , $key , $m ) ) { $key = $m[1]; } if ( preg_match( '#^/'(.+?)/'$#' , $key , $m ) ) { $key = $m[1]; } ++ $i; $val[$key] = jsonDecode( $json , $to_encode , $i ); $key = ''; } } ++ $i; return $val; break; case '[' : $val = array(); $i ++; $t = 0; while( $json[$i] != ']' ) { if ( $json[$i] == ',' ) { $i ++; continue; } $val[] = jsonDecode( $json , $to_encode , $i ); } $i ++; return $val; break; } } return NULL ; }