fastjson php,veryLittlePHP/FastJSON.php at master · cake654326/veryLittlePHP · GitHub

FastJSON是一款用于PHP的快速JSON编码解码库,比Service_JSON快约两倍,支持ASCII范围0x00-0x1F转换及UTF-8编码。提供了静态公共方法进行JSON字符串与PHP变量之间的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**_______________________________________

*

* FastJSON (strict version for PHP 5.2 or greater),

*simple and fast Pear Service_JSON encoder/decoder alternative

*[http://pear.php.net/pepr/pepr-proposal-show.php?id=198]

* ---------------------------------------

* This class is about two time faster than Pear Service_JSON class.

* This class is probably not powerful as Service_JSON but it has

* no dependencies and converts correctly ASCII range 0x00 - 0x1F too.

* There's any string convertion, just regular RFC specific characters are converted

* into \u00XX string.

* To don't have problems with other chars try to use utf8_encode($json_encoded_string).

* To recieve correctly JSON strings from JavaScript use encodeURIComponent then

* use, if is necessary, utef8_decode before JS to PHP convertion.

* decode method doesn't returns a standard object class but You can

* create the corret class directly with FastJSON::convert method

* and with them You can manage JS Date objects too.

* ---------------------------------------

* Summary of static public methods

*

* convert

*extra, special method

*

*decode

*converts a valid JSON string

*into a native PHP variable

*

*encode

*converts a native php variable

*into a valid JSON string

* ---------------------------------------

*

* Special FastJSON::convert method Informations

* _______________________________________

* ---------------------------------------

* This method is used by FastJSON::encode method but should be used

* to do these convertions too:

*

* - JSON string to time() integer:

*

*FastJSON::convert(decodedDate:String):time()

*

*If You recieve a date string rappresentation You

*could convert into respective time() integer.

*Example:

*FastJSON::convert(FastJSON::decode($clienttime));

*// i.e. $clienttime = 2006-11-09T14:42:30

*// returned time will be an integer useful with gmdate or date

*// to create, for example, this string

* // Thu Nov 09 2006 14:42:30 GMT+0100 (Rome, Europe)

*

* - time() to JSON string:

*

*FastJSON::convert(time():Int32, true:Boolean):JSON Date String format

*

*You could send server time() informations and send them to clients.

*Example:

*FastJSON::convert(time(), true);

*// i.e. 2006-11-09T14:42:30

*

* - associative array to generic class:

*

*FastJSON::convert(array(params=>values), new GenericClass):new Instance of GenericClass

*

*With a decoded JSON object You could convert them

*into a new instance of your Generic Class.

*Example:

*class MyClass {

*var$param = "somevalue";

*function MyClass($somevar) {

*$this->somevar = $somevar;

*};

*function getVar = function(){

*return $this->somevar;

*};

*};

*

*$instance = new MyClass("example");

*$encoded = FastJSON::encode($instance);

*// {"param":"somevalue"}

*

*$decoded = FastJSON::decode($encoded);

*// $decoded instanceof Object=> true

*// $decoded instanceof MyClass=> false

*

*$decoded = FastJSON::convert($decoded, new MyClass("example"));

*// $decoded instanceof Object=> true

*// $decoded instanceof MyClass=> true

*

*$decoded->getVar(); // example

*

* ---------------------------------------

*

* @authorAndrea Giammarchi

* @sitehttp://www.devpro.it/

* @version0.4 [fixed string convertion problems, add stdClass optional convertion instead of associative array (used by default)]

* @requiresanything

* @compatibilityPHP >= 5

* @license

* ---------------------------------------

*

* Copyright (c) 2006 - 2007 Andrea Giammarchi

*

* Permission is hereby granted, free of charge,

* to any person obtaining a copy of this software and associated

* documentation files (the "Software"),

* to deal in the Software without restriction,

* including without limitation the rights to use, copy, modify, merge,

* publish, distribute, sublicense, and/or sell copies of the Software,

* and to permit persons to whom the Software is furnished to do so,

* subject to the following conditions:

*

* The above copyright notice and this permission notice shall be included

* in all copies or substantial portions of the Software.

*

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,

* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,

* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,

* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE

* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

* _______________________________________

*/

class FastJSON {

// public methods

/**

* public static method

*

*FastJSON::convert(params:* [, result:Instance]):*

*

* @param*String or Object

* @paramInstanceoptional new generic class instance if first

*parameter is an object.

* @return*time() value or new Instance with object parameters.

*

* @noteplease read Special FastJSON::convert method Informations

*/

static public function convert($params, $result = null){

switch(gettype($params)){

case'array':

$tmp = array();

foreach($params as $key => $value) {

if(($value = FastJSON::encode($value)) !== '')

array_push($tmp, FastJSON::encode(strval($key)).':'.$value);

};

$result = '{'.implode(',', $tmp).'}';

break;

case'boolean':

$result = $params ? 'true' : 'false';

break;

case'double':

case'float':

case'integer':

$result = $result !== null ? strftime('%Y-%m-%dT%H:%M:%S', $params) : strval($params);

break;

case'NULL':

$result = 'null';

break;

case'string':

$i = create_function('&$e, $p, $l', 'return intval(substr($e, $p, $l));');

if(preg_match('/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $params))

$result = mktime($i($params, 11, 2), $i($params, 14, 2), $i($params, 17, 2), $i($params, 5, 2), $i($params, 9, 2), $i($params, 0, 4));

break;

case'object':

$tmp = array();

if(is_object($result)) {

foreach($params as $key => $value)

$result->$key = $value;

} else {

$result = get_object_vars($params);

foreach($result as $key => $value) {

if(($value = FastJSON::encode($value)) !== '')

array_push($tmp, FastJSON::encode($key).':'.$value);

};

$result = '{'.implode(',', $tmp).'}';

}

break;

}

return $result;

}

/**

* public method

*

*FastJSON::decode(params:String[, useStdClass:Boolean]):*

*

* @paramStringvalid JSON encoded string

* @paramBoleanuses stdClass instead of associative array if params contains objects (default false)

* @return*converted variable or null

*is params is not a JSON compatible string.

* @noteThis method works in an optimist way. If JSON string is not valid

* the code execution will die using exit.

*This is probably not so good but JSON is often used combined with

*XMLHttpRequest then I suppose that's better more protection than

*just some WARNING.

*With every kind of valid JSON string the old error_reporting level

*and the old error_handler will be restored.

*

* @example

*FastJSON::decode('{"param":"value"}'); // associative array

*FastJSON::decode('{"param":"value"}', true); // stdClass

*FastJSON::decode('["one",two,true,false,null,{},[1,2]]'); // array

*/

static public function decode($encode, $stdClass = false){

$pos = 0;

$slen = is_string($encode) ? strlen($encode) : null;

if($slen !== null) {

$error = error_reporting(0);

set_error_handler(array('FastJSON', '__exit'));

$result = FastJSON::__decode($encode, $pos, $slen, $stdClass);

error_reporting($error);

restore_error_handler();

}

else

$result = null;

return $result;

}

/**

* public method

*

*FastJSON::encode(params:*):String

*

* @param*Array, Boolean, Float, Int, Object, String or NULL variable.

* @returnStringJSON genric object rappresentation

*or empty string if param is not compatible.

*

* @example

*FastJSON::encode(array(1,"two")); // '[1,"two"]'

*

*$obj = new MyClass();

*obj->param = "value";

*obj->param2 = "value2";

*FastJSON::encode(obj); // '{"param":"value","param2":"value2"}'

*/

static public function encode($decode){

$result = '';

switch(gettype($decode)){

case'array':

if(!count($decode) || array_keys($decode) === range(0, count($decode) - 1)) {

$keys = array();

foreach($decode as $value) {

if(($value = FastJSON::encode($value)) !== '')

array_push($keys, $value);

}

$result = '['.implode(',', $keys).']';

}

else

$result = FastJSON::convert($decode);

break;

case'string':

$replacement = FastJSON::__getStaticReplacement();

$result = '"'.str_replace($replacement['find'], $replacement['replace'], $decode).'"';

break;

default:

if(!is_callable($decode))

$result = FastJSON::convert($decode);

break;

}

return $result;

}

// 统计需要处理的字符以及处理成什么字符 (如 \、/、'、"、\r、\f, \n, \t, \b)

static private function __getStaticReplacement(){

static $replacement = array('find'=>array(), 'replace'=>array());

if($replacement['find'] == array()) {

foreach(array_merge(range(0, 7), array(11), range(14, 31)) as $v) {

$replacement['find'][] = chr($v);

$replacement['replace'][] = "\\u00".sprintf("%02x", $v);

}

$replacement['find'] = array_merge(array(chr(0x5c), chr(0x2F), chr(0x22), chr(0x0d), chr(0x0c), chr(0x0a), chr(0x09), chr(0x08)), $replacement['find']);

$replacement['replace'] = array_merge(array('\\\\', '\\/', '\\"', '\r', '\f', '\n', '\t', '\b'), $replacement['replace']);

}

return $replacement;

}

static private function __decode(&$encode, &$pos, &$slen, &$stdClass){

switch($encode{$pos}) {

case 't':

$result = true;

$pos += 4;

break;

case 'f':

$result = false;

$pos += 5;

break;

case 'n':

$result = null;

$pos += 4;

break;

case '[': // 普通的数组

$result = array();

++$pos;

while($encode{$pos} !== ']') {

array_push($result, FastJSON::__decode($encode, $pos, $slen, $stdClass));

if($encode{$pos} === ',')

++$pos;

}

++$pos;

break;

case '{': // 自定义下表的数组或者对象

$result = $stdClass ? new stdClass : array();

++$pos;

while($encode{$pos} !== '}') {

// 这里由于需要自己处理 key,双引号不能递归了让 case '"': 来处理的

// 所以 这里自己处理双引号

if($encode{$pos} === '"')

++$pos;

$tmp = FastJSON::__decodeString($encode, $pos);

$pos += 2; // 需要先跳过双引号,再跳过 赋值的 冒号

if($stdClass)

$result->$tmp = FastJSON::__decode($encode, $pos, $slen, $stdClass);

else

$result[$tmp] = FastJSON::__decode($encode, $pos, $slen, $stdClass);

if($encode{$pos} === ',')

++$pos;

}

++$pos;

break;

case '"':

switch($encode{++$pos}) {

case '"':

$result = "";

break;

default:

$result = FastJSON::__decodeString($encode, $pos);

break;

}

++$pos;

break;

default:

$tmp = '';

preg_replace('/^(\-)?([0-9]+)(\.[0-9]+)?([eE]\+[0-9]+)?/e', '$tmp = "\\1\\2\\3\\4"', substr($encode, $pos));

if($tmp !== '') {

$pos += strlen($tmp);

$nint = intval($tmp);

$nfloat = floatval($tmp);

$result = $nfloat == $nint ? $nint : $nfloat;

}

break;

}

return $result;

}

/**

* 处理字符串(将字符串中的特殊字符转义)

* @static

* @param $encode

* @param $pos

* @return mixed

*/

static private function __decodeString(&$encode, &$pos) {

$replacement = FastJSON::__getStaticReplacement(); // 收集诸如 \、/、'、"、\r、\f, \n, \t, \b 等所有需要用转义字符替换的特殊字符

$endString = FastJSON::__endString($encode, $pos, $pos); // 得到要处理字符串的长度

$result = str_replace($replacement['replace'], $replacement['find'], substr($encode, $pos, $endString)); // 将转义的字符还原

$pos += $endString; // 跳出处理的字符串

return $result; // 返回处理结果

}

/**

* 计算要处理的字符串的长度 (排除掉\" 的干扰)

* @static

* @param $encode 要处理的字符串

* @param $position [in] 开始处理的位置 | [out] 结束字符的位置

* @param $pos 开始处理的位置

* @return int 返回开始处理的位置 与 结束字符的位置 的距离

*/

static private function __endString(&$encode, $position, &$pos) {

do {

$position = strpos($encode, '"', $position + 1);

// 循环定位字符串的结束字符:", 使用 __slashedChar 是为了过滤掉 \"

}while($position !== false && FastJSON::__slashedChar($encode, $position - 1));

if($position === false)

trigger_error('', E_USER_WARNING);

return $position - $pos;

}

static private function __exit($str, $a, $b) {

exit($str . 'FATAL: FastJSON decode method failure [malicious or incorrect JSON string]');

}

/**

* 判断字符串中指定的字符是否已经被转义

* @static

* @param $encode 要检查的字符串

* @param $position 要检查的位置

* @return int 如果已经被完整转义返回0,否则返回1

*/

static private function __slashedChar(&$encode, $position) {

$pos = 0;

while($encode{$position--} === '\\')

$pos++; // 统计转义字符的数量

return $pos % 2; // 能被2正除说明该字符没有被转义,否则就已经被\转义了

}

}

?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值