CJSON

优质
小牛编辑
133浏览
2023-12-01
所有包 | 方法
system.web.helpers
继承class CJSON
源自1.0
版本$Id: CJSON.php 3204 2011-05-05 21:36:32Z alexander.makarow $
源码framework/web/helpers/CJSON.php
CJSON用于转换PHP数据到JSON格式基从JSON格式转换为PHP数据。

公共方法

隐藏继承方法

方法描述定义在
decode()解码一个JSON字符串为一个适当的变量CJSON
encode()把一个任意的变量编码成JSON格式CJSON

受保护方法

隐藏继承方法

方法描述定义在
nameValue()array-walking 功能用于产生JSON格式的名称-值对CJSON
reduceString()减少一个字符串,删除开头和结尾的注释和空白CJSON
unicodeToUTF8()这个方法将一个Unicode编码的数所转换成相对应的utf-8编码的数据CJSON
utf16beToUTF8()UTF-16BE转换为UTF-8。CJSON
utf8ToUTF16BE()UTF-8转换为UTF-16BE。CJSON
utf8ToUnicode()这个方法将一个utf-8编码的数所转换成CJSON

方法详细

decode() 方法
public static mixed decode(string $str, boolean $useArray=true)
$strstringJSON-格式的字符串
$useArrayboolean是否用联合数组来代替对象数据
{return}mixed给定的JSON字符串相对应的数字, 布尔值, 字符串, 数组, 或对象。 注意decode()总是返回ASCII或UTF-8格式的字符串。
源码: framework/web/helpers/CJSON.php#324 (显示) publicstaticfunctiondecode($str,$useArray=true)
{
if(function_exists('json_decode'))
returnjson_decode($str,$useArray);

$str=self::reduceString($str);

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

case'false':
returnfalse;

case'null':
returnnull;

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

//Thiswouldworkonitsown,butI'mtryingtobe
//goodaboutreturningintegerswhereappropriate:
//return(float)$str;

//Returnfloatorint,asappropriate
return((float)$str==(integer)$str)
?(integer)$str
:(float)$str;

}elseif(preg_match('/^("|').+(1)$/s',$str,$m)&&$m[1]==$m[2]){
//STRINGSRETURNEDINUTF-8FORMAT
$delim=substr($str,0,1);
$chrs=substr($str,1,-1);
$utf8='';
$strlen_chrs=strlen($chrs);

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

$substr_chrs_c_2=substr($chrs,$c,2);
$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;

casepreg_match('/\u[0-9A-F]{4}/i',substr($chrs,$c,6)):
//single,escapedunicodecharacter
$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:
//charactersU-00000080-U-000007FF,mask110XXXXX
//seehttp://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8.=substr($chrs,$c,2);
++$c;
break;

case($ord_chrs_c&0xF0)==0xE0:
//charactersU-00000800-U-0000FFFF,mask1110XXXX
//seehttp://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8.=substr($chrs,$c,3);
$c+=2;
break;

case($ord_chrs_c&0xF8)==0xF0:
//charactersU-00010000-U-001FFFFF,mask11110XXX
//seehttp://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8.=substr($chrs,$c,4);
$c+=3;
break;

case($ord_chrs_c&0xFC)==0xF8:
//charactersU-00200000-U-03FFFFFF,mask111110XX
//seehttp://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8.=substr($chrs,$c,5);
$c+=4;
break;

case($ord_chrs_c&0xFE)==0xFC:
//charactersU-04000000-U-7FFFFFFF,mask1111110X
//seehttp://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$utf8.=substr($chrs,$c,6);
$c+=5;
break;

}

}

return$utf8;

}elseif(preg_match('/^[.*]$/s',$str)||preg_match('/^{.*}$/s',$str)){
//array,orobjectnotation

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=newstdClass();
}
}

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

$chrs=substr($str,1,-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,$c,2);

if(($c==$strlen_chrs)||(($chrs{$c}==',')&&($top['what']==self::JSON_SLICE))){
//foundacommathatisnotinsideastring,array,etc.,
//ORwe'vereachedtheendofthecharacterlist
$slice=substr($chrs,$top['where'],($c-$top['where']));
array_push($stk,array('what'=>self::JSON_SLICE,'where'=>($c+1),'delim'=>false));
//print("Foundsplitat{$c}:".substr($chrs,$top['where'],(1+$c-$top['where']))."n");

if(reset($stk)==self::JSON_IN_ARR){
//weareinanarray,sojustpushanelementontothestack
array_push($arr,self::decode($slice,$useArray));

}elseif(reset($stk)==self::JSON_IN_OBJ){
//weareinanobject,sofigure
//outthepropertynameandsetan
//elementinanassociativearray,
//fornow
if(preg_match('/^s*(["'].*[^\]["'])s*:s*(S.*),?$/Uis',$slice,$parts)){
//"name":valuepair
$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:valuepair,wherenameisunquoted
$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)){
//foundaquote,andwearenotinsideastring
array_push($stk,array('what'=>self::JSON_IN_STR,'where'=>$c,'delim'=>$chrs{$c}));
//print("Foundstartofstringat{$c}n");

}elseif(($chrs{$c}==$top['delim'])&&
($top['what']==self::JSON_IN_STR)&&
(($chrs{$c-1}!="\")||
($chrs{$c-1}=="\"&&$chrs{$c-2}=="\"))){
//foundaquote,we'reinastring,andit'snotescaped
array_pop($stk);
//print("Foundendofstringat{$c}:".substr($chrs,$top['where'],(1+1+$c-$top['where']))."n");

}elseif(($chrs{$c}=='[')&&
in_array($top['what'],array(self::JSON_SLICE,self::JSON_IN_ARR,self::JSON_IN_OBJ))){
//foundaleft-bracket,andweareinanarray,object,orslice
array_push($stk,array('what'=>self::JSON_IN_ARR,'where'=>$c,'delim'=>false));
//print("Foundstartofarrayat{$c}n");

}elseif(($chrs{$c}==']')&&($top['what']==self::JSON_IN_ARR)){
//foundaright-bracket,andwe'reinanarray
array_pop($stk);
//print("Foundendofarrayat{$c}:".substr($chrs,$top['where'],(1+$c-$top['where']))."n");

}elseif(($chrs{$c}=='{')&&
in_array($top['what'],array(self::JSON_SLICE,self::JSON_IN_ARR,self::JSON_IN_OBJ))){
//foundaleft-brace,andweareinanarray,object,orslice
array_push($stk,array('what'=>self::JSON_IN_OBJ,'where'=>$c,'delim'=>false));
//print("Foundstartofobjectat{$c}n");

}elseif(($chrs{$c}=='}')&&($top['what']==self::JSON_IN_OBJ)){
//foundaright-brace,andwe'reinanobject
array_pop($stk);
//print("Foundendofobjectat{$c}:".substr($chrs,$top['where'],(1+$c-$top['where']))."n");

}elseif(($substr_chrs_c_2=='/*')&&
in_array($top['what'],array(self::JSON_SLICE,self::JSON_IN_ARR,self::JSON_IN_OBJ))){
//foundacommentstart,andweareinanarray,object,orslice
array_push($stk,array('what'=>self::JSON_IN_CMT,'where'=>$c,'delim'=>false));
$c++;
//print("Foundstartofcommentat{$c}n");

}elseif(($substr_chrs_c_2=='*/')&&($top['what']==self::JSON_IN_CMT)){
//foundacommentend,andwe'reinonenow
array_pop($stk);
$c++;

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

//print("Foundendofcommentat{$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;

}

}
}
}

解码一个JSON字符串为一个适当的变量

encode() 方法
public static string encode(mixed $var)
$varmixed任意的数字类型,布尔型,字符串,数组或对象都将被编码。 如果$var是一个字符串,在编码前它将首先被转换为UTF-8格式。
{return}string代表输入变量的JSON字符串。
源码: framework/web/helpers/CJSON.php#96 (显示) publicstaticfunctionencode($var)
{
switch(gettype($var)){
case'boolean':
return$var?'true':'false';

case'NULL':
return'null';

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

case'double':
case'float':
returnstr_replace(',','.',(float)$var);//locale-independentrepresentation

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

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

//STRINGSAREEXPECTEDTOBEINASCIIORUTF-8FORMAT
$ascii='';
$strlen_var=strlen($var);

/*
*Iterateovereverycharacterinthestring,
*escapingwithaslashorencodingtoUTF-8wherenecessary
*/
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:
//doublequote,slash,slosh
$ascii.='\'.$var{$c};
break;

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

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

case(($ord_var_c&0xF0)==0xE0):
//charactersU-00000800-U-0000FFFF,mask1110XXXX
//seehttp://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):
//charactersU-00010000-U-001FFFFF,mask11110XXX
//seehttp://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):
//charactersU-00200000-U-03FFFFFF,mask111110XX
//seehttp://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):
//charactersU-04000000-U-7FFFFFFF,mask1111110X
//seehttp://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':
/*
*AsperJSONspecifanyarraykeyisnotaninteger
*wemusttreatthethewholearrayasanobject.We
*alsotrytocatchasparselypopulatedassociative
*arraywithnumerickeysherebecausesomeJSengines
*willcreateanarraywithemptyindexesupto
*max_indexwhichcancausememoryissuesandbecause
*thekeys,whichmayberelevant,willberemapped
*otherwise.
*
*AspertheECMAandJSONspecificationanobjectmay
*haveanystringasaproperty.Unfortunatelydueto
*aholeintheECMAspecificationifthekeyisa
*ECMAreservedwordorstartswithadigitthe
*parameterisonlyaccessibleusingECMAScript's
*bracketnotation.
*/

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

//treatitlikearegulararray
return'['.join(',',array_map(array('CJSON','encode'),$var)).']';

case'object':
if($varinstanceofTraversable)
{
$vars=array();
foreach($varas$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'';
}
}

把一个任意的变量编码成JSON格式

nameValue() 方法
protected static string nameValue(string $name, mixed $value)
$namestring要使用的键的名称
$valuemixed要编码的数组元素
{return}stringJSON-格式 名称-值 对, 比如'"name":value'
源码: framework/web/helpers/CJSON.php#283 (显示) protectedstaticfunctionnameValue($name,$value)
{
returnself::encode(strval($name)).':'.self::encode($value);
}

array-walking 功能用于产生JSON格式的名称-值对

reduceString() 方法
protected static string reduceString(string $str)
$strstring字符串剥离的注释和空白
{return}string剥离注释和空白的的字符串
源码: framework/web/helpers/CJSON.php#296 (显示) protectedstaticfunctionreduceString($str)
{
$str=preg_replace(array(

//eliminatesinglelinecommentsin'//...'form
'#^s*//(.+)$#m',

//eliminatemulti-linecommentsin'/*...*/'form,atstartofstring
'#^s*/*(.+)*/#Us',

//eliminatemulti-linecommentsin'/*...*/'form,atendofstring
'#/*(.+)*/s*$#Us'

),'',$str);

//eliminateextraneousspace
returntrim($str);
}

减少一个字符串,删除开头和结尾的注释和空白

unicodeToUTF8() 方法
protected static string unicodeToUTF8(string &$str)
$strstring要转换的数据
{return}string
源码: framework/web/helpers/CJSON.php#648 (显示) protectedstaticfunctionunicodeToUTF8(&$str)
{
$utf8='';
foreach($stras$unicode)
{
if($unicode<128)
{
$utf8.=chr($unicode);
}
elseif($unicode<2048)
{
$utf8.=chr(192+(($unicode-($unicode%64))/64));
$utf8.=chr(128+($unicode%64));
}
else
{
$utf8.=chr(224+(($unicode-($unicode%4096))/4096));
$utf8.=chr(128+((($unicode%4096)-($unicode%64))/64));
$utf8.=chr(128+($unicode%64));
}
}
return$utf8;
}

这个方法将一个Unicode编码的数所转换成相对应的utf-8编码的数据

参见

  • utf8ToUnicode()
utf16beToUTF8() 方法
protected static string utf16beToUTF8(string &$str)
$strstringstring to convert
{return}string
源码: framework/web/helpers/CJSON.php#699 (显示) protectedstaticfunctionutf16beToUTF8(&$str)
{
$uni=unpack('n*',$str);
returnself::unicodeToUTF8($uni);
}

UTF-16BE转换为UTF-8。

也许实际上不带mb_string的UCS-2应归于utf8ToUnicode限制

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

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

UTF-8转换为UTF-16BE。

也许实际上不带mb_string的UCS-2应归于utf8ToUnicode限制

utf8ToUnicode() 方法
protected static string utf8ToUnicode(string &$str)
$strstring要转换的字符串
{return}string
源码: framework/web/helpers/CJSON.php#610 (显示) protectedstaticfunctionutf8ToUnicode(&$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)==0)
$lookingFor=($thisValue<224)?2:3;
$values[]=$thisValue;
if(count($values)==$lookingFor)
{
$number=($lookingFor==3)?
(($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;
}

这个方法将一个utf-8编码的数所转换成 相对应的Unicode编码的数据

参见

  • unicodeToUTF8()