JSON格式编码操作类

【原创】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 ) ){
			// double
			if( 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;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值