3 // +--------------------------------------------------------------------+
4 // | PHP version 4 and 5 |
5 // +--------------------------------------------------------------------+
6 // | Copyright (c) 2006 Hawk |
7 // +--------------------------------------------------------------------+
8 // | This source file is subject to version 3.00 of the PHP License, |
9 // | that is available at http://www.php.net/license/3_0.txt. |
10 // | If you did not receive a copy of the PHP license and are unable to |
11 // | obtain it through the world-wide-web, please send a note to |
12 // | license@php.net so we can mail you a copy immediately. |
13 // +--------------------------------------------------------------------+
14 // | Authors: Hawk <scholar@hawklab.jp> |
15 // +--------------------------------------------------------------------+
20 * Converts to JSON format.
24 * //create a new instance of Jsphon_Encoder
25 * $json =& new Jsphon_Encoder();
27 * //convert a complex value to JSON notation, and send it to the browser
28 * $value = array('foo', 'bar', array('hoge' => array(1,2)));
29 * $output = $json->encode($value);
32 * //prints: ["foo","bar",{"hoge":[1,2]}]
49 var $_utf8overUCS2reg;
52 * constructs a new Jsphon_Encoder instance.
54 * @param bool $escapeNonASCII If true, encode() converts non-ASCII characters
55 * to Unicode escape sequence (\uXXXX).
56 * @param bool $escapeOverUCS2 If true, encode() converts all the non-ASCII characters
57 * that is encodable in UTF-16 to Unicode escape sequence.
58 * This parameter affects the encoder's behavior
59 * only if $escapeNonASCII is set to true and
60 * the multibyte string extension is available.
63 function Jsphon_Encoder($escapeNonASCII=true, $escapeOverUCS2=false)
65 $this->_escapeNonASCII = $escapeNonASCII;
66 $this->_escapeOverUCS2 = $escapeOverUCS2;
67 $this->_mbstring = extension_loaded('mbstring');
69 $this->_transTable = array(
80 $utf8ucs2 = '[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}';
81 $utf16sur = '[\xF0-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2}';
82 $this->_utf8UCS2reg = "/{$utf8ucs2}/";
83 $this->_utf8overUCS2reg = "/{$utf8ucs2}|{$utf16sur}/";
87 * encodes an arbitrary variables into JSON format.
89 * If $_escapeNonASCII is set to true,
90 * encode() removes all non-ASCII characters to make sure that
91 * returning value dosen't contain any non-ASCII characters.
96 function encode($value)
98 $json = $this->_encode($value);
99 if($this->_escapeNonASCII) {
100 $json = preg_replace('/[\x80-\xFF]/', '', $json);
105 function _encode($value)
107 if($value === null) {
110 } elseif(is_bool($value)) {
111 return $value ? 'true' : 'false';
113 } elseif(is_int($value)) {
116 } elseif(is_float($value)) {
117 return (float)$value;
119 } elseif(is_string($value)) {
120 return '"'. $this->_encodeString($value) .'"';
122 } elseif(is_array($value)) {
123 if(($len = count($value)) > 0 &&
124 array_keys($value) !== range(0, $len - 1)) {
125 return $this->_encodeObject($value);
127 return '['. join(',', array_map(array(&$this, '_encode'), $value)) .']';
130 } elseif(is_object($value)) {
131 return $this->_encodeObject($value);
138 function _encodeObject($arr)
141 foreach($arr as $name => $value) {
142 $result[] = $this->_encode((string)$name) .':'. $this->_encode($value);
144 return '{'. join(',', $result) ."}";
147 function _encodeString($str)
149 $str = strtr($str, $this->_transTable);
151 if(!$this->_escapeNonASCII) {
155 if(!$this->_mbstring) {
156 return $this->_escapeNonASCIIWithoutMbstring($str);
159 if($this->_escapeOverUCS2) {
160 return $this->_escapeNonASCIIOverUCS2($str);
162 return $this->_escapeNonASCII($str);
166 function _escapeNonASCII($str)
168 $transTable = array();
170 if(!preg_match_all($this->_utf8UCS2reg, $str, $matches)) {
174 foreach($matches[0] as $utf8char) {
175 if(isset($transTable[$utf8char])) {
178 $transTable[$utf8char] = $this->_formatSeq(
179 mb_convert_encoding($utf8char, 'UTF-16', 'UTF-8'));
181 return strtr($str, $transTable);
184 function _escapeNonASCIIOverUCS2($str)
186 $transTable = array();
188 if(!preg_match_all($this->_utf8overUCS2reg, $str, $matches)) {
192 foreach($matches[0] as $utf8char) {
193 if(isset($transTable[$utf8char])) {
196 $utf16char = mb_convert_encoding($utf8char, 'UTF-16', 'UTF-8');
198 if(($l = strlen($utf16char)) == 2) {
199 $transTable[$utf8char] = $this->_formatSeq($utf16char);
201 $transTable[$utf8char] =
202 $this->_formatSeq(substr($utf16char, 0, 2)) . $this->_formatSeq(substr($utf16char, 2));
206 return strtr($str, $transTable);
209 function _escapeNonASCIIWithoutMbstring($str)
211 $transTable = array();
213 if(!preg_match_all($this->_utf8UCS2reg, $str, $matches)) {
217 foreach($matches[0] as $utf8char) {
218 if(isset($transTable[$utf8char])) {
222 switch(strlen($utf8char)) {
225 ((ord($utf8char{0}) & 0x1F) << 6) |
226 (ord($utf8char{1}) & 0x3F)
232 ((ord($utf8char{0}) & 0x0F) << 12) |
233 ((ord($utf8char{1}) & 0x3F) << 6 ) |
234 (ord($utf8char{2}) & 0x3F)
239 $transTable[$utf8char] = '\u'. substr('0000'. dechex($code), -4);
241 return strtr($str, $transTable);
244 function _formatSeq($u16)
246 return '\u'. substr('0000'. bin2hex($u16), -4);