system system.base system.caching system.caching.dependencies system.collections system.console system.db system.db.ar system.db.schema system.db.schema.cubrid system.db.schema.mssql system.db.schema.mysql system.db.schema.oci system.db.schema.pgsql system.db.schema.sqlite system.gii system.i18n system.i18n.gettext system.logging system.test system.utils system.validators system.web system.web.actions system.web.auth system.web.filters system.web.form system.web.helpers system.web.renderers system.web.services system.web.widgets system.web.widgets.captcha system.web.widgets.pagers zii.behaviors zii.widgets zii.widgets.grid zii.widgets.jui

CJSON

system.web.helpers
继承 class CJSON
可用自 1.0
源码 framework/web/helpers/CJSON.php
CJSON converts PHP data to and from JSON format.

公共方法

隐藏继承的方法

方法描述被定义在
decode() decodes a JSON string into appropriate variable CJSON
encode() Encodes an arbitrary variable into JSON format CJSON

受保护的方法

隐藏继承的方法

方法描述被定义在
nameValue() array-walking function for use in generating JSON-formatted name-value pairs CJSON
reduceString() reduce a string by removing leading and trailing comments and whitespace CJSON
unicodeToUTF8() This function converts a Unicode array back to its UTF-8 representation CJSON
utf16beToUTF8() UTF-8 to UTF-16BE conversion. CJSON
utf8ToUTF16BE() UTF-8 to UTF-16BE conversion. CJSON
utf8ToUnicode() This function returns any UTF-8 encoded text as a list of CJSON

方法详情

decode() 方法
public static mixed decode(string $str, boolean $useArray=true)
$str string JSON-formatted string
$useArray boolean whether to use associative array to represent object data
{return} mixed number, boolean, string, array, or object corresponding to given JSON input string. Note that decode() always returns strings in ASCII or UTF-8 format!
源码: framework/web/helpers/CJSON.php#331 (显示)
public static function decode($str$useArray=true)
{
    if(
function_exists('json_decode'))
    {
        
$json json_decode($str,$useArray);

        
// based on investigation, native fails sometimes returning null.
        // see: http://gggeek.altervista.org/sw/article_20070425.html
        // As of PHP 5.3.6 it still fails on some valid JSON strings
        
if($json !== null)
            return 
$json;
    }

    
$str self::reduceString($str);

    switch (
strtolower($str)) {
        case 
'true':
            return 
true;

        case 
'false':
            return 
false;

        case 
'null':
            return 
null;

        default:
            if (
is_numeric($str)) {
                
// Lookie-loo, it's a number

                // This would work on its own, but I'm trying to be
                // good about returning integers where appropriate:
                // return (float)$str;

                // Return float or int, as appropriate
                
return ((float)$str == (integer)$str)
                    ? (integer)
$str
                    
: (float)$str;

            } elseif (
preg_match('/^("|\').+(\1)$/s'$str$m) && $m[1] == $m[2]) {
                
// STRINGS RETURNED IN UTF-8 FORMAT
                
$delim substr($str01);
                
$chrs substr($str1, -1);
                
$utf8 '';
                
$strlen_chrs strlen($chrs);

                for (
$c 0$c $strlen_chrs; ++$c) {

                    
$substr_chrs_c_2 substr($chrs$c2);
                    
$ord_chrs_c ord($chrs{$c});

                    switch (
true) {
                        case 
$substr_chrs_c_2 == '\b':
                            
$utf8 .= chr(0x08);
                            ++
$c;
                            break;
                        case 
$substr_chrs_c_2 == '\t':
                            
$utf8 .= chr(0x09);
                            ++
$c;
                            break;
                        case 
$substr_chrs_c_2 == '\n':
                            
$utf8 .= chr(0x0A);
                            ++
$c;
                            break;
                        case 
$substr_chrs_c_2 == '\f':
                            
$utf8 .= chr(0x0C);
                            ++
$c;
                            break;
                        case 
$substr_chrs_c_2 == '\r':
                            
$utf8 .= chr(0x0D);
                            ++
$c;
                            break;

                        case 
$substr_chrs_c_2 == '\\"':
                        case 
$substr_chrs_c_2 == '\\\'':
                        case 
$substr_chrs_c_2 == '\\\\':
                        case 
$substr_chrs_c_2 == '\\/':
                            if ((
$delim == '"' && $substr_chrs_c_2 != '\\\'') ||
                               (
$delim == "'" && $substr_chrs_c_2 != '\\"')) {
                                
$utf8 .= $chrs{++$c};
                            }
                            break;

                        case 
preg_match('/\\\u[0-9A-F]{4}/i'substr($chrs$c6)):
                            
// single, escaped unicode character
                            
$utf16 chr(hexdec(substr($chrs, ($c+2), 2)))
                                   . 
chr(hexdec(substr($chrs, ($c+4), 2)));
                            
$utf8 .= self::utf16beToUTF8($utf16);
                            
$c+=5;
                            break;

                        case (
$ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
                            
$utf8 .= $chrs{$c};
                            break;

                        case (
$ord_chrs_c 0xE0) == 0xC0:
                            
// characters U-00000080 - U-000007FF, mask 110XXXXX
                            //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                            
$utf8 .= substr($chrs$c2);
                            ++
$c;
                            break;

                        case (
$ord_chrs_c 0xF0) == 0xE0:
                            
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                            
$utf8 .= substr($chrs$c3);
                            
$c += 2;
                            break;

                        case (
$ord_chrs_c 0xF8) == 0xF0:
                            
// characters U-00010000 - U-001FFFFF, mask 11110XXX
                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                            
$utf8 .= substr($chrs$c4);
                            
$c += 3;
                            break;

                        case (
$ord_chrs_c 0xFC) == 0xF8:
                            
// characters U-00200000 - U-03FFFFFF, mask 111110XX
                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                            
$utf8 .= substr($chrs$c5);
                            
$c += 4;
                            break;

                        case (
$ord_chrs_c 0xFE) == 0xFC:
                            
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
                            // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                            
$utf8 .= substr($chrs$c6);
                            
$c += 5;
                            break;

                    }

                }

                return 
$utf8;

            } elseif (
preg_match('/^\[.*\]$/s'$str) || preg_match('/^\{.*\}$/s'$str)) {
                
// array, or object notation

                
if ($str{0} == '[') {
                    
$stk = array(self::JSON_IN_ARR);
                    
$arr = array();
                } else {
                    if (
$useArray) {
                        
$stk = array(self::JSON_IN_OBJ);
                        
$obj = array();
                    } else {
                        
$stk = array(self::JSON_IN_OBJ);
                        
$obj = new stdClass();
                    }
                }

                
$stk[] = array('what' => self::JSON_SLICE'where' => 0'delim' => false);

                
$chrs substr($str1, -1);
                
$chrs self::reduceString($chrs);

                if (
$chrs == '') {
                    if (
reset($stk) == self::JSON_IN_ARR) {
                        return 
$arr;

                    } else {
                        return 
$obj;

                    }
                }

                
//print("\nparsing {$chrs}\n");

                
$strlen_chrs strlen($chrs);

                for (
$c 0$c <= $strlen_chrs; ++$c) {

                    
$top end($stk);
                    
$substr_chrs_c_2 substr($chrs$c2);

                    if ((
$c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) {
                        
// found a comma that is not inside a string, array, etc.,
                        // OR we've reached the end of the character list
                        
$slice substr($chrs$top['where'], ($c $top['where']));
                        
$stk[] = array('what' => self::JSON_SLICE'where' => ($c 1), 'delim' => false);
                        
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");

                        
if (reset($stk) == self::JSON_IN_ARR) {
                            
// we are in an array, so just push an element onto the stack
                            
$arr[] = self::decode($slice,$useArray);

                        } elseif (
reset($stk) == self::JSON_IN_OBJ) {
                            
// we are in an object, so figure
                            // out the property name and set an
                            // element in an associative array,
                            // for now
                            
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis'$slice$parts)) {
                                
// "name":value pair
                                
$key self::decode($parts[1],$useArray);
                                
$val self::decode($parts[2],$useArray);

                                if (
$useArray) {
                                    
$obj[$key] = $val;
                                } else {
                                    
$obj->$key $val;
                                }
                            } elseif (
preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis'$slice$parts)) {
                                
// name:value pair, where name is unquoted
                                
$key $parts[1];
                                
$val self::decode($parts[2],$useArray);

                                if (
$useArray) {
                                    
$obj[$key] = $val;
                                } else {
                                    
$obj->$key $val;
                                }
                            }

                        }

                    } elseif (((
$chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) {
                        
// found a quote, and we are not inside a string
                        
$stk[] = array('what' => self::JSON_IN_STR'where' => $c'delim' => $chrs{$c});
                        
//print("Found start of string at {$c}\n");

                    
} elseif (($chrs{$c} == $top['delim']) &&
                             (
$top['what'] == self::JSON_IN_STR) &&
                             ((
$chrs{$c 1} != "\\") ||
                             (
$chrs{$c 1} == "\\" && $chrs{$c 2} == "\\"))) {
                        
// found a quote, we're in a string, and it's not escaped
                        
array_pop($stk);
                        
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");

                    
} elseif (($chrs{$c} == '[') &&
                             
in_array($top['what'], array(self::JSON_SLICEself::JSON_IN_ARRself::JSON_IN_OBJ))) {
                        
// found a left-bracket, and we are in an array, object, or slice
                        
$stk[] = array('what' => self::JSON_IN_ARR'where' => $c'delim' => false);
                        
//print("Found start of array at {$c}\n");

                    
} elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) {
                        
// found a right-bracket, and we're in an array
                        
array_pop($stk);
                        
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");

                    
} elseif (($chrs{$c} == '{') &&
                             
in_array($top['what'], array(self::JSON_SLICEself::JSON_IN_ARRself::JSON_IN_OBJ))) {
                        
// found a left-brace, and we are in an array, object, or slice
                        
$stk[] = array('what' => self::JSON_IN_OBJ'where' => $c'delim' => false);
                        
//print("Found start of object at {$c}\n");

                    
} elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) {
                        
// found a right-brace, and we're in an object
                        
array_pop($stk);
                        
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");

                    
} elseif (($substr_chrs_c_2 == '/*') &&
                             
in_array($top['what'], array(self::JSON_SLICEself::JSON_IN_ARRself::JSON_IN_OBJ))) {
                        
// found a comment start, and we are in an array, object, or slice
                        
$stk[] = array('what' => self::JSON_IN_CMT'where' => $c'delim' => false);
                        
$c++;
                        
//print("Found start of comment at {$c}\n");

                    
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) {
                        
// found a comment end, and we're in one now
                        
array_pop($stk);
                        
$c++;

                        for (
$i $top['where']; $i <= $c; ++$i)
                            
$chrs substr_replace($chrs' '$i1);

                        
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");

                    
}

                }

                if (
reset($stk) == self::JSON_IN_ARR) {
                    return 
$arr;

                } elseif (
reset($stk) == self::JSON_IN_OBJ) {
                    return 
$obj;

                }

            }
    }
}

decodes a JSON string into appropriate variable

encode() 方法
public static string encode(mixed $var)
$var mixed any number, boolean, string, array, or object to be encoded. If var is a string, it will be converted to UTF-8 format first before being encoded.
{return} string JSON string representation of input var
源码: framework/web/helpers/CJSON.php#95 (显示)
public static function encode($var)
{
    switch (
gettype($var)) {
        case 
'boolean':
            return 
$var 'true' 'false';

        case 
'NULL':
            return 
'null';

        case 
'integer':
            return (int) 
$var;

        case 
'double':
        case 
'float':
            return 
str_replace(',','.',(float)$var); // locale-independent representation

        
case 'string':
            if ((
$enc=strtoupper(Yii::app()->charset))!=='UTF-8')
                
$var=iconv($enc'UTF-8'$var);

            if(
function_exists('json_encode'))
                return 
json_encode($var);

            
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
            
$ascii '';
            
$strlen_var strlen($var);

           
/*
            * Iterate over every character in the string,
            * escaping with a slash or encoding to UTF-8 where necessary
            */
            
for ($c 0$c $strlen_var; ++$c) {

                
$ord_var_c ord($var{$c});

                switch (
true) {
                    case 
$ord_var_c == 0x08:
                        
$ascii .= '\b';
                        break;
                    case 
$ord_var_c == 0x09:
                        
$ascii .= '\t';
                        break;
                    case 
$ord_var_c == 0x0A:
                        
$ascii .= '\n';
                        break;
                    case 
$ord_var_c == 0x0C:
                        
$ascii .= '\f';
                        break;
                    case 
$ord_var_c == 0x0D:
                        
$ascii .= '\r';
                        break;

                    case 
$ord_var_c == 0x22:
                    case 
$ord_var_c == 0x2F:
                    case 
$ord_var_c == 0x5C:
                        
// double quote, slash, slosh
                        
$ascii .= '\\'.$var{$c};
                        break;

                    case ((
$ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
                        
// characters U-00000000 - U-0000007F (same as ASCII)
                        
$ascii .= $var{$c};
                        break;

                    case ((
$ord_var_c 0xE0) == 0xC0):
                        
// characters U-00000080 - U-000007FF, mask 110XXXXX
                        // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                        
$char pack('C*'$ord_var_cord($var{$c+1}));
                        
$c+=1;
                        
$utf16 =  self::utf8ToUTF16BE($char);
                        
$ascii .= sprintf('\u%04s'bin2hex($utf16));
                        break;

                    case ((
$ord_var_c 0xF0) == 0xE0):
                        
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
                        // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                        
$char pack('C*'$ord_var_c,
                                     
ord($var{$c+1}),
                                     
ord($var{$c+2}));
                        
$c+=2;
                        
$utf16 self::utf8ToUTF16BE($char);
                        
$ascii .= sprintf('\u%04s'bin2hex($utf16));
                        break;

                    case ((
$ord_var_c 0xF8) == 0xF0):
                        
// characters U-00010000 - U-001FFFFF, mask 11110XXX
                        // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                        
$char pack('C*'$ord_var_c,
                                     
ord($var{$c+1}),
                                     
ord($var{$c+2}),
                                     
ord($var{$c+3}));
                        
$c+=3;
                        
$utf16 self::utf8ToUTF16BE($char);
                        
$ascii .= sprintf('\u%04s'bin2hex($utf16));
                        break;

                    case ((
$ord_var_c 0xFC) == 0xF8):
                        
// characters U-00200000 - U-03FFFFFF, mask 111110XX
                        // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                        
$char pack('C*'$ord_var_c,
                                     
ord($var{$c+1}),
                                     
ord($var{$c+2}),
                                     
ord($var{$c+3}),
                                     
ord($var{$c+4}));
                        
$c+=4;
                        
$utf16 self::utf8ToUTF16BE($char);
                        
$ascii .= sprintf('\u%04s'bin2hex($utf16));
                        break;

                    case ((
$ord_var_c 0xFE) == 0xFC):
                        
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
                        // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
                        
$char pack('C*'$ord_var_c,
                                     
ord($var{$c+1}),
                                     
ord($var{$c+2}),
                                     
ord($var{$c+3}),
                                     
ord($var{$c+4}),
                                     
ord($var{$c+5}));
                        
$c+=5;
                        
$utf16 self::utf8ToUTF16BE($char);
                        
$ascii .= sprintf('\u%04s'bin2hex($utf16));
                        break;
                }
            }

            return 
'"'.$ascii.'"';

        case 
'array':
           
/*
            * As per JSON spec if any array key is not an integer
            * we must treat the the whole array as an object. We
            * also try to catch a sparsely populated associative
            * array with numeric keys here because some JS engines
            * will create an array with empty indexes up to
            * max_index which can cause memory issues and because
            * the keys, which may be relevant, will be remapped
            * otherwise.
            *
            * As per the ECMA and JSON specification an object may
            * have any string as a property. Unfortunately due to
            * a hole in the ECMA specification if the key is a
            * ECMA reserved word or starts with a digit the
            * parameter is only accessible using ECMAScript's
            * bracket notation.
            */

            // treat as a JSON object
            
if (is_array($var) && count($var) && (array_keys($var) !== range(0sizeof($var) - 1))) {
                return 
'{' .
                       
join(','array_map(array('CJSON''nameValue'),
                                           
array_keys($var),
                                           
array_values($var)))
                       . 
'}';
            }

            
// treat it like a regular array
            
return '[' join(','array_map(array('CJSON''encode'), $var)) . ']';

        case 
'object':
            
// Check for the JsonSerializable interface available in PHP5.4
            // Note that instanceof returns false in case it doesnt know the interface.
            
if (interface_exists('JsonSerializable'false) && $var instanceof JsonSerializable)
            {
                
// We use the function defined in the interface instead of json_encode.
                // This way even for PHP < 5.4 one could define the interface and use it.
                
return self::encode($var->jsonSerialize());
            }
            elseif (
$var instanceof Traversable)
            {
                
$vars = array();
                foreach (
$var as $k=>$v)
                    
$vars[$k] = $v;
            }
            else
                
$vars get_object_vars($var);
            return 
'{' .
                   
join(','array_map(array('CJSON''nameValue'),
                                       
array_keys($vars),
                                       
array_values($vars)))
                   . 
'}';

        default:
            return 
'';
    }
}

Encodes an arbitrary variable into JSON format

nameValue() 方法
protected static string nameValue(string $name, mixed $value)
$name string name of key to use
$value mixed reference to an array element to be encoded
{return} string JSON-formatted name-value pair, like '"name":value'
源码: framework/web/helpers/CJSON.php#290 (显示)
protected static function nameValue($name$value)
{
    return 
self::encode(strval($name)) . ':' self::encode($value);
}

array-walking function for use in generating JSON-formatted name-value pairs

reduceString() 方法
protected static string reduceString(string $str)
$str string string value to strip of comments and whitespace
{return} string string value stripped of comments and whitespace
源码: framework/web/helpers/CJSON.php#303 (显示)
protected static function reduceString($str)
{
    
$str preg_replace(array(

            
// eliminate single line comments in '// ...' form
            
'#^\s*//(.+)$#m',

            
// eliminate multi-line comments in '/* ... */' form, at start of string
            
'#^\s*/\*(.+)\*/#Us',

            
// eliminate multi-line comments in '/* ... */' form, at end of string
            
'#/\*(.+)\*/\s*$#Us'

        
), ''$str);

    
// eliminate extraneous space
    
return trim($str);
}

reduce a string by removing leading and trailing comments and whitespace

unicodeToUTF8() 方法
protected static string unicodeToUTF8(string &$str)
$str string string to convert
{return} string
源码: framework/web/helpers/CJSON.php#661 (显示)
protected static function unicodeToUTF8( &$str )
{
    
$utf8 '';
    foreach( 
$str as $unicode )
    {
        if ( 
$unicode 128 )
        {
            
$utf8.= chr$unicode );
        }
        elseif ( 
$unicode 2048 )
        {
            
$utf8.= chr192 +  ( ( $unicode - ( $unicode 64 ) ) / 64 ) );
            
$utf8.= chr128 + ( $unicode 64 ) );
        }
        else
        {
            
$utf8.= chr224 + ( ( $unicode - ( $unicode 4096 ) ) / 4096 ) );
            
$utf8.= chr128 + ( ( ( $unicode 4096 ) - ( $unicode 64 ) ) / 64 ) );
            
$utf8.= chr128 + ( $unicode 64 ) );
        }
    }
    return 
$utf8;
}

This function converts a Unicode array back to its UTF-8 representation

utf16beToUTF8() 方法
protected static string utf16beToUTF8(string &$str)
$str string string to convert
{return} string
源码: framework/web/helpers/CJSON.php#712 (显示)
protected static function utf16beToUTF8(&$str)
{
    
$uni unpack('n*',$str);
    return 
self::unicodeToUTF8($uni);
}

UTF-8 to UTF-16BE conversion.

Maybe really UCS-2 without mb_string due to utf8ToUnicode limits

utf8ToUTF16BE() 方法
protected static string utf8ToUTF16BE(string &$str, boolean $bom=false)
$str string string to convert
$bom boolean whether to output BOM header
{return} string
源码: framework/web/helpers/CJSON.php#693 (显示)
protected static function utf8ToUTF16BE(&$str$bom false)
{
    
$out $bom "\xFE\xFF" '';
    if(
function_exists('mb_convert_encoding'))
        return 
$out.mb_convert_encoding($str,'UTF-16BE','UTF-8');

    
$uni self::utf8ToUnicode($str);
    foreach(
$uni as $cp)
        
$out .= pack('n',$cp);
    return 
$out;
}

UTF-8 to UTF-16BE conversion.

Maybe really UCS-2 without mb_string due to utf8ToUnicode limits

utf8ToUnicode() 方法
protected static string utf8ToUnicode(string &$str)
$str string string to convert
{return} string
源码: framework/web/helpers/CJSON.php#623 (显示)
protected static function utf8ToUnicode( &$str )
{
    
$unicode = array();
    
$values = array();
    
$lookingFor 1;

    for (
$i 0$i strlen$str ); $i++ )
    {
        
$thisValue ord$str$i ] );
        if ( 
$thisValue 128 )
            
$unicode[] = $thisValue;
        else
        {
            if ( 
count$values ) == )
                
$lookingFor = ( $thisValue 224 ) ? 3;
            
$values[] = $thisValue;
            if ( 
count$values ) == $lookingFor )
            {
                
$number = ( $lookingFor == ) ?
                    ( ( 
$values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ):
                    ( ( 
$values[0] % 32 ) * 64 ) + ( $values[1] % 64 );
                
$unicode[] = $number;
                
$values = array();
                
$lookingFor 1;
            }
        }
    }
    return 
$unicode;
}

This function returns any UTF-8 encoded text as a list of Unicode values: