This repository was archived by the owner on Feb 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathJSON.php
122 lines (110 loc) · 3.58 KB
/
JSON.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
/* THIS FILE:
* a) BELONGS TO THE 'PHP-UTIL' LIBRARY:
* https://github.com/thiagodp/php-util
*
* b) IS DISTRIBUTED UNDER THE CREATIVE COMMONS LICENCE (CC BY 3.0):
* http://creativecommons.org/licenses/by/3.0/
*
* USE IT AT YOUR OWN RISK!
*/
require_once 'RTTI.php'; // Uses RTTI::getPrivateAttributes
/**
* JSON utilities.
*
* @author Thiago Delgado Pinto
* @version 1.5.1
*/
class JSON {
private static $conversions = array();
/**
* Add a conversion for objects of a certain class.
* If the class name is already mapped, the function is overridden.
*
* @param [in] $className Class name.
* @param [in] $function Function that receives a value and returns a value.
*
* @details Example:
*
* addConversion( 'DateTime', function( $value ) {
* return $value->format( 'Y-m-d' );
* } );
*
*/
static function addConversion( $className, $function ) {
self::$conversions[ $className ] = $function;
}
/** @return bool */
static function hasConversion( $className ) {
return array_key_exists( $className, self::$conversions );
}
/**
* Remove a conversion for a certain class.
* @param [in] $className Class name.
*/
static function removeConversion( $className ) {
unset( self::$conversions[ $className ] );
}
/**
* Encode a data to JSON format.
*
* @param data the data to be serialized as JSON.
* @param getterPrefixForObjectMethods the prefix for getter methods (defaults to 'get').
* Ignore it for non object data.
* @return a string in JSON format.
*/
static function encode( $data, $getterPrefixForObjectMethods = 'get' ) {
$type = gettype( $data );
$isObject = false;
switch ( $type ) {
case 'string' : return '"' . self::correct( $data ) . '"';
case 'number' : ; // continue
case 'integer' : ; // continue
case 'float' : ; // continue
case 'double' : return $data;
case 'boolean' : return ( $data ) ? 'true' : 'false';
case 'NULL' : return 'null';
case 'object' : {
$className = get_class( $data );
if ( array_key_exists( $className, self::$conversions )
&& is_callable( self::$conversions[ $className ] ) ) {
$function = self::$conversions[ $className ];
$convertedValue = call_user_func( $function, $data );
return self::encode( $convertedValue );
}
//$data = RTTI::getPrivateAttributes( $data, $getterPrefixForObjectMethods );
$data = RTTI::getAttributes( $data, RTTI::anyVisibility(), $getterPrefixForObjectMethods );
$isObject = true;
// continue
}
case 'array' : {
$output = array();
foreach ( $data as $key => $value ) {
$encodedValue = self::encode( $value, $getterPrefixForObjectMethods );
if ( is_numeric( $key ) ) {
$output []= $encodedValue;
} else {
$encodedKey = self::encode( $key, $getterPrefixForObjectMethods );
$output []= $encodedKey . ' : ' . $encodedValue;
}
}
return $isObject ? '{ ' . implode( ', ', $output ) . ' }' : '[ ' . implode( ', ', $output ) . ' ]';
}
default: return ''; // Not supported type
}
}
/**
* Correct the string to be returned as JSON. This function is replacing addslashes that fails
* in convert \' to '. The javascript fails if a \' is found in a JSON string.
*
* @param str the string to be corrected.
* @return a corrected string.
*/
private static function correct( $str ) {
// I know that the parameters in str_replace could be an array but I think it is more
// readable to use this way.
$newStr = str_replace( '"', '\"', $str );
return str_replace( '\\\'', '\'', $newStr );
}
}
?>