[ Index ] |
|
Code source de PRADO 3.0.6 |
1 <?php 2 /** 3 * Converts to and from JSON format. 4 * 5 * JSON (JavaScript Object Notation) is a lightweight data-interchange 6 * format. It is easy for humans to read and write. It is easy for machines 7 * to parse and generate. It is based on a subset of the JavaScript 8 * Programming Language, Standard ECMA-262 3rd Edition - December 1999. 9 * This feature can also be found in Python. JSON is a text format that is 10 * completely language independent but uses conventions that are familiar 11 * to programmers of the C-family of languages, including C, C++, C#, Java, 12 * JavaScript, Perl, TCL, and many others. These properties make JSON an 13 * ideal data-interchange language. 14 * 15 * This package provides a simple encoder and decoder for JSON notation. It 16 * is intended for use with client-side Javascript applications that make 17 * use of HTTPRequest to perform server communication functions - data can 18 * be encoded into JSON notation for use in a client-side javascript, or 19 * decoded from incoming Javascript requests. JSON format is native to 20 * Javascript, and can be directly eval()'ed with no further parsing 21 * overhead 22 * 23 * All strings should be in ASCII or UTF-8 format! 24 * 25 * PHP versions 4 and 5 26 * 27 * LICENSE: Redistribution and use in source and binary forms, with or 28 * without modification, are permitted provided that the following 29 * conditions are met: Redistributions of source code must retain the 30 * above copyright notice, this list of conditions and the following 31 * disclaimer. Redistributions in binary form must reproduce the above 32 * copyright notice, this list of conditions and the following disclaimer 33 * in the documentation and/or other materials provided with the 34 * distribution. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 38 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 39 * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 41 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 42 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 45 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 46 * DAMAGE. 47 * 48 * @package System.Web.Javascripts 49 * @author Michal Migurski <mike-json@teczno.com> 50 * @author Matt Knapp <mdknapp[at]gmail[dot]com> 51 * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com> 52 * @copyright 2005 Michal Migurski 53 * @license http://www.opensource.org/licenses/bsd-license.php 54 * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 55 */ 56 57 /** 58 * Converts to and from JSON format. 59 * 60 * @package System.Web.Javascripts 61 * @author Michal Migurski <mike-json@teczno.com> 62 * @author Matt Knapp <mdknapp[at]gmail[dot]com> 63 * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com> 64 * @copyright 2005 Michal Migurski 65 * @license http://www.php.net/license/3_0.txt PHP License 3.0 66 */ 67 class TJSON 68 { 69 /** 70 * Marker constant for JSON::decode(), used to flag stack state 71 */ 72 const JSON_SLICE = 1; 73 74 /** 75 * Marker constant for JSON::decode(), used to flag stack state 76 */ 77 const JSON_IN_STR = 2; 78 79 /** 80 * Marker constant for JSON::decode(), used to flag stack state 81 */ 82 const JSON_IN_ARR = 4; 83 84 /** 85 * Marker constant for JSON::decode(), used to flag stack state 86 */ 87 const JSON_IN_OBJ = 8; 88 89 /** 90 * Marker constant for JSON::decode(), used to flag stack state 91 */ 92 const JSON_IN_CMT = 16; 93 94 /** 95 * Behavior switch for JSON::decode() 96 */ 97 const JSON_LOOSE_TYPE = 10; 98 99 /** 100 * Behavior switch for JSON::decode() 101 */ 102 const JSON_STRICT_TYPE = 11; 103 104 /** 105 * constructs a new JSON instance 106 * 107 * @param int $use object behavior: when encoding or decoding, 108 * be loose or strict about object/array usage 109 * 110 * possible values: 111 * self::JSON_STRICT_TYPE - strict typing, default 112 * "{...}" syntax creates objects in decode. 113 * self::JSON_LOOSE_TYPE - loose typing 114 * "{...}" syntax creates associative arrays in decode. 115 */ 116 public function __construct($use=self::JSON_STRICT_TYPE) 117 { 118 $this->use = $use; 119 } 120 121 /** 122 * encodes an arbitrary variable into JSON format 123 * 124 * @param mixed $var any number, boolean, string, array, or object to be encoded. 125 * see argument 1 to JSON() above for array-parsing behavior. 126 * if var is a strng, note that encode() always expects it 127 * to be in ASCII or UTF-8 format! 128 * 129 * @return string JSON string representation of input var 130 * @access public 131 */ 132 public function encode($var) 133 { 134 switch (gettype($var)) { 135 case 'boolean': 136 return $var ? 'true' : 'false'; 137 138 case 'NULL': 139 return 'null'; 140 141 case 'integer': 142 return (int) $var; 143 144 case 'double': 145 case 'float': 146 return (float) $var; 147 148 case 'string': 149 // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT 150 $ascii = ''; 151 $strlen_var = strlen($var); 152 153 /* 154 * Iterate over every character in the string, 155 * escaping with a slash or encoding to UTF-8 where necessary 156 */ 157 for ($c = 0; $c < $strlen_var; ++$c) { 158 159 $ord_var_c = ord($var{$c}); 160 161 switch (true) { 162 case $ord_var_c == 0x08: 163 $ascii .= '\b'; 164 break; 165 case $ord_var_c == 0x09: 166 $ascii .= '\t'; 167 break; 168 case $ord_var_c == 0x0A: 169 $ascii .= '\n'; 170 break; 171 case $ord_var_c == 0x0C: 172 $ascii .= '\f'; 173 break; 174 case $ord_var_c == 0x0D: 175 $ascii .= '\r'; 176 break; 177 178 case $ord_var_c == 0x22: 179 case $ord_var_c == 0x2F: 180 case $ord_var_c == 0x5C: 181 // double quote, slash, slosh 182 $ascii .= '\\'.$var{$c}; 183 break; 184 185 case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): 186 // characters U-00000000 - U-0000007F (same as ASCII) 187 $ascii .= $var{$c}; 188 break; 189 190 case (($ord_var_c & 0xE0) == 0xC0): 191 // characters U-00000080 - U-000007FF, mask 110XXXXX 192 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 193 $char = pack('C*', $ord_var_c, ord($var{$c+1})); 194 $c+=1; 195 $utf16 = $this->utf8_to_utf16be($char); 196 $ascii .= sprintf('\u%04s', bin2hex($utf16)); 197 break; 198 199 case (($ord_var_c & 0xF0) == 0xE0): 200 // characters U-00000800 - U-0000FFFF, mask 1110XXXX 201 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 202 $char = pack('C*', $ord_var_c, 203 ord($var{$c+1}), 204 ord($var{$c+2})); 205 $c+=2; 206 $utf16 = $this->utf8_to_utf16be($char); 207 $ascii .= sprintf('\u%04s', bin2hex($utf16)); 208 break; 209 210 case (($ord_var_c & 0xF8) == 0xF0): 211 // characters U-00010000 - U-001FFFFF, mask 11110XXX 212 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 213 $char = pack('C*', $ord_var_c, 214 ord($var{$c+1}), 215 ord($var{$c+2}), 216 ord($var{$c+3})); 217 $c+=3; 218 $utf16 = $this->utf8_to_utf16be($char); 219 $ascii .= sprintf('\u%04s', bin2hex($utf16)); 220 break; 221 222 case (($ord_var_c & 0xFC) == 0xF8): 223 // characters U-00200000 - U-03FFFFFF, mask 111110XX 224 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 225 $char = pack('C*', $ord_var_c, 226 ord($var{$c+1}), 227 ord($var{$c+2}), 228 ord($var{$c+3}), 229 ord($var{$c+4})); 230 $c+=4; 231 $utf16 = $this->utf8_to_utf16be($char); 232 $ascii .= sprintf('\u%04s', bin2hex($utf16)); 233 break; 234 235 case (($ord_var_c & 0xFE) == 0xFC): 236 // characters U-04000000 - U-7FFFFFFF, mask 1111110X 237 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 238 $char = pack('C*', $ord_var_c, 239 ord($var{$c+1}), 240 ord($var{$c+2}), 241 ord($var{$c+3}), 242 ord($var{$c+4}), 243 ord($var{$c+5})); 244 $c+=5; 245 $utf16 = $this->utf8_to_utf16be($char); 246 $ascii .= sprintf('\u%04s', bin2hex($utf16)); 247 break; 248 } 249 } 250 251 return '"'.$ascii.'"'; 252 253 case 'array': 254 /* 255 * As per JSON spec if any array key is not an integer 256 * we must treat the the whole array as an object. We 257 * also try to catch a sparsely populated associative 258 * array with numeric keys here because some JS engines 259 * will create an array with empty indexes up to 260 * max_index which can cause memory issues and because 261 * the keys, which may be relevant, will be remapped 262 * otherwise. 263 * 264 * As per the ECMA and JSON specification an object may 265 * have any string as a property. Unfortunately due to 266 * a hole in the ECMA specification if the key is a 267 * ECMA reserved word or starts with a digit the 268 * parameter is only accessible using ECMAScript's 269 * bracket notation. 270 */ 271 272 // treat as a JSON object 273 if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { 274 return '{' . 275 join(',', array_map(array($this, 'name_value'), 276 array_keys($var), 277 array_values($var))) 278 . '}'; 279 } 280 281 // treat it like a regular array 282 return '[' . join(',', array_map(array($this, 'encode'), $var)) . ']'; 283 284 case 'object': 285 $vars = get_object_vars($var); 286 return '{' . 287 join(',', array_map(array($this, 'name_value'), 288 array_keys($vars), 289 array_values($vars))) 290 . '}'; 291 292 default: 293 return ''; 294 } 295 } 296 297 /** 298 * encodes an arbitrary variable into JSON format, alias for encode() 299 * @see JSON::encode() 300 * 301 * @param mixed $var any number, boolean, string, array, or object to be encoded. 302 * see argument 1 to JSON() above for array-parsing behavior. 303 * if var is a strng, note that encode() always expects it 304 * to be in ASCII or UTF-8 format! 305 * 306 * @return string JSON string representation of input var 307 * @access public 308 */ 309 public function enc($var) 310 { 311 return $this->encode($var); 312 } 313 314 /** function name_value 315 * array-walking function for use in generating JSON-formatted name-value pairs 316 * 317 * @param string $name name of key to use 318 * @param mixed $value reference to an array element to be encoded 319 * 320 * @return string JSON-formatted name-value pair, like '"name":value' 321 * @access private 322 */ 323 protected function name_value($name, $value) 324 { 325 return $this->encode(strval($name)) . ':' . $this->encode($value); 326 } 327 328 /** 329 * reduce a string by removing leading and trailing comments and whitespace 330 * 331 * @param $str string string value to strip of comments and whitespace 332 * 333 * @return string string value stripped of comments and whitespace 334 * @access private 335 */ 336 protected function reduce_string($str) 337 { 338 $str = preg_replace(array( 339 340 // eliminate single line comments in '// ...' form 341 '#^\s*//(.+)$#m', 342 343 // eliminate multi-line comments in '/* ... */' form, at start of string 344 '#^\s*/\*(.+)\*/#Us', 345 346 // eliminate multi-line comments in '/* ... */' form, at end of string 347 '#/\*(.+)\*/\s*$#Us' 348 349 ), '', $str); 350 351 // eliminate extraneous space 352 return trim($str); 353 } 354 355 /** 356 * decodes a JSON string into appropriate variable 357 * 358 * @param string $str JSON-formatted string 359 * 360 * @return mixed number, boolean, string, array, or object 361 * corresponding to given JSON input string. 362 * See argument 1 to JSON() above for object-output behavior. 363 * Note that decode() always returns strings 364 * in ASCII or UTF-8 format! 365 * @access public 366 */ 367 public function decode($str) 368 { 369 $str = $this->reduce_string($str); 370 371 switch (strtolower($str)) { 372 case 'true': 373 return true; 374 375 case 'false': 376 return false; 377 378 case 'null': 379 return null; 380 381 default: 382 if (is_numeric($str)) { 383 // Lookie-loo, it's a number 384 385 // This would work on its own, but I'm trying to be 386 // good about returning integers where appropriate: 387 // return (float)$str; 388 389 // Return float or int, as appropriate 390 return ((float)$str == (integer)$str) 391 ? (integer)$str 392 : (float)$str; 393 394 } elseif (preg_match('/^("|\').+(\1)$/s', $str, $m) && $m[1] == $m[2]) { 395 // STRINGS RETURNED IN UTF-8 FORMAT 396 $delim = substr($str, 0, 1); 397 $chrs = substr($str, 1, -1); 398 $utf8 = ''; 399 $strlen_chrs = strlen($chrs); 400 401 for ($c = 0; $c < $strlen_chrs; ++$c) { 402 403 $substr_chrs_c_2 = substr($chrs, $c, 2); 404 $ord_chrs_c = ord($chrs{$c}); 405 406 switch (true) { 407 case $substr_chrs_c_2 == '\b': 408 $utf8 .= chr(0x08); 409 ++$c; 410 break; 411 case $substr_chrs_c_2 == '\t': 412 $utf8 .= chr(0x09); 413 ++$c; 414 break; 415 case $substr_chrs_c_2 == '\n': 416 $utf8 .= chr(0x0A); 417 ++$c; 418 break; 419 case $substr_chrs_c_2 == '\f': 420 $utf8 .= chr(0x0C); 421 ++$c; 422 break; 423 case $substr_chrs_c_2 == '\r': 424 $utf8 .= chr(0x0D); 425 ++$c; 426 break; 427 428 case $substr_chrs_c_2 == '\\"': 429 case $substr_chrs_c_2 == '\\\'': 430 case $substr_chrs_c_2 == '\\\\': 431 case $substr_chrs_c_2 == '\\/': 432 if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || 433 ($delim == "'" && $substr_chrs_c_2 != '\\"')) { 434 $utf8 .= $chrs{++$c}; 435 } 436 break; 437 438 case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): 439 // single, escaped unicode character 440 $utf16 = chr(hexdec(substr($chrs, ($c+2), 2))) 441 . chr(hexdec(substr($chrs, ($c+4), 2))); 442 $utf8 .= $this->utf16be_to_utf8($utf16); 443 $c+=5; 444 break; 445 446 case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): 447 $utf8 .= $chrs{$c}; 448 break; 449 450 case ($ord_chrs_c & 0xE0) == 0xC0: 451 // characters U-00000080 - U-000007FF, mask 110XXXXX 452 //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 453 $utf8 .= substr($chrs, $c, 2); 454 ++$c; 455 break; 456 457 case ($ord_chrs_c & 0xF0) == 0xE0: 458 // characters U-00000800 - U-0000FFFF, mask 1110XXXX 459 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 460 $utf8 .= substr($chrs, $c, 3); 461 $c += 2; 462 break; 463 464 case ($ord_chrs_c & 0xF8) == 0xF0: 465 // characters U-00010000 - U-001FFFFF, mask 11110XXX 466 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 467 $utf8 .= substr($chrs, $c, 4); 468 $c += 3; 469 break; 470 471 case ($ord_chrs_c & 0xFC) == 0xF8: 472 // characters U-00200000 - U-03FFFFFF, mask 111110XX 473 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 474 $utf8 .= substr($chrs, $c, 5); 475 $c += 4; 476 break; 477 478 case ($ord_chrs_c & 0xFE) == 0xFC: 479 // characters U-04000000 - U-7FFFFFFF, mask 1111110X 480 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 481 $utf8 .= substr($chrs, $c, 6); 482 $c += 5; 483 break; 484 485 } 486 487 } 488 489 return $utf8; 490 491 } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { 492 // array, or object notation 493 494 if ($str{0} == '[') { 495 $stk = array(self::JSON_IN_ARR); 496 $arr = array(); 497 } else { 498 if ($this->use == self::JSON_LOOSE_TYPE) { 499 $stk = array(self::JSON_IN_OBJ); 500 $obj = array(); 501 } else { 502 $stk = array(self::JSON_IN_OBJ); 503 $obj = new stdClass(); 504 } 505 } 506 507 array_push($stk, array('what' => self::JSON_SLICE, 508 'where' => 0, 509 'delim' => false)); 510 511 $chrs = substr($str, 1, -1); 512 $chrs = $this->reduce_string($chrs); 513 514 if ($chrs == '') { 515 if (reset($stk) == self::JSON_IN_ARR) { 516 return $arr; 517 518 } else { 519 return $obj; 520 521 } 522 } 523 524 //print("\nparsing {$chrs}\n"); 525 526 $strlen_chrs = strlen($chrs); 527 528 for ($c = 0; $c <= $strlen_chrs; ++$c) { 529 530 $top = end($stk); 531 $substr_chrs_c_2 = substr($chrs, $c, 2); 532 533 if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { 534 // found a comma that is not inside a string, array, etc., 535 // OR we've reached the end of the character list 536 $slice = substr($chrs, $top['where'], ($c - $top['where'])); 537 array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); 538 //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 539 540 if (reset($stk) == self::JSON_IN_ARR) { 541 // we are in an array, so just push an element onto the stack 542 array_push($arr, $this->decode($slice)); 543 544 } elseif (reset($stk) == self::JSON_IN_OBJ) { 545 // we are in an object, so figure 546 // out the property name and set an 547 // element in an associative array, 548 // for now 549 if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { 550 // "name":value pair 551 $key = $this->decode($parts[1]); 552 $val = $this->decode($parts[2]); 553 554 if ($this->use == self::JSON_LOOSE_TYPE) { 555 $obj[$key] = $val; 556 } else { 557 $obj->$key = $val; 558 } 559 } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { 560 // name:value pair, where name is unquoted 561 $key = $parts[1]; 562 $val = $this->decode($parts[2]); 563 564 if ($this->use == self::JSON_LOOSE_TYPE) { 565 $obj[$key] = $val; 566 } else { 567 $obj->$key = $val; 568 } 569 } 570 571 } 572 573 } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { 574 // found a quote, and we are not inside a string 575 array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); 576 //print("Found start of string at {$c}\n"); 577 578 } elseif (($chrs{$c} == $top['delim']) && 579 ($top['what'] == self::JSON_IN_STR) && 580 (($chrs{$c - 1} != "\\") || 581 ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { 582 // found a quote, we're in a string, and it's not escaped 583 array_pop($stk); 584 //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); 585 586 } elseif (($chrs{$c} == '[') && 587 in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { 588 // found a left-bracket, and we are in an array, object, or slice 589 array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); 590 //print("Found start of array at {$c}\n"); 591 592 } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { 593 // found a right-bracket, and we're in an array 594 array_pop($stk); 595 //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 596 597 } elseif (($chrs{$c} == '{') && 598 in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { 599 // found a left-brace, and we are in an array, object, or slice 600 array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); 601 //print("Found start of object at {$c}\n"); 602 603 } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { 604 // found a right-brace, and we're in an object 605 array_pop($stk); 606 //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 607 608 } elseif (($substr_chrs_c_2 == '/*') && 609 in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { 610 // found a comment start, and we are in an array, object, or slice 611 array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => $c, 'delim' => false)); 612 $c++; 613 //print("Found start of comment at {$c}\n"); 614 615 } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { 616 // found a comment end, and we're in one now 617 array_pop($stk); 618 $c++; 619 620 for ($i = $top['where']; $i <= $c; ++$i) 621 $chrs = substr_replace($chrs, ' ', $i, 1); 622 623 //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 624 625 } 626 627 } 628 629 if (reset($stk) == self::JSON_IN_ARR) { 630 return $arr; 631 632 } elseif (reset($stk) == self::JSON_IN_OBJ) { 633 return $obj; 634 635 } 636 637 } 638 } 639 } 640 641 /** 642 * decodes a JSON string into appropriate variable; alias for decode() 643 * @see JSON::decode() 644 * 645 * @param string $str JSON-formatted string 646 * 647 * @return mixed number, boolean, string, array, or object 648 * corresponding to given JSON input string. 649 * See argument 1 to JSON() above for object-output behavior. 650 * Note that decode() always returns strings 651 * in ASCII or UTF-8 format! 652 */ 653 public function dec($var) 654 { 655 return $this->decode($var); 656 } 657 658 659 /** 660 * This function returns any UTF-8 encoded text as a list of 661 * Unicode values: 662 * 663 * @author Scott Michael Reynen <scott@randomchaos.com> 664 * @link http://www.randomchaos.com/document.php?source=php_and_unicode 665 * @see unicode_to_utf8() 666 */ 667 protected function utf8_to_unicode( &$str ) 668 { 669 $unicode = array(); 670 $values = array(); 671 $lookingFor = 1; 672 673 for ($i = 0; $i < strlen( $str ); $i++ ) 674 { 675 $thisValue = ord( $str[ $i ] ); 676 if ( $thisValue < 128 ) 677 $unicode[] = $thisValue; 678 else 679 { 680 if ( count( $values ) == 0 ) 681 $lookingFor = ( $thisValue < 224 ) ? 2 : 3; 682 $values[] = $thisValue; 683 if ( count( $values ) == $lookingFor ) 684 { 685 $number = ( $lookingFor == 3 ) ? 686 ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ): 687 ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 ); 688 $unicode[] = $number; 689 $values = array(); 690 $lookingFor = 1; 691 } 692 } 693 } 694 return $unicode; 695 } 696 697 /** 698 * This function converts a Unicode array back to its UTF-8 representation 699 * 700 * @author Scott Michael Reynen <scott@randomchaos.com> 701 * @link http://www.randomchaos.com/document.php?source=php_and_unicode 702 * @see utf8_to_unicode() 703 */ 704 protected function unicode_to_utf8( &$str ) 705 { 706 $utf8 = ''; 707 foreach( $str as $unicode ) 708 { 709 if ( $unicode < 128 ) 710 { 711 $utf8.= chr( $unicode ); 712 } 713 elseif ( $unicode < 2048 ) 714 { 715 $utf8.= chr( 192 + ( ( $unicode - ( $unicode % 64 ) ) / 64 ) ); 716 $utf8.= chr( 128 + ( $unicode % 64 ) ); 717 } 718 else 719 { 720 $utf8.= chr( 224 + ( ( $unicode - ( $unicode % 4096 ) ) / 4096 ) ); 721 $utf8.= chr( 128 + ( ( ( $unicode % 4096 ) - ( $unicode % 64 ) ) / 64 ) ); 722 $utf8.= chr( 128 + ( $unicode % 64 ) ); 723 } 724 } 725 return $utf8; 726 } 727 728 /** 729 * UTF-8 to UTF-16BE conversion. 730 * 731 * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits 732 */ 733 protected function utf8_to_utf16be(&$str, $bom = false) 734 { 735 $out = $bom ? "\xFE\xFF" : ''; 736 if(function_exists('mb_convert_encoding')) 737 return $out.mb_convert_encoding($str,'UTF-16BE','UTF-8'); 738 739 $uni = $this->utf8_to_unicode($str); 740 foreach($uni as $cp) 741 $out .= pack('n',$cp); 742 return $out; 743 } 744 745 /** 746 * UTF-8 to UTF-16BE conversion. 747 * 748 * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits 749 */ 750 protected function utf16be_to_utf8(&$str) 751 { 752 $uni = unpack('n*',$str); 753 return unicode_to_utf8($uni); 754 } 755 756 } 757 758 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |