JSON格式编码操作类

来源:互联网 发布:销售数据字典怎么写 编辑:程序博客网 时间:2024/05/16 17:09

【原创】JSON格式编码操作类

可以使大家加深对字符串编码和json编码原理的了解

define('IS_NULL',   'NULL');define('IS_BOOL',   'boolean');define('IS_INT',    'integer');define('IS_DOUBLE', 'double');define('IS_STRING', 'string');define('IS_ARRAY',  'array');define('IS_OBJECT', 'object');/**     * @author jiang kejun <jinhua_k9@163.com>     * @name Json        * @since 2013.6.3   * @uses 对json的操作   * @version $Id: json.php 376 2013.6.3 create jkj $  * @version $Id: json.php 385 2013.7.16 edit jkj $  */class Json{/** * 转换介质对象 * @var string */var $buf;/** * 存16进制unicode数组 * @var array */var $utf16;// =>var $SIGN = ':';// " key "var $quotes = '"';function __construct(){$this->buf = "";$this->utf16 = array();}/** * 对utf8对象进行json格式编码 * * @access public * @param mixed $value * @return string buf */public function encode( $value ){switch ( gettype( $value ) ){case IS_NULL:$this->__S( $buf, "null" );break;case IS_BOOL:$add = !empty( $value ) ? "true" : "false";$this->__S( $this->buf, $add );break;case IS_INT:                 $this->__S( $this->buf, (int)$value );                break;            case IS_DOUBLE:            $this->__S( $this->buf, (float)$value );                break;            case IS_STRING:            $this->_handle_string( $this->buf, $value );            break;            case IS_ARRAY:            $this->_handle_array( $this->buf, $value );            break;            case IS_OBJECT:            break;            default:            $this->__S( $this->buf, "null" );            break;}return $this->buf;}/** * 处理数组 * * @access private * @param string &$buf * @param array $data */private function _handle_array( &$buf, array $data ) {$count = count( $data );$pos   = 0;//$iskey = isset( $data[0] );$iskey = key($data);if( !$iskey ){$this->__S( $buf, '[' );} else {$this->__S( $buf, '{' );}foreach ( $data as $key=>$val ){if( $iskey ){$this->_handle_string( $buf, $key );$this->__S( $buf, $this->SIGN );}$this->encode( $val );if( $pos < $count-1 ) $this->__S( $buf, ',' );$pos++;}if( !$iskey ){$this->__S( $buf, ']' );} else {$this->__S( $buf, '}' );}}/** * 处理字符串 * * @access private * @param string &$buf * @param string $s */private function _handle_string( &$buf, $s ) {$digits = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');$len = strlen( $s );if( $len == 0 ) {$this->__S( $buf, "\"\"" );}$len = $this->utf8_to_utf16( $s );if( $len <= 0 ){if( $len < 0 ){$this->__S( $buf, "null" );} else {$this->__S( $buf, "\"\"" );}return ;}$this->__S( $buf, $this->quotes );if( is_numeric( $s ) ){// doubleif( strpos( $s, "." ) === false ){$this->__S( $buf, (int)$s );}else {$this->__S( $buf, (float)$s );}$len = 0;}$pos = 0;while ( $pos < $len ) {$us = $this->utf16[$pos++];   switch( $us )             {             case '"':                 $this->__S( $buf, "\\\"" );                    break;                case '\\':                     $this->__S( $buf, "\\\\" );                     break; case '/':                     $this->__S( $buf, "\\/" );                    break;                 case '\b':                     $this->__S( $buf, "\\b" );                     break;                 case '\f':                     $this->__S( $buf, "\\f" );                     break;                 case '\n':             $this->__S( $buf, "\\n" );                     break;                 case '\r':                     $this->__S( $buf, "\\r" );                     break;                 case '\t':                     $this->__S( $buf, "\\t" );                     break;                 case '<':                     $this->__S( $buf, '<' );                     break;                 case '>':                     $this->__S( $buf, '>' );                     break;                 case '&':                     $this->__S( $buf, '&' );                     break;                 case '\'':                      $this->__S( $buf, '\'' );                     break;                 default:                if ( $us >= ' ' && ( $us & 127 ) == $us ) {                     $this->__S( $buf, $us );                     } else {                         $this->__S( $buf, "\\u" );                        // 10进制转16进制$this->__S( $buf, $digits[($us & 0xf000) >> 12] );$this->__S( $buf, $digits[($us & 0xf00)  >> 8] );$this->__S( $buf, $digits[($us & 0xf0)   >> 4] );$this->__S( $buf, $digits[($us & 0xf)] );                }                break;        }}         $this->__S( $buf, $this->quotes );        if ( $this->utf16 ){        $this->utf16 = array();        }}function __S( &$buf, $val ) {if( NULL === $buf ) {$buf = $val;}$buf .= $val;} /** * 将utf8的unicode 转化成16进制的数组 * * @param string $s * @return int 数组的count */function utf8_to_utf16( $s ) {if( !$this->is_utf8( $s ) ){ return -1; }$pos = 0;$len = strlen( $s );for( ;$pos < $len; ){$ascii = ord( $s{$pos} );if($ascii > 128){$this->utf16[] = $this->_utf8_to_unicode( substr( $s, $pos, 3 ) );$pos += 3;}else {$this->utf16[] = $s{$pos};$pos += 1;}}return count( $this->utf16 );}/** * 将16进制的数组转化成带utf8字符 * * @param string $out_charset 返回的字符集编码,用于本地化和测试 * @return null|string str 带utf8字符 */function utf16_to_utf8( $out_charset='utf-8' ) {if( !$this->utf16 ){ return null; }$arr = array();foreach ( $this->utf16 as $utf16 ) {if( $utf16 > 0x80 || is_numeric( $utf16 ) ){$tmp = $this->_unicode_to_utf8( $utf16 );if( !$this->is_utf8( $tmp ) ) $arr[] = chr(0);else {if( strtolower( $out_charset ) != 'utf-8' ){$arr[] = iconv( 'utf-8', $out_charset, $tmp );}else $arr[] = $tmp;}}else {$arr[] = $utf16;}}return implode( "", $arr );}/** * utf8转Unicode 10进制 * * @param string $c * @return int $un unicode */function _utf8_to_unicode( $c ) {$un = 0;  switch( strlen( $c ) ) {     case 1:       $un = ord( $c );      break;    case 2:       $un = ( ord( $c[0] ) & 0x3f ) << 6;       $un += ord( $c[1] ) & 0x3f;       break;     case 3:       $un = ( ord( $c[0] ) & 0x1f ) << 12;       $un += ( ord( $c[1] ) & 0x3f ) << 6;       $un += ord( $c[2] ) & 0x3f;       break;     case 4:       $un = ( ord( $c[0] ) & 0x0f ) << 18;       $un += ( ord( $c[1] ) & 0x3f ) << 12;       $un += ( ord( $c[2] ) & 0x3f ) << 6;       $un += ord( $c[3] ) & 0x3f;       break;  }  return $un;}/** * 10进制unicode转utf8 * * @param int $un * @return string utf8编码字符 */function _unicode_to_utf8( $un ) {$c1 = 0; $c2 = 0;$c3 = 0; $c4 = 0;if( $un < 0x80 )$c1 = $un >> 0 & 0x7F | 0x00;elseif( $un < 0x0800 ){$c1 = $un >> 6 & 0x1F | 0xC0;$c2 = $un >> 0 & 0x3F | 0x80;}elseif( $un < 0x010000 ){$c1 = $un >> 12 & 0x0F | 0xE0;$c2 = $un >> 6 & 0x3F | 0x80;$c3 = $un >> 0 & 0x3F | 0x80;}elseif( $un < 0x110000 ){$c1 = $un >> 18 & 0x07 | 0xF0;$c2 = $un >> 12 & 0x3F | 0x80;$c3 = $un >> 6 & 0x3F | 0x80;$c4 = $un >> 0 & 0x3F | 0x80;}return chr( $c1 ).chr( $c2 ).chr( $c3 ).chr( $c4 );}/** * 是否是utf8编码字符串 * * @param string $str * @return bool */function is_utf8( $str ) {    $c = 0; $b = 0;    $bits = 0;    $len = strlen( $str );    for( $i = 0; $i < $len; $i++ ){        $c = ord( $str[$i] );        if( $c > 128 ){            if( $c >= 254 ) return false;            elseif( $c >= 252 ) $bits = 6;            elseif( $c >= 248 ) $bits = 5;            elseif( $c >= 240 ) $bits = 4;            elseif( $c >= 224 ) $bits = 3;            elseif( $c >= 192 ) $bits = 2;            else return false;            if( ( $i + $bits ) > $len ) return false;            while( $bits > 1 ){                $i++;                $b = ord( $str[$i] );                if( $b < 128 || $b > 191 ) return false;                $bits--;            }        }    }    return true;}/** * 对 JSON 格式的字符串进行解码 * * @access public * @param string $json * @param bool $assoc true:返回array; false:返回stdclass * @return mixed */public function decode( $json, $assoc=false ) {##############################################  Is interested to continue to write    #### use methods have already been written  ####        Began to write in here          ##############################################return $mixed;}}