Check-in [02e65f8aad]
Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | upgradephp-16 |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
02e65f8aad653b484395b5b20eaacea2 |
User & Date: | mario 2010-06-22 17:03:43 |
2010-06-22
| ||
17:21 | builds a test-version of upgrade.php, having all functions prefixed with "up_" check-in: 94a0e3704d user: mario tags: trunk | |
17:03 | upgradephp-16 check-in: 02e65f8aad user: mario tags: trunk | |
17:03 | upgradephp-15 check-in: 51e3884900 user: mario tags: trunk | |
Changes to doc/README.
1 2 3 4 | PHP downwards compatibility functions ------------------------------------- The "upgrade.php" package implements features and functions from | | | > | | | | | > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | PHP downwards compatibility functions ------------------------------------- The "upgrade.php" package implements features and functions from newer PHP versions. It defines them as pure PHP code. Functions get defined dynamically defines, at runtime. All emulated functions use names identical to the original implementation. But it doesn't perturb if the native functions exist. So this is really a drop-in replacement. It allows you to use all PHP features regardless of the current PHP interpreter. You just have to include() this single script to remove any backward compatibility woes. This allows relying on the newer, more powerful PHP functions. The use and retyping of workarounds gets superfluous. Your application remains "PHP 4.1+ COMPATIBLE" while actually using PHP5.2 features. this is useful: - for open source distributions - if your own providers PHP version is immemorial - you want to test new functions, but not install a new PHP ver |
︙ | ︙ | |||
269 270 271 272 273 274 275 | this README), because they probably make little sense distributed alongside elsewhere. It is also safe to extract a few function bodies/definitions out of upgrade.php to make a shorter version (load only the needed funcs). But you should keep the "if (function_exists(...))" wrapper code preferrably. | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | this README), because they probably make little sense distributed alongside elsewhere. It is also safe to extract a few function bodies/definitions out of upgrade.php to make a shorter version (load only the needed funcs). But you should keep the "if (function_exists(...))" wrapper code preferrably. PHP_Compat however might make a better source, if you really need just one or two functions. Omissions --------- A few PHP features are specifically NOT implemented, and so still had to be taken care of in your scripts: |
︙ | ︙ | |||
292 293 294 295 296 297 298 | ext/ ---- The ext/ subdirectory in here provides a few more or less useful emulations for various PHP extensions or function groups. | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | ext/ ---- The ext/ subdirectory in here provides a few more or less useful emulations for various PHP extensions or function groups. · "ext/php40array" provides a few exotic array diff functions (for associative arrays and for using multiple callback functions) · "ext/exotic" contains some rarely needed functions, which have been removed from the main file for that and other reasons · "ext/bcmath" provides the mathematical functions with arbitrary precision on Unix systems, but emulation also works on top of |
︙ | ︙ | |||
326 327 328 329 330 331 332 | Other snippets in ext/ are probably incomplete or just TODO stubs. doc/devtools/ ------------- Please run the "updoc" script once to update your PHP manual, if you | | | | > > > | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | Other snippets in ext/ are probably incomplete or just TODO stubs. doc/devtools/ ------------- Please run the "updoc" script once to update your PHP manual, if you are planning to use the upgrade.php script. It adds notes to version compatibility strings on each page, when an upgradephp equivalent exists. · The "dtools/updoc" commandline script updates your local PHP documentation to carry hints about emulated functions. It'll simply add a small "EMU" on top of the supported functions` description pages (in the line typically listing the PHP versions). The other cmdline scripts are used for developing upgrade.php: · "ckavail.php" was used to check for added functions between different PHP interpreter versions, purely a development script. · "dtools/doctests" greps your local PHP manual for function use examples, and executes them with the given PHP interpreter and the "upgrade.php" script loaded of course. This way you get live tests, but also see: |
︙ | ︙ | |||
408 409 410 411 412 413 414 | Other Notes ----------- · This script doesn't reside in any CVS/SVN reposititory currently because it is considered a too minor and small project. · The project homepage is <http://upgradephp.berlios.de/> but see | | > | > > > > > | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | Other Notes ----------- · This script doesn't reside in any CVS/SVN reposititory currently because it is considered a too minor and small project. · The project homepage is <http://upgradephp.berlios.de/> but see also <http://freshmeat.net/projects/upgradephp> for any update notifications. License ------- Almost all in here is Public Domain. There are no restrictions on how or where you could use it. You may redistribute it under any license as you wish, and you don't need to tell anyone where you got it from. It has absolutely no impact on the rest of YOUR project; you are free to include it as if you had written it yourself. You could prepend the license preamble (GNU GPL, LGPL, BSD, MPL, MSFT EULA, PHP, CDDL, Artistic, ...) of your choice if you want to. Exceptions are the doc/tests* and doc/runtest scripts. Those are under the PHP license, taken from PEAR, PECL or PHP. The "ext/pdo.php" class is from Andrea Giammarchi and under the PHP License as well. Also check out http://xpdo.org/ - the origin. Author ------ The current maintainer can be contacted under <milky*users·sf·net> Please drop me a line, regarding omissions, bugs, contributing a few bytes... ChangeLog --------- v16 - json_decode() array-conversion fix by Gerhard (tinned-software.net) - object-oriented input $_REQUEST filter wrapper in contrib/ - some old code moved to contrib/archive/ v15 - moved to phpDoc comment style, but not all emulated functions carry @param lists - tarball directories restructured - ext/filter ... - json_decode now decodes \uXXXX unicode references - include the PDO emulation classes of Andrea Giammarchi (under PHP License) |
︙ | ︙ |
Changes to doc/devtools/listemu.
1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/local/bin/php -qC <?php /* Prints the list of emulated functions. */ #-- basedir $dir = realpath(dirname(__FILE__) . "/../"); #-- grep for function definitions $text = ""; $text .= implode("", file("$dir/upgrade.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 | #!/usr/local/bin/php -qC <?php /* Prints the list of emulated functions. */ #-- basedir $dir = realpath(dirname(__FILE__) . "/../"); #-- grep for function definitions $text = ""; $text .= implode("", file("$dir/upgrade.php")); $text .= implode("", file("$dir/ext/php40array.php")); $text .= implode("", file("$dir/ext/bcmath.php")); $text .= implode("", file("$dir/ext/gettext.php")); $text .= implode("", file("$dir/ext/mime.php")); $text .= implode("", file("$dir/ext/old.php")); $text .= implode("", file("$dir/ext/posix.php")); $text .= implode("", file("$dir/ext/ctype.php")); $text .= implode("", file("$dir/ext/unfinished/odbc.php")); if (preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu)) { $list = array_unique($uu[1]); } #-- print echo "Following functions can be emulated currently:\n"; foreach ($list as $func) { echo "· $func\n"; } ?> |
Changes to doc/gettext.txt.
1 2 3 4 5 6 7 8 | PHP-only gettext emulation -------------------------- The "gettext.php" include script tries to reimplement GNU gettext in pure PHP. It is incomplete and divergent in many ways, but seems to work well in its goal to be a quick drop-in replacement. | | | | | | | | | | > | > | 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 | PHP-only gettext emulation -------------------------- The "gettext.php" include script tries to reimplement GNU gettext in pure PHP. It is incomplete and divergent in many ways, but seems to work well in its goal to be a quick drop-in replacement. You load the script like you'd include the "upgrade.php" script. You then have the family of gettext functions always available - wether compiled into your PHP binary or not. This way you can freely use standardized i18n features safely on any web server; and with all your applications. There are however a few minor obstacles and differences in between the original and the emulation which you have to take care of. Most of the incompatibilites descend from lousily documented behaviour of the original, and the emulated version have not been tested *extensively*. - You should use setlocale() before any bindtextdomain(), because this emulation does load the .mo/.po data files only once. - The emulation only ever loads one translation file (it never retrieves translation strings from different localizations, so it is less useful in conjunction with Accept-Language header settings - where multiple languages could be mixed together). [Original gettext may or may not load from multiple files??] - To be compliant with the native implementation, you have to make sure, that the .mo files are built from the *.po source files. (The emulation tries to work on both, but it really shouldn't do that.) - Order of environment variable precedence is: 1. LANGUAGE 2. LC_ALL 3. LC_MESSAGE 4. LANG (multiple langs) 5. setlocale() 6. HTTP_ACCEPT_LANGUAGE (incompliant with GNU gettext, but deemed senseful for PHP) - There is a second variant of the script, which tries to handle plural forms. This has multiple limitations: - does not employ a full Plural-Forms parser (a C expression which must be interpreted at runtime) - matches and works only with a few built-in language plural form syntaxes and orderings - and it's fully untested as of yet (= not tested with a real-world plural .po/.mo translation package) - It constructs a global $_GETTEXT[] variable which contains all messages and translations at runtime in-memory. That means, it is far more memory-hungry and less scalable than the original GNU libintl in C. |
Deleted ext/array.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added ext/contrib/archive/bcmath.old.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 | <?php /** * These two alternate bcmath implementations don't emulate arbitrary * precision at all. And therefore have been removed from bcmath.php. * */ #-- GMP if (!function_exists("bcadd") && function_exists("gmp_strval")) { function bcadd($a, $b) { return gmp_strval(gmp_add($a, $b)); } function bcsub($a, $b) { return gmp_strval(gmp_sub($a, $b)); } function bcmul($a, $b) { return gmp_strval(gmp_mul($a, $b)); } function bcdiv($a, $b, $precision=NULL) { $qr = gmp_div_qr($a, $b); $q = gmp_strval($qr[0]); $r = gmp_strval($qr[1]); if ((!$r) || ($precision===0)) { return($q); } else { if (isset($precision)) { $r = substr($r, 0, $precision); } return("$q.$r"); } } function bcmod($a, $b) { return gmp_strval(gmp_mod($a, $b)); } function bcpow($a, $b) { return gmp_strval(gmp_pow($a, $b)); } function bcpowmod($x, $y, $mod) { return gmp_strval(gmp_powm($x, $y, $mod)); } function bcsqrt($x) { return gmp_strval(gmp_sqrt($x)); } function bccomp($a, $b) { return gmp_cmp($a, $b); } function bcscale($scale="IGNORED") { trigger_error("bcscale(): ignored", E_USER_ERROR); } }//gmp emulation #-- bigint // @dl("php_big_int".PHP_SHLIB_SUFFIX)) if (!function_exists("bcadd") && function_exists("bi_serialize")) { function bcadd($a, $b) { return bi_to_str(bi_add($a, $b)); } function bcsub($a, $b) { return bi_to_str(bi_sub($a, $b)); } function bcmul($a, $b) { return bi_to_str(bi_mul($a, $b)); } function bcdiv($a, $b) { return bi_to_str(bi_div($a, $b)); } function bcmod($a, $b) { return bi_to_str(bi_mod($a, $b)); } function bcpow($a, $b) { return bi_to_str(bi_pow($a, $b)); } function bcpowmod($a, $b, $c) { return bi_to_str(bi_powmod($a, $b, $c)); } function bcsqrt($a) { return bi_to_str(bi_sqrt($a)); } function bccomp($a, $b) { return bi_cmp($a, $b); } function bcscale($scale="IGNORED") { trigger_error("bcscale(): ignored", E_USER_ERROR); } } ?> |
Added ext/contrib/archive/pdo-2006-01-29.tar.gz.
cannot compute difference between binary files
Added ext/contrib/archive/phprequest.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 | <?php /* Allows http "POST" and "PUSH" requests with a Content-Type of "application/vnd.php.serialized". This isn't used in the wild. */ if (empty($_POST) and (strtoupper($_SERVER["REQUEST_METHOD"][0]) == "P") and (strtolower(trim(strtok($_SERVER["CONTENT_TYPE"], ";,("))) == "application/vnd.php.serialized")) { #-- search for bare request body if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) { $_POST = $GLOBALS["HTTP_RAW_POST_DATA"]; } else { $f = fopen("php://input", "rb"); $_POST = fread($f, 1<<22); fclose($f); } #-- uncompress and decode, if something found if ($_POST) { #-- strip known/supported encodings $enc = trim(strtok(strtolower($_SERVER["HTTP_CONTENT_ENCODING"]), ",;")); if ($enc == "deflate") { $_POST = gzinflate($_POST); } elseif ($enc == "compress") { $_POST = gzuncompress($_POST); } elseif ($enc == "gzip") { $_POST = function_exists("gzdecode") ? gzdecode($_POST) : gzinflate(substr($_POST, 10, strlen($_POST) - 18)); } elseif (($enc == "x-bzip2") or ($enc == "bzip2")) { $_POST = function_exists("bzdecompress") ? bzdecompress($_POST) : NULL; } #-- decipher if ($_POST) { $_POST = unserialize($_POST); } #-- merge if ($_POST) { $_REQUEST = array_merge($_REQUEST, $_POST); } } } ?> |
Added ext/contrib/archive/xmlrpc.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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 | <?php define("XMLRPC_VERSION", "0.3.10"); # api: PHP # type: api # provides: rpc, xml-rpc # version: 0.3.10 # category: library # priority: optional # title: XML-RPC client and server # description: serves remote procedure calls # homepage: http://freshmeat.net/p/upgradephp # # Supports XML-RPC (text/xml) and XML+RPC (application/rpc+xml) compressed, # and can be used as client or server interface. Works without XMLRPC and # XML extensions, but utilizes them for optimal speed whenever available. # # XXXX XXXX MMM MMM LLL RRRRRRR PPPPPPP CCCCCCC # XXXX XXXX MMMM MMMM LLL +++ RRRRRRRR PPPPPPPP CCCCCCCCC # XXXXXXX MMMMM MMMMM LLL +++ RRR RRR PPP PPP CCC CCC # XXXXX MMMMMMMMMMM LLL +++++++++++ RRR RRR PPP PPP CCC # XXX MMM MMM MMM LLL +++++++++++ RRRRRRRR PPPPPPPP CCC # XXXXX MMM M MMM LLL +++ RRRRRRR PPPPPPP CCC # XXXXXXX MMM MMM LLL +++ RRR RRR PPP CCC CCC # XXXX XXXX MMM MMM LLLLLLL RRR RRR PPP CCCCCCCCC # XXXX XXXX MMM MMM LLLLLLL RRR RRR PPP CCCCCCC # # This is Public Domain. (c) 2004 WhoEver wants to. [milky*erphesfurt·de] #-- config define("XMLRPC_PLUS", 0); # use XML+RPC per default define("XMLRPC_AUTO_TYPES", 0); # detect base64+datetime strings and automatically generate the according xmlrpc object representations then define("XMLRPC_AUTO_UTF8", 1); # de/convert anything from and to UTF-8 automatically - if yourscripts use Latin1 natively, but the RPC server expects/sends UTF-8 define("XMLRPC_CHARSET", "utf-8"); # used in responses and requests define("XMLRPC_AUTODISCOVERY", 0); # "connections" automatically create methods define("XMLRPC_FAST", 1); # use PHPs XML-RPC extension where possible define("XMLRPC_OO", 1); # return XML-RPC/HTTP errors as objects define("XMLRPC_DEBUG", 0); # output error hints, write /tmp dumps - set this to 1, 2 or 3 #-- _server() settings define("XMLRPC_LOG", "/tmp/xmlrpc.".@$_SERVER["SERVER_NAME"].".log"); #-- general data # (don't change the following, most are auto-configured values) define("XMLRPC_UA", "xml+rpc/".XMLRPC_VERSION." (PHP/".PHP_VERSION."; ".PHP_OS.")"); define("XMLRPC_MIME_NEW", "application/rpc+xml"); define("XMLRPC_MIME_OLD", "text/xml"); define("XMLRPC_MIME", XMLRPC_MIME_OLD); define("XMLRPC_ACCEPT", XMLRPC_MIME_NEW.", ".XMLRPC_MIME_OLD."; q=0.5"); define("XMLRPC_EPI", function_exists("xmlrpc_decode_request")); #-- init error_reporting(0); if (isset($_SERVER["HTTP_CONTENT_TYPE"]) && empty($_SERVER["CONTENT_TYPE"])) { $_SERVER["CONTENT_TYPE"] = $_SERVER["HTTP_CONTENT_TYPE"]; // older CGI implementations } ############################################################################ # # # client part # # # ############################################################################ #-- Issue a request, call can take any number of arguments. # $result = xmlrpc("http://example.com/RPC2/", "method1", $arg1 ...); # $result = xmlrpc("xml+rpc://here.org/RPC3/", "ns.function", ...); # Results automatically have <datetime> values converted into Unix # timestamps and <base64> unpacked into strings. # function xmlrpc($server, $method=NULL /*, ... */) { if ($method) { $params = func_get_args(); shift($params); shift($params); return xmlrpc_request($server, $method, $params); } else { return new xmlrpc_connection($server); } } #-- Generate and send request, decode response. function xmlrpc_request($url, $method, $params=array(), $plus=XMLRPC_PLUS, $gzip=0) { global $xmlrpc_response_headers, $xmlrpc_error; #-- init whole lib for request (we are not-OO here) $xmlrpc_error = false; $xmlrpc_response_headers = array(); #-- encapsulate req, transmit it $socket = xmlrpc_request_send($url, $method, $params, $plus, $gzip); if (!$socket) { return xmlrpc_error(-32768, "no connection", 0, "GLOBALVARS"); } #-- wait for, read response $response = ""; while (!feof($socket) && (strlen($DATA) <= 768<<10)) { $response .= fread($socket, 4<<10); } fclose($socket); if (XMLRPC_DEBUG >= 3) { echo "<code>$response</code>"; } #-- decode answer and give results return xmlrpc_response_decode($response); } #-- an alias function xmlrpc_call($url, $method, $params=array(), $plus=XMLRPC_PLUS, $gzip=0) { return xmlrpc_request($url, $method, $params, $plus, $gzip); } #-- marshall request parameters into array, hash, xml string function xmlrpc_request_send($url, $method, &$params, $plus, $gzip, $blocking=true) { #-- get connection data $c = parse_url($url); ($host = $c["host"]); ($port = @$c["port"]) or ($port = 80); ($path = $c["path"]) or ($path = "/"); if (strpos($c["scheme"], "+")) { $plus++; } if (strpos($c["scheme"], "gzip")) { $gzip++; } if (!$host) { return(NULL); } $inj = ""; if ($str = $c["user"]) { if ($c["pass"]) { $str .= ":" . $c["pass"]; } $inj = "Authorization: Basic " . base64_encode($str) . "\n"; } #-- mk request HTTP+XML block from params $request = xmlrpc_request_marshall($method, $params); $request = xmlrpc_request_http($request, $path, $host, $plus, $gzip, $inj); #-- connect, send request if ($socket = fsockopen($host, $port, $io_err, $io_err_s, 30)) { socket_set_blocking($socket, $blocking); socket_set_timeout($socket, 17, 555); } else { echo "Could not connect to '<b>$host</b>:$port$path' - error $io_err: $io_err_s.<br>\n"; return(NULL); } fputs($socket, $request); #-- done here return($socket); } #-- marshall function call into XML+HTTP string function xmlrpc_request_marshall($method, &$params) { #-- use xmlrpc-epi if (XMLRPC_FAST && XMLRPC_EPI) { $query = xmlrpc_encode_request($method, $params); return($query); } #-- build query $query = array( "methodCall" => array( "methodName" => array( ",0"=>$method ), "params" => array() ) ); foreach ($params as $i=>$p) { $query["methodCall"]["params"]["param,$i"] = xmlrpc_compact_value($p); } $query = array2xml($query, 1, 'encoding="'.XMLRPC_CHARSET.'" '); #-- encode? if (XMLRPC_AUTO_UTF8) { $query = utf8_encode($query); } return($query); } #-- enclose body into HTTP request string function xmlrpc_request_http(&$query, $path, $host, $plus, $gzip, $inj_header="") { #-- build request $n = "\015\012"; $request = "POST $path HTTP/1.0$n" . "Host: $host$n" . ($inj_header ? str_replace("\n", $n, $inj_header) : "") . "User-Agent: " . XMLRPC_UA . "$n" . "Accept: ".XMLRPC_ACCEPT."$n" . (!XMLRPC_DEBUG ? "Accept-Encoding: deflate$n" : "") . "Content-Type: ".($plus ? XMLRPC_MIME_NEW : XMLRPC_MIME_OLD) ."; charset=".XMLRPC_CHARSET."$n"; #-- compress? if ($gzip) { $query = gzdeflate($query); $request .= "Content-Encoding: deflate$n"; } $request .= "Content-Length: " . strlen($query) . "$n" . "$n"; $request .= $query . "$n"; return($request); } #-- unpack response from HTTP and XML representation function xmlrpc_response_decode(&$response) { global $xmlrpc_response_headers; #-- split into headers and content $l1 = strpos($response, "\n\n"); $l2 = strpos($response, "\n\r\n"); if ($l2 && (!$l1 || ($l2<$l1))) { $head = substr($response, 0, $l2); $response = substr($response, $l2+3); } else { $head = substr($response, 0, $l1); $response = substr($response, $l2+2); } #-- decode headers, decompress body foreach (explode("\n", $head) as $line) { $xmlrpc_response_headers[strtolower(trim(strtok($line, ":")))] = trim(strtok("\000")); } if ($enc = trim(@$xmlrpc_response_headers["content-encoding"])) { if (($enc == "gzip") || ($enc == "x-gzip")) { $response = gzinflate(substr($response, 10, strlen($response)-18)); } elseif (($enc == "compress") || ($enc == "x-compress")) { $response = gzuncompress($response); } elseif (($enc == "deflate") || ($enc == "x-deflate")) { $response = gzinflate($response); } } $r = xmlrpc_response_unmarshall($response); if (XMLRPC_DEBUG) {var_dump($r);} return($r); } #-- decode XML-RPC from string into array and extract its actual meaning function xmlrpc_response_unmarshall(&$response) { global $xmlrpc_response_headers; #-- strip encoding if (XMLRPC_AUTO_UTF8) { xmlrpc_decode_utf8xml($response, @$xmlrpc_response_headers["content-type"].@$xmlrpc_response_headers["content-charset"]); } if (XMLRPC_DEBUG >= 4) { fwrite(fopen("/tmp/xmlrpc:resp_in_xml","w"), $response); } #-- use xmlrpc-epi if (XMLRPC_FAST && XMLRPC_EPI) { $r = xmlrpc_decode_request($response, $uu); xmlrpc_epi_decode_xtypes($r); if (is_array($r) && (count($r)==2) && isset($r["faultCode"]) && isset($r["faultString"])) { return xmlrpc_error($r["faultCode"], $r["faultString"], 1, "GLOBALVARS"); } else { return($r); } } #-- unmarshall XML $response = xml2array($response); #-- fetch content (one returned element) if ($r = @$response["methodResponse,0"]["params,0"]["param,0"]["value,0"]) { $r = xmlrpc_decode_value($r); return($r); } #-- error cases # (we should rather return an error object here) if (($r = @$response["methodResponse,0"]["fault,0"]["value,0"]) && ($r = xmlrpc_decode_value($r))) { return xmlrpc_error($r["faultCode"], $r["faultString"], 1, "GLOBALVARS"); } else { return xmlrpc_error(-32600, "xml+rpc: invalid response", 0, "GLBLVRS"); } return(NULL); } #-- Establish a virtual XML+RPC or XML-RPC server connection (a pseudo # handshake is used to determine supported protocol / extensions). class xmlrpc_connection { #-- init function xmlrpc_connection($url, $autodiscovery=0) { global $xmlrpc_response_headers; $this->server = $url; $this->plus = 0; $this->gzip = 0; #-- handshake to check supported protocol $funcs = $this->call("system.getVersion"); $this->plus = (strpos($xmlrpc_response_headers["accept"], XMLRPC_MIME_NEW) !== false); $this->gzip = (strpos($xmlrpc_response_headers["accept_encoding"], "deflate") !== false); #-- auto-discovery, create 'method' names if ($funcs && (XMLRPC_AUTODISCOVERY || $autodiscovery)) { foreach ($funcs as $fn) { $short = $fn; if ($l = strpos($fn, ".")) { $short = substr($fn, $l + 1); if (substr($fn, 0, $l) == "system") { continue; } } $this->short = create_function("", "return xmlrpc_request('{$this->server}','$fn',func_get_args(),{$this->plus},{$this->gzip});"); } } } #-- generical call (needs func name) function call($method /*, ... */) { $params = func_get_args(); shift($params); $r = xmlrpc_request($this->serverm, $method, $params, $this->plus, $this->gzip); return($r); } } #-- an alias class xmlrpc extends xmlrpc_connection { } ############################################################################ # # # server implementation # # # ############################################################################ #-- Check request and execute function if registered in $xmlrpc_methods[] # array. function xmlrpc_server() { global $xmlrpc_methods; #-- server is active define("XMLRPC_SERVER", getmypid()); if (XMLRPC_DEBUG) { error_reporting(E_ALL^E_NOTICE); } ob_start(); #-- standard reply headers header("Accept: ".XMLRPC_MIME_NEW.", ".XMLRPC_MIME_OLD."; q=0.5"); header("Accept-Encoding: deflate"); header("X-Server: " . XMLRPC_UA); header("Connection: close"); header("Cache-Control: private"); #-- fixes for PHP/Apache if (function_exists("getallheaders")) { foreach (getallheaders() as $i=>$v) { $_SERVER[strtoupper(strtr("HTTP_$i", "-", "_"))] = $v; } } #-- check and get call $allowed = array( "REQUEST_METHOD" => array("POST", "PUT", "CALL"), "CONTENT_TYPE" => array(XMLRPC_MIME_NEW, XMLRPC_MIME_OLD), ); foreach ($allowed as $WHAT=>$WHICH) { if (!in_array(trim(strtok($WRONG=$_SERVER[$WHAT], ";,(")), $WHICH)) { header("Status: 400 Go Away, Stupid!"); if (!$WRONG) { $WRONG = "undefined"; } die("<h2>Error</h2>Your request was bogus, <b>$WHAT</b> must be <i>" . implode("</i> or <i>", $WHICH) . "</i>, but yours was '<tt>$WRONG</tt>'.\n"); } } if (!($xml_request = xmlrpc_fetch_post_chunk())) { header("Status: 500 How Sad"); die("<h2>Error</h2>Could not fetch POST data.\n"); } #-- decipher incoming XML request string $method = ""; if (XMLRPC_FAST && XMLRPC_EPI) { $params = xmlrpc_decode_request($xml_request, $method); xmlrpc_epi_decode_xtypes($params); } else { $params = xmlrpc_request_unmarshall($xml_request, $method); } #-- add the few system.methods() //if (empty($xmlrpc_methods)) { // $xmlrpc_methods = get_defined_functions(); //} $xmlrpc_methods["system"] = "xmlrpc_system_methods"; # a class #-- call $result = xmlrpc_exec_method($method, $params); #-- send back result if (isset($result)) { if (isset($result)) { $resp["methodResponse"]["params"]["param"] = xmlrpc_compact_value($result); } else { $resp["methodResponse"]["params"] = array(); } xmlrpc_send_response($resp); } else { $result = xmlrpc_error(0, "No Result"); xmlrpc_send_response($result); } } #-- decode <methodCall> XML string into understandable chunks, # gives $params as return value and $method name via pass-by-ref function xmlrpc_request_unmarshall(&$xml_request, &$method) { #-- mangle charset if (XMLRPC_AUTO_UTF8) { xmlrpc_decode_utf8xml($xml_request, $_SERVER["CONTENT_TYPE"].$_SERVER["HTTP_CONTENT_CHARSET"]); } #-- decode XML string into PHP arrays $call = xml2array($xml_request, 1); $xml_request = NULL; $call = $call["methodCall,0"]; if (!$call) { xmlrpc_send_response(xmlrpc_error(-32600, "Bad Request, <methodCall> missing")); } $method = $call["methodName,0"][",0"]; if (!$method) { xmlrpc_send_response(xmlrpc_error(-32600, "Bad Request, <methodName> missing")); } $params = array(); foreach ($call["params,1"] as $uu => $param) { $params[] = xmlrpc_decode_value($param["value,0"]); } return($params); } #-- Call the requested method (using the XML-method to PHP-function mapping # table and hints). function xmlrpc_exec_method($method, $params) { global $xmlrpc_methods; if (XMLRPC_DEBUG >= 2) { error_reporting(E_ALL^E_NOTICE); } #-- check if allowed call $rf = strtr($method, ".", "_"); $cl = strtok($method, "."); if (!$xmlrpc_methods[$method] && !$xmlrpc_methods[$cl] && !in_array($method, $xmlrpc_methods) && !in_array($rf, $xmlrpc_methods) && !in_array($cl, $xmlrpc_methods) ) { xmlrpc_send_response(xmlrpc_error(-32601)); } #-- real function call if ($php_func_name = $xmlrpc_methods[$method]) { $rf = $method = $php_func_name; } if (function_exists($rf)) { $result = call_user_func_array($rf, $params); if (XMLRPC_DEBUG >= 4) { fwrite(fopen("/tmp/xmlrpc:func_call_res","w"),serialize(array($rf,$result,$params))); } return($result); } #-- PHP object method calls else { $class = strtok($method, "."); $method = strtok("\000"); if ($uu = $xmlrpc_methods[$class]) { $class = $uu; } if ($class && class_exists($class) && $method) { $obj = new $class; if (method_exists($obj, $method)) { $result = call_user_method_array($method, $obj, $params); //<DEPRECATED> return($result); } } } #-- else error xmlrpc_send_response(xmlrpc_error(-32601)); } #-- Get POST data from PHP (if it gives it to us). function xmlrpc_fetch_post_chunk() { global $HTTP_RAW_POST_DATA; $data = false; if ($f = fopen("php://input", "rb")) { $data = fread($f, 0x0100000); fclose($f); } if (empty($data)) { ini_set("always_populate_raw_post_data", "true"); // well, maybe(!?) $data = $HTTP_RAW_POST_DATA; $HTTP_RAW_POST_DATA = ""; } $enc = trim(strtolower($_SERVER["HTTP_CONTENT_ENCODING"])); $funcs = array("deflate"=>"gzinflate", "gzip"=>"gzdecode", "compress"=>"gzuncompress", "x-gzip"=>"gzdecode", "x-bzip2"=>"bzuncompress"); if ($enc && ($pf = $funcs[$enc]) && function_exists($pf)) { $data = $pf($data); } return($data); } #-- converts UTF-8 documents into Latin-1 ones function xmlrpc_decode_utf8xml(&$xml, $ct) { if (strpos(strtolower($ct), "utf-8") or preg_match('/<\?xml[^>]+encoding=["\']utf-8/i', $xml)) { $xml = utf8_decode($xml); $xml = preg_replace('/(<\?xml[^>]+encoding=["\'])utf-8(["\'])/i', '$1iso-8859-1$2', $xml, 1); } } #-- Creates an error object. function xmlrpc_error($no=-32500, $str="", $type=1, $into_vars=0) { global $xmlrpc_error, $xmlrpc_errorcode; $errors = array( 0 => "No Result", -32300 => "Transport error", -32400 => "Internal Server Error", -32500 => "Application error", -32600 => "Invalid message format / Bad request", -32601 => "Method does not exist", -32602 => "Parameter type mismatch", -32603 => "Internal XML-RPC error", -32604 => "Too many parameters", -32700 => "Not well-formed XML", -32701 => "Unsupported encoding - only ISO-8859-1 and UTF-8 capable", -32702 => "Invalid characters, encoding mismatch", ); #-- build response xml/array if (!($str) && !($str = $errors[$no])) { $str = "Unknown Error"; } if ($into_vars && !XMLRPC_OO) { $xmlrpc_error = $str; $xmlrpc_errorcode = $no; return(NULL); } else { return new xmlrpc_error($no, $str, $type); } } #-- error object class xmlrpc_error { var $type = 1; // else an HTTP error var $no; var $str; function xmlrpc_error($no, $str, $type=1) { $this->type = $type; $this->no = $no; $this->str = $str; } function send() { $error = xmlrpc_compact_value(array( "faultCode" => $no, "faultString" => $str, )); $resp = array( "methodResponse" => array( "fault" => $error ) ); xmlrpc_send_response($resp); } } #-- Sends a response. function xmlrpc_send_response($r) { #-- error objects send itself (by calling _send_response() again ;-) if (is_object($r)) { $r->send(); } #-- answer XML-RPC and XML+RPC requests $ct = trim(strtok(strtolower($_SERVER["CONTENT_TYPE"]), ";,(")); // from original request $cs = XMLRPC_CHARSET; header("Content-Type: $ct; charset=\"$cs\""); #-- make XML document from it if (is_array($r)) { $r = array2xml($r, 1, 'encoding="'.$cs.'" '); } #-- compress answer? if (!headers_sent()) { $enc = trim(strtolower($_SERVER["HTTP_ACCEPT_ENCODING"])); $funcs = array("deflate"=>"gzdeflate", "gzip"=>"gzencode", "compress"=>"gzcompress", "x-gzip"=>"gzencode", "x-bzip2"=>"bzcompress"); if ($enc && ($pf = $funcs[$enc]) && function_exists($pf)) { header("Content-Encoding: $enc"); $r = $pf($r); } } #-- send if (ob_get_level()) { #-- this prevents that PHP errors appear as garbage in our response $add .= "<!--\n" . ob_get_contents() . "\n-->"; ob_end_clean(); } header("Content-Length: " . strlen($r)); print $r . $add; die; } #-- Provides "system.*" method namespace. class xmlrpc_system_methods { function listMethods() { global $xmlrpc_methods; $r = array(); foreach ($xmlrpc_methods as $i=>$i2) { $real = is_int($i) ? $i2 : $i; if (class_exists($real) && ($i2=$real) || class_exists($i2)) { foreach (get_class_methods($i2) as $add) { $r[] = $real.".".$add; } } else { $r[] = $real; } } return($r); } function time() { return new xmlrpc_datetime(time()); } } ############################################################################ # # # misc functions # # # ############################################################################ function xmlrpc_log($message) { } function xmlrpc_die($error="", $str="") { } ############################################################################ # # # data representation mangling # # # ############################################################################ #-- Makes compact-array2xml datavar from a PHP variable. function xmlrpc_compact_value($var, $n=0) { #-- create compact-array2xml tree $root = array( "value,$n" => array(), ); $r = &$root["value,$n"]; #-- detect PHP values to be complex types in XML-RPC if (XMLRPC_AUTO_TYPES && is_string($var)) { if ((strlen($var) >= 64) && preg_match('/^[\w]+=*$/', $var)) { $var = new xmlrpc_base64($var); } elseif ((strlen($var)==17) && ($var[8]=="T") && preg_match('/^\d{8}T\d\d:\d\d:\d\d$/', $var)) { $var = new xmlrpc_datetime($var); } } #-- complex types if (is_object($var)) { $r = $var->out(); } #-- arrays and hashes(structs) elseif (is_array($var)) { if (isset($var[0]) || empty($var)) { $r = array("array,$n" => array("data,0" => array())); $r = &$r["array,$n"]["data,0"]; foreach ($var as $n=>$val) { $r = array_merge($r, xmlrpc_compact_value($val, $n)); } } else { $r = array("struct,$n"=>array()); $r = &$r["struct,$n"]; $n = 0; foreach ($var as $i=>$val) { $r["member,$n"] = array_merge(array( "name,0" => array(",0" => "$i"), ), xmlrpc_compact_value($val, 1)); $n++; } } } #-- simple types elseif (is_bool($var)) { $r = array( "boolean,$n" => array(",0" => ($var?1:0)), ); } elseif (is_int($var)) { $r = array( "int,$n" => array(",0" => $var), ); } elseif (is_float($var)) { $r = array( "double,$n" => array(",0" => $var), ); } elseif (is_string($var)) { $r = array( "string,$n" => array(",0" => $var), ); } return($root); } #-- Makes a PHP array from a compact-xml2array representation. $value must # always be the xml2array elements _below_ the ["value,0"] or ["data,0"] # or ["member,N"] entry. function xmlrpc_decode_value($value) { $val = NULL; foreach ($value as $i=>$d) { #-- use single (text) content xml2array entry as actual $d var if (is_array($d) && isset($d[",0"])) { $d = $d[",0"]; } #-- convert into PHP var based on type $type = strtok($i, ","); switch ($type) { case "array": $val = array(); foreach ($d["data,0"] as $i=>$value) { $val[] = xmlrpc_decode_value($value); } break; case "struct": $val = array(); foreach ($d as $uu=>$d2) { if (($in=$d2["name,0"][",0"]) && ($pos2=1) || ($in=$d2["name,1"][",0"]) && ($pos2=0)) { $val[$in] = xmlrpc_decode_value($d2["value,$pos2"]); } } break; case "": # handles also '<value>s</value>' instead case "0": # of '<value><string>s</string></value>' case "string": $val = is_array($d) ? "" : (string)$d; break; case "base64": $val = (XMLRPC_AUTO_TYPES>=2) ? base64_decode($d) : (string)$d; if ((XMLRPC_AUTO_UTF8 >= 2) && ($uu = utf8_decode($val))) { $val = $uu; } break; // case "real": case "float": // neither is allowed case "double": $val = (double)$d; break; case "i4": case "int": $val = (int)$d; break; case "boolean": $val = (boolean)$d; break; case "dateTime.iso8601": $val = xmlrpc_strtotime($d); break; default: if (defined("XMLRPC_SERVER")) { xmlrpc_send_response(xmlrpc_error(-32600, "Unknown data type '$type'")); } else { echo $xmlrpc_error = "UNKNOWN XML-RPC DATA TYPE '$type'<br>\n"; $xmlrpc_errorcode = -32207; } # echo "<!-- UNKNOWN TYPE $type -->\n"; # xmlrpc_log("bad data type '$type' enountered"); } } return($val); } #-- More complex XML-RPC data types need object representation to # distinguish them from ordinary string and integer vars. class xmlrpc_xtype { var $scalar = ""; var $xmlrpc_type = "string"; var $tag = "string"; function xmlrpc_type($str) { $this->data = $str; } function out() { return array($this->tag.",0" => array(",0"=>$this->scalar)); } } class xmlrpc_base64 extends xmlrpc_xtype { function xmlrpc_base64($str) { $this->tag = "base64"; $this->xmlrpc_type = "base64"; if (XMLRPC_AUTO_UTF8 >= 2) { $str = utf8_encode($str); } if (!preg_match("/^[=\w\s]+$/", $str)) { $this->encode=1; } $this->scalar = $str; } function out() { if (isset($this->encode)) { $this->scalar = chunk_split(base64_encode($this->scalar), 74, "\n"); } return xmlrpc_xtype::out(); } } class xmlrpc_datetime extends xmlrpc_xtype { function xmlrpc_datetime($t) { $this->tag = "dateTime.iso8601"; $this->xmlrpc_type = "datetime"; if (($t > 0) && ($t[8] != "T")) { $this->timestamp = $t; $t = xmlrpc_timetostr($t); } $this->scalar = $t; } } #-- Further simplify use of the above ones. function xmlrpc_base64($string) { return(new xmlrpc_base64($string)); } function xmlrpc_datetime($timestr) { return(new xmlrpc_datetime($timestr)); } #-- Deciphers ISO datetime string into UNIX timestamp. function xmlrpc_strtotime($str) { $tm = explode(":", substr($str, 9)); $t = mktime($tm[0], $tm[1], $tm[2], substr($str, 4, 2), substr($str, 6, 2), substr($str, 0, 4)); return($t); } function xmlrpc_timetostr($time) { return(gmstrftime("%Y%m%dT%T", $time)); } #-- helping hand for the xmlrpc-epi extension of php function xmlrpc_epi_decode_xtypes(&$r) { if (is_object($r) && isset($r->xmlrpc_type)) { if (isset($r->timestamp)) { $r = $r->timestamp; } else { $r = $r->scalar; } } elseif (is_array($r)) { foreach ($r as $i=>$v) { xmlrpc_epi_decode_xtypes($r[$i]); } } } ############################################################################ # # # simplified XML parser # # # ############################################################################ #-- Encode the two chars & and < into htmlentities (there is nothing said # about the possible other entities in the XML-RPC spec). function xml_entities($str) { $e = array( "&" => "&", "<" => "<", // ">" => ">", ); return(strtr($str, $e)); } function xml_decode_entities($str) { $e = array( "<" => "<", ">" => ">", "'" => "'", """ => '"', "&" => "&", ); if (strpos($e, "&#") !== false) { $e = preg_replace('/&#(\d+);/e', 'chr($1)', $e); $e = preg_replace('/&#x([\da-fA-F]+);/e', 'chr(hexdec("$1"))', $e); } return(strtr($str, $e)); } #-- Can split simplified XML into a PHP array structure. The now used # 'compact' format will yield tag sub arrays with an "*,0" index and # just [",0"] for text nodes. function xml2array($xml, $compact="ALWAYS") { $r = array(); if (function_exists("xml_parser_create") && (strlen($xml) >= 512)) { $r = xml2array_php($xml); } else { xml2array_parse($xml, $r, $compact); } return($r); } #-- Recursively builds an array of the chunks fetched via strtok() from # the original XML input string. function xml2array_parse(&$string, &$r, $compact=1) { $n = 0; do { #-- split chunks $l = strpos($string, "<"); $p = strpos($string, ">", $l); $text = $attr=$close = $tag = false; if ($l === false) { $text = $string; $string = false; } else { $tag = strtok(substr($string, $l+1, $p-$l-1), " "); if ((strncmp($tag, "![CDATA[", 8)==0) && ($p = strpos($string, "]]>", $l))) { $text = substr($string, $l+9, $p-$l-9); } else { if ($l) { $text = xml_decode_entities(substr($string, 0, $l)); } $attr = strtok("\000"); $close = $attr && ($attr[strlen($attr)-1]=="/"); $string = substr($string, $p+1); } } #-- insert text/body content into array if (trim($text)) { # if ($compact) { $r[",$n"] = $text; # } # else { # $r[] = $text; # } $n++; } #-- recurse for tags if ($tag && ($tag[0] >= 'A')) { #-- don't read <? <! </ pseudo-tags # if ($compact) { $r["$tag,$n"] = array(); $new = &$r["$tag,$n"]; # } else { # $r[] = array($tag => array()); # $new = &$r[count($r)-1][$tag]; # } if (!$close) { xml2array_parse($string, $new, $compact); } $n++; } #-- stop if no more tags or content if (empty($tag) && empty($text) || empty($string)) { $tag = "/"; } } while ($tag[0] != "/"); } #-- Uses the XML extension of PHP to convert an XML stream into the # compact array representation. function xml2array_php(&$xml, $compact=1) { $p = xml_parser_create(xml_which_charset($xml)); xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, false); xml_parser_set_option($p, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); xml_parse_into_struct($p, $xml, $struct); $a = array(); // will hold all tag nodes $tree = array(&$a); // stack of pointers to last node of any tree level $in = &$a; // pointer to last created node foreach ($struct as $t) { unset($value); extract($t); $depth = count($tree) - 1; $in = &$tree[$depth]; $tag .= "," . count($in); //echo "#$depth, TAG=\"$tag\", TYP=$type, LEV=$level, VAL=$value\n"; switch ($type[1]) { #-- OpEN case "p": $in[$tag] = array(); if ($type=="open") { $tree[] = &$in[$tag]; } if (isset($value) && trim($value)) { $in[$tag][",0"] = $value; } break; #-- CoMPLETE case "o": $in[$tag] = array(); if (isset($value) && trim($value)) { $in[$tag][",0"] = $value; } break; #-- ClOSE case "l": array_pop($tree); break; #-- CdATA - usually just whitespace case "d": if (isset($value) && trim($value)) { $in[",".count($in)] = $value; } break; default: // case "attribute": // and anything else we do not want } } return($a); } function xml_which_charset(&$xml) { return( strpos(strtok($xml, "\n"), '-8859-1"') ? "iso-8859-1" : "utf-8" ); } ############################################################################ # # # simplified XML creator # # # ############################################################################ #-- This is the opposite of the above xml2array, and can also work with the # so called $compact format. function array2xml($r, $compact=1, $ins="") { $string = "<?xml version=\"1.0\" $ins?>"; array2xml_push($string, $r, $compact); return($string); } #-- Recursively throws out the XMLified tree generated by the xml2array() # 'parser' function. function array2xml_push(&$string, &$r, $compact, $ind=-1) { $old_ind = ++$ind - 1; if ($old_ind < 0) { $old_ind = 0; } foreach ($r as $i=>$d) { $d = &$r[$i]; if (is_scalar($d)) { $string .= xml_entities($d); } elseif (is_array($d)) { if ($compact) { $i = strtok($i, ","); } $ls = str_repeat(" ", $ind); $string .= "\n$ls<$i>"; $string .= array2xml_push($string, $d, $compact, $ind); $ls = str_repeat(" ", $old_ind); $string .= "</$i>\n$ls"; } } } ?> |
Added ext/contrib/archive/xmlrpc.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | XML-RPC is a "standard" (well, not yet exactly) for accessing remotely provided 'Web services'. More exactly it is just a complicated encoding standard for calling functions and procedures on a remote Web server (and getting its calculation or data request results of course). It is still in wide use for many interesting features like accessing database content, searching, data conversion, and so on. It started as a lightweight alternative to SOAP, which currently is more on the rise. While SOAP is much more bloated, also XML-RPC is not the quickest RPC format available, is not really standards-compliant (bogus specs over the time), and so has probably only a limited lifetime now. Therefore you should try to provide your services and access others` via vanilla HTTP requests (form or url encoding), when possible; use the "http.php" class for this. (There is also a faster PHP-RPC standard on the rise, which provides type-safe data transport over compressed and fast connections, without the encoding overhead and charset issues when using XML-RPC.) xmlrpc.php ¯¯¯¯¯¯¯¯¯¯ The 'xmlrpc.php' script implements the XML-RPC spec., but adds a few extensions, namely use of the (yet unregistered) "application/rpc+xml" MIME type and compressed HTTP transportation. It uses a builtin stupid XML parser (for the highly simplified XML-RPC message content) and thus is totally independent of any PHP extensions. It of course takes advantage of the XML extension where present (a lot faster), and it even can make use of Epinions XML-RPC extension for PHP (really fast than). It is mostly not object-oriented, but extremely easy to use for building XML-RPC servers or calling remote procedures. configuration ¯¯¯¯¯¯¯¯¯¯¯¯¯ There are a few constants and variables that the 'xmlrpc.php' script respects. XMLRPC_PLUS If set to 1 enables use of the "application/rpc+xml" MIME type and request compression per default (for server and client). In 2004 still not the recommended setting. XMLRPC_AUTO_TYPES Allows the request encoder to automatically determine the <base64> and <dateTime.iso8061> types, even if you just used them as scalar PHP values. Otherwise you had to use 'new xmlrpc_base64("STrinG==")' and 'new xmlrpc_datetime("20001020T00:00:00")' to prepare such values. XMLRPC_AUTO_UTF8 Takes care of transforming the complete RPC messages into/from UTF-8, what is useful if your scripts deal only with Latin1 and always expect this. <base64> are also de/encoded if you set this constant to 2. XMLRPC_CHARSET The whole script is currently optimized to produce UTF-8 and decode requests from/into Latin-1 for your scripts. XMLRPC_FAST Enables use of Epinions XML-RPC extension module for PHP automatically where available. You only want to disable this for debugging purposes. XMLRPC_OO Engages error result objects, else you had to use the two global vars "$xmlrpc_error" and "$xmlrpc_errorstr" to detect such cases. If you enable it you must however compare all xmlrpc_request() result values against being an object (what does not happen for succeeded XML-RPC requests). XMLRPC_AUTODISCOVERY If you create a "xmlrpc" or "xmlrpc_connection" object and this is enabled, you would get the object with function names of the automatically instantiated methods of the remotely provided service wrapped into one object (not yet), much like in the Python library for xmlrpc. XMLRPC_LOG Creates a log file for incoming requests to the _server() part of xmlrpc (whenerver you activate it with the _server() call). There are also a few automatically defined values, which you shouldn't care about: XMLRPC_MIME Contains the currently selected default MIME type for transport. XMLRPC_MIME_NEW Contains the newer MIME type value. Do not change. XMLRPC_MIME_OLD For compatibility with older XML-RPC clients and servers. Do not change. XMLRPC_ACCEPT Again the MIME Types wrapped into a HTTP Accept: header for requests and responses. XMLRPC_EPI Tells if the Epinions extension is available. server configuration ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ $xmlrpc_methods[] Every accessible method (for remote calls) must be defined here, for use with the xmlrpc_server(). There is a separate section on this one. making xmlrpc() requests ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ You can call a remote procedure by just using the short xmlrpc() call syntax: $result = xmlrpc("http://example.com/rpc.php", "the.function", 1, 2, 3); Where 1, 2 and 3 would be parameters to "the.function" on the remote server. The number of parameters is not limited, and you do not need to give one at all (if the remote procedure does not require them. The parameter values are automatically encoded into XML-RPC representations except for <base64> and <dateTime.iso8061> ones, for which you needed to create objects first. The $result of course recieved in ordinary PHP representation of the remote functions result value. xmlrpc_request() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Is basically the same as calling the xmlrpc() function, but that all parameters given to the remote function are now to be passed as array in the third parameter: $params = array( "param1", "param2", "param3" ); $r = xmlrpc_request("server.com:80", "remoteMethod", $params); Also a fourth parameter to xmlrpc_request (boolean) says if to use the old XML-RPC or the faster XML+RPC interface. But beware, that this could fail if you connect to an older server. xmlrpc_connection ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ You can also establish a 'connection' (this is purely virtual) to a remote XML-RPC server, using a xmlrpc_connection object as follows: $xc = new xmlrpc_connection("http://example.com/rpc.php"); Then you could regularily call remote functions on that server: $result1 = $xc->call("function1"); $result2 = $xc->call("function2", 2, $result1, 0x5F02); The xmlrpc_connection automatically chooses XML+RPC if available with the remote server. data types ¯¯¯¯¯¯¯¯¯¯ Unless XMLRPC_AUTO_TYPES was enabled (discouraged, because this is considered 'unreliable type guessing') you need to explicetely mark parameters passed to the xmlrpc() or xmlrpc_request() calls for their later XML-RPC type. To do so, you have the two class types 'xmlrpc_datetime' and 'xmlrpc_base64' availabe. Use them as follows: $param1 = new xmlrpc_base64( base64_encode($string1) ); $p2 = new xmlrpc_datetime( time() + 60*60*24*7 ); $r = xmlrpc("www.server.com/rpc/", "function1", $param1, $p2); Please note, that you needed to call base64_encode() yourself, and that the _datetime() can also use standard Unix timestamps as input. The XML-RPC <dateTime.iso8601> entites are, btw, automatically converted into Unix timestamps, if returned as result from xmlrpc() and xmlrpc_request() calls. This happens regardless of XMLRPC_AUTO_TYPES. If XMLRPC_AUTO_TYPES is set to 2, then even <base64> result values would be automatically converted into their plain (binary) string representation. "Bugs" ¯¯¯¯¯¯ pass-by-reference is not possible ;) xmlrpc_server() use ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ To make a set of functions available for remote calls, you would create an interface script and make its URL public. Assuming that you had a subdirectory "./myrpc" on your server, you would likely want to create the file "./myrpc/index.php" with following content: <?php $xmlrpc_methods = array( "myFunction", "mySecondOne", ); include("xmlrpc.php"); xmlrpc_server(); ?> So, by calling the xmlrpc_server() you make all registered functions ($xmlrpc_methods) available with the URL "xml+rpc://example.com/myrpc/" for remote calls. $xmlrpc_methods[] ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ All function names you list in this array (before calling the xmlrpc_server() function) will be available for remote calls. The function names are mapped to remote method names by having the _ underscore as alias the the . dot, which is commonly used. So a function whose name was "tools_register" was available as remotely callable method "tools_register" or "tools.register". Also with xmlrpc_server() it is possible to register member methods of object classes as remotely callable methods. All you needed to do is list your class in $xmlrpc_methods[]. You can also give aliases, both for function names and for object classes: $xmlrpc_methods["callable.methodname"] = "here_function_name"; $xmlrpc_methods["section"] = "here_class_name"; The member methods of a class cannot be aliased however. xmlrpc_server() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Just fetches the current request, decodes it and executes the destination method (PHP function) if listed in the global $xmlrpc_methods[] variable. It automatically exits after sending the response or an error. So this is the last command in your xmlrpc wrapper script. xmlrpc_fetch_post_chunk() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Begs PHP for the complete POST data stream. It only has two options to do so and may fail with some Webservers and earlier PHP versions. In either case try to set the "always_populate_raw_post_data" option in php.ini or from within a .htaccess file. To allow the server part to receive the XML-RPC message, you either need PHP 4.3 or later, or configure your PHP interpreter specifically to pass in the POSTed data stream. In you php.ini ([PHP] section) add: always_populate_raw_post_data = 1 Or following in a .htaccess per-dir configuration file for Apache: php_option always_populate_raw_post_data=1 xmlrpc_send_response() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Is called from within xmlrpc_server() to send the response for the processed request (also sends error responses). xmlrpc_error() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Creates a XML-RPC error result array. --------------------------------------------------------------------------- internals --------------------------------------------------------------------------- Unless you are interrested in an in-deep discussion of the "xmlrpc.php" you should effectively stop reading here. xmlrpc data representation encoders ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ This lib uses the simple xml2array() compact format to do the initial work of converting a XML file into an array representation. Various design restrictions of the XML-RPC message format then impose certain structures inside of the xml2array-compact representation, what is taken adavantage of. For example <struct> entries have in the compact representation sub-elements like ["member,0"], ["member,1"], ["member,2"] and so on. Each of which then has two sub elements: ["name,0"] and ["value,1"]. The XML-RPC <array> instead had one ["data,0"] with sub-arrays of ["value,0"], ["value,1"], ["value,2"] and so on, which would be recursively feed through: xmlrpc_decode_value() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Makes a PHP representation of a part (one must start it with the content of a ["value,0"]) from a xml2array()-compact representation made out of a XML-RPC message. xmlrpc_compact_value() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Converts a PHP array or scalar variable into an array suitable for transformation into a XML-RPC message string using the array2xml() function then. generic functions ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ The xml2array() and array2xml() functions are stupid XML parsers and probably only suitable for XML-RPC messages. xml2array() ¯¯¯¯¯¯¯¯¯¯¯ Can decode a SimplifiedXML document into an array structure - and this in two formats. Internall xml+rpc uses only the so called "$compact format". If we had a XML document like the following: <xml> <more> <string> String </string> </more> <more> <string> String2 </string> <int>5</int> </more> </xml> It would return for the $compact=1 format, something like: array( "xml,0" => array( "more,0" => array( "string,0" = array( ",0" => " String " ) ) "more,1" => array( "string,0" = array( ",0" => " String2 " ), "int,1" = array( ",0" => 5 ) ) ) ); Where every tagname had a ","+NUMBER suffix, and text nodes would start with the comma. The numbers are always counted up in each nesting level from 0, regardless if it counted text or tag nodes. The not-compact format would hold another subarray to denote a deeper level tag node, but leave the text nodes as entries into the ordering array level. This was more suitable for XML like files, where you had mixed text and tag nodes in a level. For example: <html> string1 <b>string2</b> </html> Would become in the not-compact format: array( 0 => array( "html" => array( 0 => "\n string1\n " 1 => array( "b" => array( 0 => "string2", ) ) ) ) array2xml() ¯¯¯¯¯¯¯¯¯¯¯ Regenerates a XML stream from an array structure like the one emitted by xml2array(). other functions ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ If you want a different behaviour, you might want to alter one of the following functions. xmlrpc_method_call() ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Is responsible in the _server() part for invoking the requested function. It does so by using the $xmlrpc_methods[] array as mapping to the PHP functions to activate. If you would like to have a better mapping support, or even to add parameter type and number checking, then this is where you would want to start editing the code. |
Deleted ext/contrib/exceptions.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted ext/contrib/fix.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added ext/contrib/fix_magic_quotes.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 | <?php /* api: PHP type: intercept title: PHP fixes descriptions: removes bogus magic_quotes and left over superglobals priority: auto category: library conflicts: strike_register_globals, strip_wonderful_slashes Outdated and bogus PHP settings (register_globals and magic_quotes) are defended by this script, so code cannot be negatively impacted. It can always be loaded as it doesn't cause problems or speed disadvantages on correctly configured servers. THE "PHP.INI" SHOULD BE FIXED PREFERABLY. */ #-- strike register_globals (injected variables) if (ini_get("register_globals") == "1") { ewiki_recursive_unset($GLOBALS, $_REQUEST); ini_set("register_globals", 0); } #-- strip any \'s if magic_quotes (variable garbaging) is still enabled if (ini_get("magic_quotes_gpc") && get_magic_quotes_gpc()) { ewiki_recursive_stripslashes($_REQUEST); ewiki_recursive_stripslashes($_GET); ewiki_recursive_stripslashes($_POST); ewiki_recursive_stripslashes($_COOKIE); ewiki_recursive_stripslashes($_ENV); ewiki_recursive_stripslashes($_SERVER); ini_set("magic_quotes_gpc", 0); } #-- now that one is really dumb set_magic_quotes_runtime(0); #-- implementation function ewiki_recursive_unset(&$TO, $FROM) { foreach ($FROM as $var=>$value) { if (isset($TO[$var]) && ($TO[$var]==$FROM[$var])) { unset($TO[$var]); unset($TO[$var]); // double unset to work around ZE-num/assoc-hashcode bug } } } function ewiki_recursive_stripslashes(&$var) { if (is_array($var)) { foreach ($var as $key=>$item) { ewiki_recursive_stripslashes($var[$key]); } } else { $var = stripslashes($var); } } ?> |
Added ext/contrib/header_errors.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 | <?php /* The error handler provided here will feed all errors and warnings into HTTP headers of the form "X-Error-NNNNN: ...", so they can't disturb page output or make XML documents invalid. This allows to turn on complete error_reporting() without any functionality loss due to premature output. You of course need a good Web browser that can easily display all response headers then for developing. */ set_error_handler("ewiki_http_header_errors"); ini_set("html_errors", 0); function ewiki_http_header_errors($errno, $msg, $file, $line, $lvars) { static $error_types = array( E_PARSE => "PARSE ERROR", E_ERROR => "ERROR", E_WARNING => "WARNING", E_NOTICE => "NOTICE", E_STRICT => "STRICT", E_USER_ERROR => "USER ERROR", E_USER_WARNING => "USER WARNING", E_USER_NOTICE => "USER NOTICE", ); ($errtype = $error_types[$errno]) or ($errtype = "UNDEF ERROR"); #-- check for @ and disabled errors $emask = get_cfg_var("error_reporting"); if (! ($emask & $errno)) { return; } #-- output $msg = strtr($msg, "\r\n\t\f", " "); $msg = "$errtype: $msg in $file, line #$line"; if (headers_sent()) { print "\n<!--<div class=\"php-error\">$msg</div>-->\n"; } else { $no = crc32($msg); $no = ($no & 0xFFFF) ^ ($no >> 16); header("X-Error-$no: $msg"); if ($errno == E_FATAL) { header("Status: 500 Something bad happened"); } } } ?> |
Deleted ext/contrib/hiddenerrors.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted ext/contrib/http.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted ext/contrib/http.txt.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added ext/contrib/http_query.class.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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | <?php /* api: PHP type: functions category: library priority: optional provides: http-request title: HTTP requests description: implements HTTP protocol, various request methods supported url: http://freshmeat.net/p/upgradephp version: 11.3 This snippet implements HTTP queries, and allows for most request methods, content types and encodings. It is useful for contacting scripts made to serve HTML forms. - does neither depend upon wget or curl, nor any other extension - you can add ->$params (form variables) on the fly, it's a hash - if the initial URL contains a query string, the vars will be extracted first - set the ->$enc very carefully, because many CGI apps and HTTP servers can't deal with it (else "gzip" and "deflate" are nice) - there are abbreviations for the content ->$type values (namely "form" , "url" and "php") - user:password@ pairs may be included in the initially given URL - headers always get normalized to "Studly-Caps" - won't support keep-alive connections - for PUT and other methods, the ->$params var may just hold the request body - files can be added to the ->params array as hash with specially named fields: "content"/"data", and "filename"/"name" , "type" - you can add authentication information using the standard notation "http://user:passw@www.example.com/..." for ->$url and ->$proxy A response object will have a ->$content field, ->$headers[] and ->len, ->type attributes as well. You could also ->decode() the body, if it is app/vnd.php.serialized or app/x-www-form-urlencoded. Public Domain (use freely, transform into any other license, like LGPL, BSD, MPL, ...; but if you change this into GPL please be so kind and leave your users a hint where to find the free version). */ #-- request objects class http_request { var $method = "GET"; var $proto = "HTTP/1.1"; var $url = ""; var $params = array(); // URL/form post vars, or single request body str var $headers = array(); var $cookies = array(); var $type = "url"; // content-type, abbrv. for x-www-form-... var $enc = false; // "gzip" or "deflate" var $error="", $io_err=0, $io_err_s=""; var $active_client = 1; // enables redirect-following var $redirects = 3; var $proxy = false; // set to "http://host:NN/" var $timeout = 15; #-- constructor function http_request($method="GET", $url="", $params=NULL) { $this->headers["User-Agent"] = "http_query/17.2 {$GLOBALS[ewiki_config][ua]}"; $this->headers["Accept"] = "text/html, application/xml;q=0.9, text/xml;q=0.7, xml/*;q=0.6, text/plain;q=0.5, text/*;q=0.1, image/png;q=0.8, image/*;q=0.4, */*+xml;q=0.3; application/x-msword;q=0.001, */*;q=0.075"; $this->headers["Accept-Language"] = "en, eo, es;q=0.2, fr;q=0.1, nl;q=0.1, de;q=0.1"; $this->headers["Accept-Charset"] = "iso-8859-1, utf-8"; $this->headers["Accept-Feature"] = "textonly, tables, !tcpa, !javascript, !activex, !graphic"; $this->headers["Accept-Encoding"] = "deflate, gzip, compress, x-gzip, x-bzip2"; //$this->headers["Referer"] = '$google'; $this->headers["TE"] = "identity, chunked, binary, base64"; $this->headers["Connection"] = "close"; //$this->headers["Content-Type"] = & $this->type; if (isset($params)) { $this->params = $params; } if (strpos($method, "://")) { $url = $method; # glue for incompat PEAR::Http_Request $method = "GET"; } $this->method($method); $this->setURL($url); } #-- sets request method function method($str = "GET") { $this->method = $str; } #-- special headers function setcookie($str="name=value", $add="") { $this->cookies[strtok($str,"=")] = strtok("\000").$add; } #-- deciphers URL into server+path and query string function setURL($url) { if ($this->method == "GET") { $this->url = strtok($url, "?"); if ($uu = strtok("\000")) { $this->setQueryString($uu); } } else { $this->url = $url; } } #-- decodes a query strings vars into the $params hash function setQueryString($qs) { $qs = ltrim($qs, "?"); parse_str($qs, $this->params); } #-- returns params as querystring for GET requests function getQueryString() { $qs = ""; if (function_exists("http_build_query")) { $qs = http_build_query($this->params); } else { foreach ($this->params as $n=>$v) { $qs .= "&" . urlencode($n) . "=" . urlencode($v); } $qs = substr($qs, 1); } return($qs); } #-- transforms $params into request body function pack(&$path) { $m = strtoupper($this->method); #-- GET, HEAD if (($m == "GET") || ($m == "HEAD")) { $BODY = ""; $path .= (strpos($path, "?") ? "&" : "?") . $this->getQueryString(); } #-- POST elseif (($m == "POST") && is_array($this->params)) { #-- known encoding types $type = $this->type($this->type, 0); if ($type == "url") { $BODY = $this->getQueryString($prep=""); } elseif ($type == "php") { $BODY = serialize($this->params); } elseif ($type == "form") { // boundary doesn't need checking, unique enough $bnd = "snip-".dechex(time())."-".md5(serialize($this->params)) . "-".dechex(rand())."-snap"; $BODY = ""; foreach ($this->params as $i=>$v) { $ct = "text/plain"; $inj = ""; if (is_array($v)) { ($ct = $v["ct"].$v["type"].$v["content-type"]) || ($ct = "application/octet-stream"); $inj = ' filename="' . urlencode($v["name"].$v["file"].$v["filename"]) . '"'; $v = $v["data"].$v["content"].$v["body"]; } $BODY .= "--$bnd\015\012" . "Content-Disposition: form-data; name=\"".urlencode($i)."\"$inj\015\012" . "Content-Type: $ct\015\012" . "Content-Length: " . strlen($v) . "\015\012" . "\015\012$v\015\012"; } $BODY .= "--$bnd--\015\012"; $ct = $this->type("form") . "; boundary=$bnd"; } #-- ignore else { $this->error = "unsupported POST encoding"; // return(false); $BODY = & $this->params; } $this->headers["Content-Type"] = isset($ct) ? $ct : $this->type($type, 1); } #-- PUT, POST, PUSH, P* elseif ($m[0] == "P") { $BODY = & $this->$params; } #-- ERROR (but don't complain) else { $this->error = "unsupported request method '{$this->method}'"; // return(false); $BODY = & $this->params; } return($BODY); } #-- converts content-type strings from/to shortened nick function type($str, $long=1) { $trans = array( "form" => "multipart/form-data", "url" => "application/x-www-form-urlencoded", "php" => "application/vnd.php.serialized", ); $trans["multi"] = &$trans["form"]; if ($long) { $new = $trans[$str]; } else { $new = array_search($str, $trans); } return( $new ? $new : $str ); } #-- initiate the configured HTTP request ------------------------------ function go($force=0, $asis=0) { #-- prepare parts $url = $this->prepare_url(); if (!$url && !$force) { return; } $BODY = $this->body($url); if (($BODY===false) && !$force) { return; } $HEAD = $this->head($url); #-- open socket if (!$this->connect($url)) { return; } #-- send request data fwrite($this->socket, $HEAD); fwrite($this->socket, $BODY); $HEAD = false; $BODY = false; #-- read response, end connection while (!feof($this->socket) && (strlen($DATA) <= 1<<22)) { $DATA .= fread($this->socket, 32<<10); #echo "fread(".strlen($DATA).") "; } fclose($this->socket); unset($this->socket); #-- for raw http pings if ($asis) { return($DATA); } #-- decode response $r = new http_response(); $r->from($DATA); // should auto-unset $DATA #-- handle redirects if ($this->active_client) { $this->auto_actions($r); } #-- fin return($r); } #-- alias function start($a=0, $b=0) { return $this->go($a, $b); } #-- creates socket connection function connect(&$url) { if ((isset($this->socket) and !feof($this->socket)) or ($this->socket = fsockopen($url["host"], $url["port"], $this->io_err, $this->io_err_s, $this->timeout))) { socket_set_blocking($this->socket, true); socket_set_timeout($this->socket, $this->timeout, 555); return(true); } else { $this->error = "no socket/connection"; return(false); } } #-- separate URL into pieces, prepare special headers function prepare_url() { $this->setURL($this->url); if (!$this->proxy) { $url = parse_url($this->url); if (strtolower($url["scheme"]) != "http") { $this->error = "unsupported protocol/scheme"; return(false); } if (!$url["host"]) { return; } if (!$url["port"]) { $url["port"] = 80; } if (!$url["path"]) { $url["path"] = "/"; } if ($url["query"]) { $url["path"] .= "?" . $url["query"]; } $proxy = ""; } else { $url = parse_url($this->proxy); $url["path"] = $this->url; $proxy = "Proxy-"; $this->headers["Proxy-Connection"] = $this->headers["Connection"]; } #-- inj auth headers if ($url["user"] || $url["pass"]) { $this->headers[$proxy."Authorization"] = "Basic " . base64_encode("$url[user]:$url[pass]"); } return($url); } #-- generates request body (if any), must be called before ->head() function body(&$url) { #-- encoding of variable $params as request body (according to reqmethod) $BODY = $this->pack($url["path"]); if ($BODY === false) { return false; } elseif ($len = strlen($BODY)) { $this->headers["Content-Length"] = $len; } $enc_funcs = array("gzip"=>"gzencode", "deflate"=>"gzinflate", "bzip2"=>"bzcompress", "x-bzip2"=>"bzcompress", "compress"=>"gzcompress"); if ((strlen($BODY) >= 1024) && ($f = $enc_funcs[$this->enc]) && function_exists($f)) { $BODY = $f($BODY); $this->headers["Content-Encoding"] = $this->enc; $this->headers["Content-Length"] = strlen($BODY); } return($BODY); } #-- generates request head part function head(&$url) { #-- inject cookie header (if any) if ($this->cookies) { $c = ""; foreach ($this->cookies as $i=>$v) { $c .= "; " . urlencode($i) . "=" . urlencode($v); } $this->headers["Cookie"] = substr($c, 2); $this->headers["Cookie2"] = '$Version="1"'; } #-- request head $CRLF = "\015\012"; $HEAD = "{$this->method} {$url[path]} {$this->proto}$CRLF"; $HEAD .= "Host: {$url[host]}$CRLF"; foreach ($this->headers as $h=>$v) { $HEAD .= trim($h) . ": " . strtr(trim($v), "\n", " ") . $CRLF; } $HEAD .= $CRLF; return($HEAD); } #-- perform some things automatically (redirects) function auto_actions(&$r) { #-- behaviour table static $bhv = array( "failure" => "204,300,304,305,306", "clean_::POST" => "300,301,302,303,307", "clean_::PUT" => "300,301,302,303,307", "clean_::GET" => "300", // $params:=undef "GET_::POST" => "303", "GET_::PUT" => "303", // downgrade $method:=GET ); #-- failure if (strstr($this->behaviour_table["failure"], $r->status)) { return; } #-- HTTP redirects if (($pri_url=$r->headers["Location"]) || ($pri_url=$r->headers["Uri"])) { if ((($this->redirects--) >= 0) && ($r->status >= 300) && ($r->status < 400)) { $m = strtoupper($this->method); if (strstr($this->behaviour_table["clean_::$m"], $r->status)) { unset($this->params); } if (strstr($this->behaviour_table["GET_::$m"], $r->status)) { $this->method("GET"); } $this->setURL($pri_url); $this->go(); } } } #-- aliases for compatiblity to PEAR::HTTP_Request function sendRequest() { return $this->go(); } function setBasicAuth($user, $pw) { $this->url = preg_replace("#//(.+?@)?#", "//$user@$pw", $this->url); } function setMethod($m) { $this->method($m); } function setProxy($host, $port=8080, $user="", $pw="") { $auth = ($pw ? "$user:$pw@" : ($user ? "$user@" : "")); $this->proxy = "http://$auth$server:$port"; } function addHeader($h, $v) { $this->headers[$h] = $v; } function getResponseStatus() { $this->headers[$h] = $v; } } class http_query extends http_request { /* this is just an alias */ } #-- every query result will be encoded in such an object -------------------- class http_response { var $status = 520; var $status_str = ""; var $headers_str = ""; var $headers = array(); var $len = 0; var $type = "message/x-raw"; var $content = ""; function http_response() { } #-- fill object from given HTTP response BLOB function from(&$SRC) { $this->breakHeaders($SRC); // split data into body + headers $SRC = false; $this->decodeHeaders(); // normalize header names $this->headerMeta(); $this->decodeTransferEncodings(); // chunked $this->decodeContentEncodings(); // gzip, deflate $this->len = strlen($this->content); } #-- separates headers block from response body part function breakHeaders(&$DATA) { $l = strpos($DATA, "\012\015\012"); $skip = 3; $r = strpos($DATA, "\012\012"); if ($r && ($r<$l)) { $l = $r; $skip = 2; } if (!$l) { $l = strlen($DATA); } $this->headers_str = rtrim(substr($DATA, 0, $l), "\015"); $this->content = substr($DATA, $l + $skip); $this->body = & $this->content; $this->data = & $this->content; // aliases $this->ct = & $this->type; } #-- splits up the $headers_str into an array and normalizes header names function decodeHeaders() { #-- normalize linebreaks $str = & $this->headers_str; // $str = str_replace("\n ", " ", $str); $str = str_replace("\r", "", $str); #-- strip headline $nl = strpos($str, "\n") + 1; $this->proto = strtok(substr($str, 0, $nl), " "); $this->status = (int) strtok(" "); $this->status_str = strtok("\000\r\n"); if ($this->status == 100) { $this->full_duplex = 1; } #-- go through lines, split name:value pairs foreach (explode("\n", substr($str, $nl)) as $line) { $i = trim(strtok($line, ":")); $v = trim(strtok("\000")); #-- normalize name look&feel $i = strtr(ucwords(strtolower(strtr($i, "-", " "))), " ", "-"); #-- add to, if key exists if (!empty($this->headers[$i])) { $this->headers[$i] .= ", ".$v; } else { $this->headers[$i] = $v; } } } #-- extract interesting values function headerMeta() { $this->len = strlen($this->content); $this->type = trim(strtok(strtolower($this->headers["Content-Type"]), ";")); } #-- strip any content transformation function decodeTransferEncodings() { $enc = trim(strtok(strtolower($this->headers["Transfer-Encoding"]), ",;")); if ($enc) { switch ($enc) { #echo "ENC($enc) "; case "chunked": $this->decodeChunkedEncoding(); break; case "base64": $this->content = base64_decode($this->content); $this->len = strlen($this->content); break; case "identity": case "binary": case "7bit": case "8bit": break; default: trigger_error("http_response::decodeTransferEncodings: unkown TE of '$enc'\n", E_WARNING); } } } #-- scripts on HTTP/1.1 servers may send fragmented response function decodeChunkedEncoding() { $bin = ""; # decoded data $p = 0; # current string position #file_put_contents("/tmp/1", $this->content); while ($p < strlen($this->content)) { #-- read len token $n = strtok(substr($this->content, $p, 20), "\n"); #echo "CHUNK($p,$n) "; $p += strlen($n)+1; #echo "CHUNK2($p,$n) "; #-- make integer $n = hexdec(trim($n)); if ($n===0) { break; } elseif (!$n) { break; //WARN } $n += 1; #-- read data $bin .= substr($this->content, $p, $n); $p += $n + 1; #echo "CHUNK3($p,$n) "; } $this->content = $bin; unset($bin); $this->len = strlen($this->content); } #-- uncompress response body function decodeContentEncodings() { $enc = trim(strtok(strtolower($this->headers["Content-Encoding"]), ";,")); $dat = &$this->content; if ($enc == "deflate") { $dat = gzinflate($dat); } elseif (($enc == "gzip") || ($enc == "x-gzip")) { if (function_exists("gzdecode")) { $dat = gzdecode($dat); } else { $dat = gzinflate(substr($dat, 10, strlen($dat)-18)); } } elseif ($enc == "compress") { $dat = gzuncompress($dat); } elseif (($enc == "x-bzip2") || ($enc == "bzip2")) { if (function_exists("bzdecompress")) { $dat = bzdecompress($dat); } else trigger_error("http_response::decodeContentEncoding: bzip2 decoding isn't supported with this PHP interpreter version", E_WARNING); } $this->len = strlen($this->content); } #-- can handle special content-types (multipart, serialized, form-data) function decode() { $t = http_request::type($this->type, 0); if ($t == "php") { return(unserialize($this->content)); } elseif ($t == "url") { parse_str($this->content, $r); return($r); } elseif ($t == "form") { // oh, not yet exactly } } #-- aliases for compatiblity to PEAR::HTTP_Request function getResponseBody() { return $this->content; } function getResponseStatus() { return $this->status; } function getResponseCode() { return $this->status; } function getResponseHeader($i=NULL) { if (!isset($i)) { return $this->headers; } $i = strtolower($i); foreach ($this->headers as $h=>$v) { if (strtolower($h)==$i) { return $v; } } } } ?> |
Added ext/contrib/http_query.class.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | Note: This class and file will be renamed into "xhttp..." in the near feature, to prevent clashes with the old PEAR class. http.php ¯¯¯¯¯¯¯¯ This script provides the easy to use "http_request" class ("http_query" is an alias). You can contact forms or simply retrieve files with it. Unlike fopen_wrappers, you get the response headers alongside and the received file will be decompressed on-the-fly (it should also be faster due to more supported compression methods). There are some options, you can set before starting the request. Most important aspect is, that you can add form ->params[] one after the other for GET and POST requests. You can also use a proxy or include authentication passwords in the initially given url, and of course inject or override a few ->headers[] when it makes sense. usage ¯¯¯¯¯ It is really easy, you only must take care to always give the method parameter before the URL ("GET" or "POST" in most cases), look at the following: <?example #-- prepare $query = new http_request("GET", "http://example.com/form.php"); $query->params["q"] = "search-this-..."; #-- do request $result = $query->go(); #-- use result if ($result && ($result->status == 200)) { echo $result->content; } ?> Note, that we could have included the "q" parameter simply appended to the URL in such simple cases ("http://example.com/form.php?q=search-..."). You can also do "POST" requests (normal for forms), but that you than must decide about the encoding format. There are two for POST requests, the default is always urlencoding (like with GET requests) with <?example $query->type = "url"; // corresponds to "app/x-www-form-urlencoded" ?> but many bigger forms however require the MIME type for form-data: <?example $query->type = "form"; // translates to "multipart/form-data" ?> You see, there are easy to remember abbreviations for this. The form variables you want to transport are simply appended to the URL for GETs or "url"-coded requests, but you could use the $query->params[] array also here. If you do a "POST" request, you do likewise; or you could also just assign the $query->params a string blob to transfer as content (if the remote app can deal with it or expects that, or you already have encoded eveything into a valid form request). If you just want to add upload-files to a "POST" request, then do this as follows: <?example $query->params["fileformname"] = array( "filename" => "original-name.zip", "type" => "application/octet-stream", "content" => "$READ_FROM_FILE_DATA...", ); // or $query->params["2nd_file"] = array( "ct" => "x.ml/my-format", "name" => "../../where/is/it/from.txt", "data" => file_get_contents(".../from.txt"), ); ?> "body" is a third alias for the "content" field here. If you don't set the "type" or "ct" flag it will get "application/octet-stream" per default (this is a good default). You could simply load the "ext/mime" script to have the best possible MIME type here. start an request ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Use the ->go() method to start a prepared HTTP request. The only alias existing today is ->start(); simply derive or edit this class to add your preferred name for this likewise (->do() cannot be used as it is a PHP reserved word, sorry ;) There are two options to ->go(), the first $force will override a few problems, and with the second ($asis) set to 1 or true, you won't get a result object, but the plain HTTP response blob (headers and response body as one large string variable). authentication ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ If the remote site requires authentification, you would simply give this within the URL: <?example $query = new http_request("GET", "http://user:passw@example.com/..."); // or later: $query->setURL("http://username:pw2@server.../") // or even: $query->url = "http://name:password@localhost/form.php"; ?> proxy ¯¯¯¯¯ You can also acccess a form or remote file using a proxy server easily, just follow this: <?example $query = new http_request("PUT", "..."); $query->proxy = "http://servername.proxy.org:3219/"; // ... $result = $query->go(); ?> You could also give a password or username for your proxy server, if you need it (works the same as for above). reponses ¯¯¯¯¯¯¯¯ The $result value from the above examples should normally be an object, it will be a scalar (false) only if something went really wrong. It will have at least a ->status field, which is typically 200 for succeeded requests. Everything above 500 means an server error, values above 400 a transport and request error (= we did something wrong) and a 300 response status means a redirection was issued. For fulfilled requests you can access the returned file/data simply as "$result->content" or "$result->body" or even "$result->data" (two aliases again). You will also have a "$result->headers[]" array, which will hold all response HTTP headers in normalized form. Typically this means: <?example echo $result->headers["Content-Type"] . "\n"; echo $result->headers["Date"] . "\n"; echo $result->headers["Last-Modified"] . "\n"; echo $result->headers["Content-Length"] . "\n"; echo $result->headers["Etag"] . "\n"; // (beware of the lcased "t" !) echo $result->headers["Content-Encoding"] . "\n"; ... print_r($result->headers); // much better here ;) ?> [[ Elsewhere the field names would be completely lowercased or fully uppercase, we have CamelCase here, with the hyphens still in of course. ]] Please note, that a known "Content-Encoding" was already removed from the received ->content. And there is also a more correct "$result->len" and a "$result->type" shorthand. A few response types are understand as application data, and in this case you can call the $result->decode() function and get a PHP variable/array from the body. redirects ¯¯¯¯¯¯¯¯¯ If you expect HTTP redirects (->status codes from 300 till 375), then the default settings are ok for you, many will automatically be catched and the form data or file request will succeed at the replied URL. To tack/catch these cases yourself, simply disable that behaviour with: <?example $query->active_client = 0; ?> PHP-RPC ¯¯¯¯¯¯¯ Not yet! But this is probably what it will look like: If you control both ends of the Wire, you shouldn't use the slow and buggy (not everything works with everything else) XML-RPC protocol for calling remote functions, but instead use the high speed PHP serialize encoding to transfer data. The "http_request" class can natively encode values as such. The MIME type "application/vnd.php.serialized" has been registered explicitely for this purpose (as alternative to "multipart/form-data" encoding, and it is type-safe as opposed to the "/x-www-form-urlencoded" format). Perl and JS implementations exist (probably also one for Python), so plattform-independence should be given. PHP-RPC shall inherit (not yet negotiated) some structure from the old XML-RPC protocol. That is, a few names are identical. If you start an request you would therefore do following: <?php function phprpc($server, $function, $args=array()) { #-- init $query = new http_request("POST", $server); #-- set content $query->type = "php"; // here corresponds to "app/vnd.php.serialized" $query->params = array( "method" => $function, "params" => $args, ); #-- start $result = $query->go(); if ($result && ($result->status == 200)) { $r = $result->decode(); if ($good = $r["result"]) { return($good); } return($r); } } ?> You of course need a server part to make use of this. Simply try the "ext/phprequest", in which case you would do the following: <?php include("ext/phprequest.php") if (count($_POST) && ($method = $_POST["method"]) and ($params = $_POST["params"])) { #-- call known/registered functions $method = strtolower($method); if ($method == "my.func") { $r = call_user_func_array("my_func", $params); } elseif ($method == "system.time") { $r = time(); } elseif ($method == "sytem.listmethods") { $r = get_defined_functions(); $r = $r["user"]; } #-- if succeeded if ($r) { header("Content-Type: application/vnd.php.serialized"); header("Content-Encoding: deflate"); $r = array("result" => $r); die(gzdeflate(serialize($r)); } } #-- your normal script can go on here //... ?> You can inject this into anywhere as it only engages, if a PHP-RPC request was detected. |
Added ext/contrib/input.README.pdf.
cannot compute difference between binary files
Added ext/contrib/input.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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | <?php /** * type: interface * title: $_REQUEST var object-wrappers * description: provides sanitization by encapsuling request variables against raw access * version: 0.1 * license: public domain (=anything you want) * depends: php:filter, php >5.1 * x-throws: E_NOTICE * * Object wrappers for HTTP input variables sanitize incoming data, * and prevent casual unverified access. Using them ensures a single * entry point and verification spot for all user data. * * $_REQUEST = new input($_REQUEST); * $_GET = new input($_GET); * $_POST = new input($_POST); * $_SERVER = new input($_SERVER); * * Provides convenient access to data over various filter methods: * * print $_GET->int("search_q"); * mysql_query(" SELECT * FROM x WHERE y='{$_POST->sql(y)}' "); * require($_SERVER->name("SERVER_NAME").".htm"); * * Available filter methods are: * ->int * ->name * ->raw * ->text * ->regex * ->array_int * ->sql * and most sanitizers that the php filter_ extension provides. * * With PHP5 you can also access the filtered variables simply as * $_GET->int->varname and $_GET->int["varname"] instead of just * with the ordinary method $_GET->int("varname") way. PHP filter_ * extension methods can be used with the method syntax only. * * * Input validation of course is no substitute for secure application * logic, parameterized sql and proper output encoding. But this * method is a good start, and streamlines input data handling. * */ /** * @package Request variable input wrapper. * */ class input { /** * previous suberglobal input array * @var array * @access private */ var $vars; /** * Initialize object from * @param array one of $_REQUEST, $_GET or $_POST etc. */ function __construct($in) { # save superglobal $this->vars = (array)$in; # provides convenience access ->filter->var and ->filter["trick"] foreach (get_class_methods(__CLASS__) as $sub) { $this->{$sub} = new input___sub($this, "$sub"); } } /** * Generic array features. (has no keys) * ->has(isset) ->no(empty) ->keys() */ function has($name) { return isset($this->vars[$name]); } function no($name) { return empty($this->vars[$name]); } function keys($name) { return array_keys($this->vars); } #--- sanitization functions --- # this should obviously be avoided function raw($name) { trigger_error("Unfiltered input variable '$name' accessed.", E_USER_NOTICE); return $this->vars[$name]; } # integer function int($name) { return (int)$this->vars[$name]; } # proper identifiers (e.g. var names, only letters) function name($name) { return preg_replace("/[^\w_]+/", "", $this->vars[$name]); } # human-readable ascii text without control characters function text($name) { return preg_replace("/[^\w\d\s,._]+/U", "", strip_tags($this->vars[$name])); } # regular expression filter / or data match function regex($name, $rx="", $match=1) { # validating if (strpos($rx, "(")) { if (preg_match($rx, $this->vars[$name], $result)) { return($result[$match]); } } # cropping elseif (strpos($rx, "[^")) { return preg_replace($rx, "", $this->vars[$name]); } } # max length string function length($name, $max=65535) { return substr($this->text($name), 0, $max); } #--- custom functions --- # escape for concatenating data into sql query (= not good, folks!) function sql($name) { trigger_error("SQL escaping of input variable '$name'. Use of parameterized SQL is recommended for speed and security reasons.", E_USER_NOTICE); return mysql_real_escape_string/*seriously?!*/($this->vars[$name]); } # identifiers with underscores and dots, like "xvar.1_2.x" function id($name) { return preg_replace("#(^[^a-z_]+)|[^\w\d_.]+|([^\w_]$)#i", "", $this->vars[$name]); } // function email($name) { ... } // provided by filter extension // function url($name) { return preg_replace("/[^-\w\d\$.+!*'(),{}\|\\~\^\[\]\`<>#%\";\/?:@&=]+/", "", $this->vars[$name]); } // function json($name) { ... } // function datetime($name) { ... } // as in HTML5 /*function html($name) { $h = new HTML_Purifier; return $h->purify( $this->vars[$name] ); }*/ #--- application logic tailored --- /*function category_id($name) { $s = $this->name(vars[$name]); if (!isset($GLOBALS["app_config"]["categories"][$s])) { error_log("Security breach: User tried access with invalid &category= parameter, {$_SERVER->text(REMOTE_ADDR)}", 0); } else return $s; }*/ // function session_id($name) { ... } // e.g. verify last IP, stale session, user-agent // function range($name, $min, $max) { ... } // #--- array variants --- # input variable is an array of integers function array_int($name) { return $this->array_($name, "intval"); } function array_($name, $func) { $tmp = (array)($this->vars[$name]); foreach ($tmp as $i=>$v) { $tmp[$i] = $func($v); } return $tmp; } #--- magic functions --- /** * If a bare variable access $_SERVER->SERVER_NAME occours, * refer to ->name() because this is the most commonly desired effect. */ function __get($name) { return $this->name($name); } /** * Unkown methods are just passed on to the native PHP filter extension, * use ->array_WHATEVER() for recursive sanitiziation * or ->filter_validate_thingy() for native filter names */ function __call($method, $args) { $map = array( "float" => "filter_number_float", "ip" => "filter_validate_ip", "hex" => array("filter_validate_int", "filter_flag_allow_hex"), ); $name = $args[0]; $flags = isset($args[1]) ? $args[1] : 0; $array_walk = (0 == strncmp($method, "array_", 6)) && ($method = substr($method, 6)); # defer filter method if (isset($map[$method])) { $filter = $map[$method]; if (is_array($filter)) { list($filter, $flags) = $filter; } $filter = strtoupper($filter); $flags = strtoupper($flags); } else { $filter = strtoupper($method); if (strpos($method, "validate") !== false) { $filter = "FILTER_SANITIZE_" . $filter; } } # whichnow? $filter_id = defined($filter) ? constant($filter) : filter_id($method); $flags_id = is_int($flags) ? $flags : (strlen($flags)>2 ? constant($flags) : 0); /* int, boolean, float, validate_url, validate_email, validate_ip, string, stripped, encoded, special_chars, unsafe_raw, email, url, number_int, number_float, magic_quotes */ # pass on if ($filter_id === false) { trigger_error("no filter '$method'", E_USER_ERROR); } elseif ($array_walk) { $tmp = $this->vars[$name]; foreach ($tmp as $i=>$v) { filter_var($tmp[$i], $filter_id, $flags_id); } return $tmp; } else { return filter_var($this->vars[$name], $filter_id, $flags_id); } } } /** * Allows additional access methods to input variables: * $_REQUEST->name->VARNAME * and: * $_REQUEST->name["invar"] * * @subpackage methodarray */ class input___sub implements ArrayAccess { function __construct($parent, $func) { $this->parent = $parent; $this->func = $func; } function __get($name) { return $this->parent->{$this->func}($name); } function offsetExists($name) { return isset($this->parent->vars[$name]); } function offsetGet($name) { return $this->__get($name); } function offsetSet($name, $value) { /*forget it*/} function offsetUnset($name) { 0; } } /** * @code Initialize automatically. * */ $_SERVER = new input($_SERVER); $_REQUEST = new input($_REQUEST); $_GET = new input($_GET); $_POST = new input($_POST); $_COOKIE = new input($_COOKIE); #$_SESSION = new input($_SESSION); #$_ENV = new input($_ENV); #$_FILES cannot be used that way ?> |
Deleted ext/contrib/pdo-2006-01-29.tar.gz.
cannot compute difference between binary files
Added ext/contrib/php4_exceptions.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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | <?php /* simplistic exception handling for PHP4 -------------------------------------- As you might know, PHP5 introduced exceptions, similiar to Javas. This feature of course cannot be used for PHP4-compatible scripts, and it can in no way be emulated by a functional API emulation like "upgrade.php". To use an exception-like scheme in PHP4 you'd have to agree on conventions - lots of. And exceptions won't look object-oriented anymore and not be compliant with the PHP5 scheme - the names are in fact held incompatible to avoid conflicts in the language semantics (reserved words). interfaces ---------- - class Exception - global variable $_EXCEPTION (- should better be a list of excptn objs?) - _try() function - _throw() function - _catch() function howto ----- - prefix a block of commands with _try(); this will initialize exception handling (evtl. resets internal vars) - errors are thrown, by calling _throw() with an Exception-class derived object instance as parameter, and returning immediately - exceptions are "catched" in if() statements, the _catch() function with a classname as parameter returns false or the $_EXCEPTION object - you shouldn't use set_exception_handler(), but $_EXCEPTION="funcname"; #-- main code _try(); { sub_call(); } if ($e = _catch("Special_Case")) { echo $e->broken_file(); } if ($e = _catch("Exception")) { echo "Something broke, I'd say."; } #-- error-prone function sub_call() { // ... _throw(new Exception("error",255)); return(); } note ---- Please don't send hatemails only because you feel the syntax is too far away from PHP5s native exception handling and counter to that in other languages. And the underscores in this agreement are just to prevent conflicts with PHP5 constructs - this is not yet another case of PHP-underscoritis ;) -> there has been another PHP framework which implemented exceptions long before PHP5 came out; I just don't know anymore which it was //@TODO: build a search engine similiar to Google to find that out */ #-- base class for exceptions if (!class_exists("exception")) { class Exception { #-- attributes var $message = ""; var $code = 0; var $file = NULL; var $line = NULL; var $backtrace = NULL; #-- constructor function Exception($message="", $code=0) { #-- values $this->message = $message; $this->code = $code; #-- debugging $this->backtrace = debug_backtrace(); array_shift($this->backtrace); $this->file = @$this->backtrace[0]["file"]; $this->line = @$this->backtrace[0]["line"]; } #-- get_ wrappers function getMessage() { return($this->message); } function getCode() { return($this->code); } function getFile() { return($this->file); } function getLine() { return($this->line); } function getTrace() { return($this->backtrace); } function getTraceAsString() { return(var_export($this->backtrace, TRUE)); } #-- output function __toString() { return($this->message); } } } #-- initialize exception handling for next block function _try() { global $_EXCEPTION; #-- clean up if (!is_string($_EXCEPTION) || !function_exists($_EXCEPTION)) { $_EXCEPTION = new Object(); } } #-- use for throwing errors function _throw($obj) { global $_EXCEPTION; #-- quick if (is_string($_EXCEPTION) && function_exists($_EXCEPTION)) { $_EXCEPTION($obj); } #-- what do we do if there's already an exception? if ($_EXCEPTION) { // ??? trigger_error("_throw: there is already an unhandled exception on the stack", E_USER_ERROR); } #-- generate object from error message if (!is_object($obj)) { $_EXCEPTION = new Exception("$obj"); } #-- pass $_EXCEPTION = $obj; return(true); // break 5; (after throwing an exception, you should // exit from your current function quickly) } #-- check if exception thrown function &_catch($classname="Exception") { global $_EXCEPTION; static $e; #-- checked for a specific error type / exception class if (is_object($_EXCEPTION) && (($classname == "*") || is_a($_EXCEPTION, $classname))) { $e = &$_EXCEPTION; //@FIX: remove reference passing, seems unnecessary unset($_EXCEPTION); // this doesn't clean the global var [but _try() does] } else { $e = false; } #-- give out extracted exception return $e; } #-- functional additions if (!function_exists("debug_backtrace")) { function debug_backtrace() { return array(); } } #-- sets global state if (!function_exists("set_exception_handler")) { // quick hack, should use a different func name function set_exception_handler($func) { global $_EXCEPTION; $_EXCEPTION = $func; } } ?> |
Added ext/contrib/php5_clone.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 | <?php /** * Some functions from PHP5, that aren't actually senseful to replicate * for PHP4. The new native object semantics cannot be emulated anyhow. * * - see also ext/contrib/exceptions.php * */ /** * Make a real object copy. This is a token in PHP5, not a function. * * Uses serialize-trick from PHP_Compat, because PHP4 references can * neither be detected nor resolved otherwise. * * @stub * @since 5.0 */ if (!function_exists("clone") && PHP_VERSION < "5.0") { eval(' function clone($obj) { // this however duplicates sub-objects and arrays too $new = unserialize(serialize(($obj)); if (method_exists($new, "__clone")) { $new->__clone(); } return $new; } '); } ?> |
Deleted ext/contrib/php5oo.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted ext/contrib/phprequest.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted ext/contrib/xmlrpc.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted ext/contrib/xmlrpc.txt.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to ext/ctype.php.
︙ | ︙ | |||
41 42 43 44 45 46 47 | } function ctype_print($text) { return ctype_punct($text) && ctype_graph($text); } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 41 42 43 44 45 46 47 48 | } function ctype_print($text) { return ctype_punct($text) && ctype_graph($text); } } ?> |
Deleted ext/exotic.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added ext/nonstandard/base16.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 | <?php /** * * This script implements the base64-encoding functions and base32 and * base16 as described in RFC3548. * * @since never * @nonstandard * */ if (!function_exists("base16_encode")) { #-- URL and filename safe variants of base64-encoding function base64_encode_safe($str) { return strtr(base64_encode($str), "+/", "-_"); } function base64_decode_safe($b64) { return base64_decode(strtr($str, "-_", "+/")); } #-- base16 function base16_encode($str) { $str = unpack("H".(2*strlen($str)), $str); $str = chunk_split($str[1]); return($str); } function base16_decode($b16) { $b16 = preg_replace("/\s+/", '', $b16); $b16 = pack("H*", $b16); return($b16); } #-- base32 function base32_encode() { # strtoupper() # "A-Z,0-7,=" } } ?> |
Deleted ext/nonstandard/base64.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added ext/php40array.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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | <?php /** * * Extended PHP array functions - _diff and _intersect() for associative * arrays and/or with callback functions (for keys and/or values). These * are too rarely used and exotic to be part of the core "upgrade.php" * script. * * NOTHING IN HERE WAS SERIOUSLY TESTED. Please grab the definitions from * PEAR::PHP_Compat if you want reliable and tested versions. * * * @group ARRAY_FUNCS_4_0 * @since 4.0 * @untested * */ #-- diff associative arrays with two user callbacks # (if this looks complicated to you, don't even try to look at the manual) if (!function_exists("array_udiff_uassoc")) { function array_udiff_uassoc() { $in = func_get_args(); $key_cb = array_pop($in); $val_cb = array_pop($in); $arr1 = array_shift($in); $r = array(); foreach ($arr1 as $i=>$v) { #-- in each array, compare against each key/value pair foreach (array_keys($in) as $c) { foreach ($in[$c] as $i2=>$v2) { $key_cmp = call_user_func_array($key_cb, array($i, $i2)); if ($key_cmp == 0) { #-- ok, in this case we must compare the data as well $val_cmp = call_user_func_array($val_cb, array($v, $v2)); if ($val_cmp == 0) { continue 3; } } } } #-- this combination isn't really found anywhere else $r[$i] = $v; } return($r); } } #-- same, but that keys now are compared normally (without callback) if (!function_exists("array_udiff_assoc")) { function array_udiff_assoc() { $in = func_get_args(); $val_cb = array_pop($in); $arr1 = array_shift($in); $r = array(); #-- compare against each key/value pair in other arrays foreach ($arr1 as $i=>$v) { foreach (array_keys($in) as $c) { if (isset($in[$c][$i])) { #-- now compare data by callback $cmp = call_user_func_array($val_cb, array($v, $in[$c][$i])); if ($cmp == 0) { continue 2; } } } #-- everything exists only in array1 $r[$i] = $v; } return($r); } } #-- .... if (!function_exists("array_diff_uassoc")) { function array_diff_uassoc() { $in = func_get_args(); $key_cb = array_pop($in); $arr1 = array_shift($in); $num = count($in); $r = array(); foreach ($arr1 as $i=>$v) { #-- in other arrays? for ($c=0; $c<$num; $c++) { foreach ($in[$c] as $i2=>$v2) { if ($v == $v2) { $cmp = call_user_func_array($key_cb, array($i, $i2)); if ($cmp == 0) { continue 3; } } } } #-- exists only in array1 $r[$i] = $v; } return($r); } } #-- diff array, keys ignored, callback for comparing values if (!function_exists("array_udiff")) { function array_udiff() { $in = func_get_args(); $val_cb = array_pop($in); $arr1 = array_shift($in); $num = count($in); $r = array(); foreach ($arr1 as $i=>$v) { #-- check other arrays for ($c=0; $c<$num; $c++) { foreach ($in[$c] as $v2) { $cmp = call_user_func_array($val_cb, array($v, $v2)); if ($cmp == 0) { continue 3; } } } #-- exists only in array1 $r[$i] = $v; } return($r); } } #-- same for intersections if (!function_exists("array_uintersect_uassoc")) { function array_uintersect_uassoc() { $in = func_get_args(); $key_cb = array_pop($in); $val_cb = array_pop($in); $all = array(); $conc = count($in); foreach ($in[0] as $i=>$v) { #-- must exist in each array (at least once, callbacks may match fuzzy) for ($c=1; $c<$conc; $c++) { $ok = false; foreach ($in[$c] as $i2=>$v2) { $key_cmp = call_user_func_array($key_cb, array($i, $i2)); $val_cmp = call_user_func_array($val_cb, array($v, $v2)); if (($key_cmp == 0) && ($val_cmp == 0)) { $ok = true; break; } } if (!$ok) { continue 2; } } #-- exists in all arrays $all[$i] = $v; } return($all); } } #-- intersection again if (!function_exists("array_uintersect_assoc")) { function array_uintersect_assoc() { $in = func_get_args(); $val_cb = array_pop($in); $all = array(); $conc = count($in); foreach ($in[0] as $i=>$v) { #-- test for that entry in any other array for ($c=1; $c<$conc; $c++) { if (isset($in[$c][$i])) { $cmp = call_user_func_array($val_cb, array($v, $in[$c][$i])); if ($cmp == 0) { continue; } } #-- failed continue 2; } #-- exists in all arrays # (but for fuzzy matching: only the first entry will be returned here) $all[$i] = $v; } return($all); } } #-- array intersection, no keys compared, but callback for values if (!function_exists("array_uintersect")) { function array_uintersect() { $in = func_get_args(); $val_cb = array_pop($in); $arr1 = array_shift($in); $num = count($in); $r = array(); foreach ($arr1 as $i=>$v) { #-- must have equivalent value in all other arrays for ($c=0; $c<$num; $c++) { foreach ($in[$c] as $i2=>$v2) { $cmp = call_user_func_array($val_cb, array($v, $v2)); if ($cmp == 0) { continue 2; //found } } continue 2; //failed } #-- everywhere $r[$i] = $v; } return($r); } } #-- diff array, keys ignored, callback for comparing values if (!function_exists("array_intersect_uassoc")) { function array_intersect_uassoc() { $args = func_get_args(); $key_cb = array_pop($args); $array1 = array_shift($args); $num = count($args); $all = array(); foreach ($array1 as $i=>$v) { #-- look through other arrays for ($c=0; $c<$num; $c++) { $ok = 0; foreach ($args[$c] as $i2=>$v2) { $cmp = call_user_func_array($key_cb, array($i, $i2)); if (($cmp == 0) && ($v == $v2)) { $ok = 1; continue 2; } } if (!$ok) { continue 2; } } #-- found in all arrays if ($ok) { $diff[$i] = $v; } } return($diff); } } ?> |
Changes to ext/stubs/zlib.php.
1 2 3 4 5 6 7 8 | <?php /* This script simulates the gz*() functions, without actually providing compression functionality. The generated data streams will be correct, but reading compressed files isn't possible. Not very useful; should only be used if there is no other way. But if your provider seriously doesn't have PHP with builtin zlib support, | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php /* This script simulates the gz*() functions, without actually providing compression functionality. The generated data streams will be correct, but reading compressed files isn't possible. Not very useful; should only be used if there is no other way. But if your provider seriously doesn't have PHP with builtin zlib support, you'd be better off simply switching to someone else... */ #-- fake zlib if (!function_exists("gzopen")) { function gzopen($fp, $mode) { |
︙ | ︙ |
Added ext/uncommon_functions.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 | <?php /* Following funtions have been removed from the core emulation script, because they are considered too special to be commonly used in WWW scripts. Anybody using these, probably takes extra precautions prior calling them (you could still load this script). Some of these functions could also be too difficult to be reimplemented 100% exactly. */ #-- calls PHP interpreter itself (really only works with 4.3 onwards) # (you should use the PHP_Compat implementation of this preferably) if (!function_exists("php_strip_whitespace")) { function php_strip_whitespace($fn) { // alternatives would be using te tokenizer or // some regexs to strip unwanted content parts // (PEAR::PHP_Compat simply calls the tokenizer) $fn = escapeshellcmd($fn); $text = `php -wqCf '$fn'`; if (!$text) { $text = implode("", file($fn)); } return $text; } } #-- invocates PHP interpreter to do the syntax check (nothing else can do) # (you should use the PHP_Compat implementation of this preferably) if (!function_exists("php_check_syntax")) { function php_check_syntax($fn) { $args = func_get_args(); if (count($args)>1) { $result = & $args[1]; } $fn = escapeshellcmd($fn); $result = system("php -lqCf '$fn'", $err); return($err==0); } } #-- print enumerated list of last-called functions if (!function_exists("debug_print_backtrace") && function_exists("debug_backtrace")) { function debug_print_backtrace() { $d = debug_backtrace(); foreach ($d as $i=>$info) { #-- index echo "#" . ($i) . " "; #-- function name if (isset($info["class"])) { echo "$info[class]::"; } if (isset($info["object"])) { echo "\$$info[object]->"; } echo "$info[function]"; #-- args echo "("; foreach ($info["args"] as $a) { echo str_replace("\n", "", var_export($a, 1)) . ", "; } echo ")"; #-- caller echo " called at ["; if ($info["file"]) { echo $info["file"] . ":" . $info["line"]; } else { echo "unknown_location"; } echo "]\n"; } } } ?> |
Deleted ext/unfinished/bcmath.old.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to ext/unfinished/filter.php.
︙ | ︙ | |||
510 511 512 513 514 515 516 | elseif ($filter == FILTER_SANITIZE_MAGIC_QUOTES) { return addslashes($var); } #-- callback function elseif ($filter == FILTER_CALLBACK) { | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | elseif ($filter == FILTER_SANITIZE_MAGIC_QUOTES) { return addslashes($var); } #-- callback function elseif ($filter == FILTER_CALLBACK) { return call_user_func($callback, $var); } #-- filter unknown else { trigger_error(E_USER_ERROR, "Uh, oh. Unknown filter id #".$filter); return $FAILURE; |
︙ | ︙ |
Changes to ext/unfinished/odbc.php.
1 2 | <?php | | | 1 2 3 4 5 6 7 8 9 10 | <?php die("'odbc.php' is incomplete. Will not be completed. Use PDO instead.\n"); /* This is just another SQL interface wrapper. It reimplements the ODBC functions in PHP by itself chaining to PEAR::DB (a double wrapper, to simplify this initial version). - does not use integers as connection_id |
︙ | ︙ |
Deleted ext/unfinished/openssl.php.
|
| < < < < < |
Deleted ext/unfinished/pdo.php.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added ext/xmlentities.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 | <?php /** * api: php * title: future PHP functions * descriptions: functions, that are not yet in php.net releases * * * */ /** * @nonstandard * * Encodes required named XML entities. It's like htmlentities(). * Doesn't re-encode or fix numeric entities. * * @param string * @return string */ if (!function_exists("xmlentities")) { function xmlentities($str) { return strtr($str, array( "&#"=>"&#", "&"=>"&", "'"=>"'", "<"=>"<", ">"=>">", "\""=>""", )); } } ?> |
Changes to upgrade.php.
1 2 3 | <?php /** * api: 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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | <?php /** * api: php * title: upgrade.php * description: Emulates functions from new PHP versions on older interpreters. * version: 16 * license: Public Domain * url: http://freshmeat.net/projects/upgradephp * type: functions * category: library * priority: auto * load_if: (PHP_VERSION<5.2) * sort: -255 * provides: upgrade-php, api:php5, json * * * By loading this library you get PHP version independence. It provides * downwards compatibility to older PHP interpreters by emulating missing * functions or constants using IDENTICAL NAMES. So this doesn't slow down * script execution on setups where the native functions already exist. It * is meant as quick drop-in solution. It spares you from rewriting code or * using cumbersome workarounds instead of the more powerful v5 functions. * * It cannot mirror PHP5s extended OO-semantics and functionality into PHP4 * however. A few features are added here that weren't part of PHP yet. And * some other function collections are separated out into the ext/ directory. * It doesn't produce many custom error messages (YAGNI), and instead leaves * reporting to invoked functions or for native PHP execution. * * And further this is PUBLIC DOMAIN (no copyright, no license, no warranty) * so therefore compatible to ALL open source licenses. You could rip this * paragraph out to republish this instead only under more restrictive terms * or your favorite license (GNU LGPL/GPL, BSDL, MPL/CDDL, Artistic/PHPL, ..) * * Any contribution is appreciated. <milky*users#sf#net> * */ /** * --------------------- CVS / FUTURE --- * @group CVS * @since future * * Following functions aren't implemented in current PHP versions, but * might already be in CVS/SVN. * * @emulated * gzdecode * * @moved out * contrib/xmlentities * */ /** * @since 6.0 * * Inflates a string enriched with gzip headers. Counterpart to gzencode(). * Not yet in any Zend-PHP. * */ if (!function_exists("gzdecode")) { function gzdecode($gzdata, $maxlen=NULL) { #-- decode header $len = strlen($gzdata); if ($len < 20) { return; } $head = substr($gzdata, 0, 10); $head = unpack("n1id/C1cm/C1flg/V1mtime/C1xfl/C1os", $head); list($ID, $CM, $FLG, $MTIME, $XFL, $OS) = array_values($head); $FTEXT = 1<<0; $FHCRC = 1<<1; $FEXTRA = 1<<2; $FNAME = 1<<3; $FCOMMENT = 1<<4; $head = unpack("V1crc/V1isize", substr($gzdata, $len-8, 8)); list($CRC32, $ISIZE) = array_values($head); #-- check gzip stream identifier if ($ID != 0x1f8b) { trigger_error("gzdecode: not in gzip format", E_USER_WARNING); return; } #-- check for deflate algorithm if ($CM != 8) { trigger_error("gzdecode: cannot decode anything but deflated streams", E_USER_WARNING); return; } #-- start of data, skip bonus fields $s = 10; if ($FLG & $FEXTRA) { $s += $XFL; } if ($FLG & $FNAME) { $s = strpos($gzdata, "\000", $s) + 1; } if ($FLG & $FCOMMENT) { $s = strpos($gzdata, "\000", $s) + 1; } if ($FLG & $FHCRC) { $s += 2; // cannot check } #-- get data, uncompress $gzdata = substr($gzdata, $s, $len-$s); if ($maxlen) { $gzdata = gzinflate($gzdata, $maxlen); return($gzdata); // no checks(?!) } else { $gzdata = gzinflate($gzdata); } #-- check+fin $chk = crc32($gzdata); if ($CRC32 != $chk) { trigger_error("gzdecode: checksum failed (real$chk != comp$CRC32)", E_USER_WARNING); } elseif ($ISIZE != strlen($gzdata)) { trigger_error("gzdecode: stream size mismatch", E_USER_WARNING); } else { return($gzdata); } } } /** * ----------------------------- 5.3 --- * @group 5_3 * @since 5.3 * * Known additions of PHP 5.3 * * @emulated * ob_get_headers (stub) * preg_filter * lcfirst * class_alias * header_remove * parse_ini_string * array_replace * * @missing * get_called_class * str_getcsv * quoted_printable_encode * forward_static_call * forward_static_call_array * stream_context_get_params * stream_context_set_default * stream_supports_lock * array_replace_recursive * hash_copy * date_create_from_format * date_parse_from_format * date_get_last_errors * date_add * date_sub * date_diff * date_timestamp_set * date_timestamp_get * timezone_location_get * date_interval_create_from_date_string * date_interval_format * * RANT: The PHP 5.3 \idiot\namespace\syntax (magic quotes 2.0) is not * reimplemented here. * */ /** * preg_replace() variant, which filters out any unmatched $subject. * */ if (!function_exists("preg_filter")) { function preg_filter($pattern, $replacement, $subject, $limit=NULL, $count=NULL) { $r = preg_replace($pattern, $replacement, $subject, $limit, $count); if (!is_array($subject)) { return preg_match($pattern, $subject) ? $r : NULL; } else { foreach ((array)$subject as $i=>$s) { if (!preg_match($pattern, $subject)) { unset($r[$i]); // just post-remove unmatched entries } } return($r); } // optimize-wise you would do the match first and then the replacing; but this is shorter } } /** * Lowercase first character. * * @param string * @return string */ if (!function_exists("lcfirst")) { function lcfirst($str) { return strlen($str) ? strtolower($str[0]) . substr($str, 1) : ""; } } /** * @stub cannot be emulated, because output buffering functions * already swallow up any sent http header * @since 5.3.? * * get all ob_ soaked headers(), * */ if (!function_exists("ob_get_headers")) { function ob_get_headers() { return (array)NULL; } } /** * @stub Cannot be emulated correctly, but let's try. * */ if (!function_exists("header_remove")) { function header_remove($name) { if ($name = preg_replace("/[^-_.\w\d]+/", "", $name)) header("$name: \t"); // Apache1.3? removed duplettes, empty header overrides previous. // ONLY if case was identical to previous header() call. (Very uncertain for applications which need to resort to such code smell.) } } /** * WTF? * At least an explaning reference was available on the php.net manual. * Why the parameters are supposed to be optional is a mystery. * */ if (!function_exists("class_alias")) { function class_alias($original, $alias) { $abstract = ""; if (class_exists("ReflectionClass")) { $oc = new ReflectionClass($original); $abstract = $oc->isAbstract() ? "abstract" : ""; } eval("$abstract class $alias extends $original { /* identical subclass */ }"); return get_parent_class($alias) == $original; } } /** * Hey, reimplementin is fun. * (Could have used a data: wrapper for parse_ini_file, but that wouldn't work for php<5.2, and the data:// (!) wrapper is flaky anyway.) * */ if (!function_exists("parse_ini_string")) { function parse_ini_string($ini, $sectioned=false, $raw=0) { $r = array(); $map = array("true"=>1, "yes"=>1, "1"=>1, "null"=>"", "false"=>"", "no"=>"", "0"=>0); $section = ""; foreach (explode("\n", $ini) as $line) { if (!strlen($line)) { } // handle [sections] elseif (($line[0] == "[") and preg_match("/\[([-_\w ]+)\]/", $line, $uu)) { $section = $uu[1]; } elseif (/*deprecated*/($line[0] != "#") && ($line[0] != ";") && ($i = strpos($line, "="))) { // key=value split $n = trim(substr($line, 0, $i)); $v = trim(substr($line, $i+1)); // replace special values if (!$raw) { $v=trim($v, '"'); // should actually use regex, to handle key="..\n.." multiline values $v=trim($v, "'"); if (isset($map[$v])) { $v=$map[$v]; } } // special array[]= keys allowed if ($i = strpos($n, "[")) { $r[$section][substr($n, 0, $i)][] = $v; } else { $r[$section][$n] = $v; } } } return $sectioned ? $r : call_user_func_array("array_merge", $r); } } /** * Inject values from supplemental arrays into $target, according to its keys. * * @param array $targt * @param+ array $supplements * @return array */ if (!function_exists("array_replace")) { function array_replace(/* & (?) */$target/*, $from, $from2, ...*/) { $merge = func_get_args(); array_shift($merge); for ($i=0; $i<count($merge); $i++) { foreach ((array)$merge[$i] as $i=>$v) { if (isset($target[$i])) { $target[$i] = $v; } } } return $target; } } /** * ------------------------------ 5.2 --- |
︙ | ︙ | |||
212 213 214 215 216 217 218 | * would scream error or explode. * @code * This is state machine spaghetti code. Needs the extranous parameters to * process subarrays, etc. When it recursively calls itself, $n is the * current position, and $waitfor a string with possible end-tokens. * * @param $json string JSON encoded values | | | > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | * would scream error or explode. * @code * This is state machine spaghetti code. Needs the extranous parameters to * process subarrays, etc. When it recursively calls itself, $n is the * current position, and $waitfor a string with possible end-tokens. * * @param $json string JSON encoded values * @param $assoc bool pack data into php array/hashes instead of objects * @return mixed parsed into PHP variable/array/object */ if (!function_exists("json_decode")) { function json_decode($json, $assoc=FALSE, $limit=512, /*emu_args*/$n=0,$state=0,$waitfor=0) { #-- result var $val = NULL; static $lang_eq = array("true" => TRUE, "false" => FALSE, "null" => NULL); static $str_eq = array("n"=>"\012", "r"=>"\015", "\\"=>"\\", '"'=>'"', "f"=>"\f", "b"=>"\b", "t"=>"\t", "/"=>"/"); if ($limit<0) return /* __cannot_compensate */; #-- flat char-wise parsing for (/*n*/; $n<strlen($json); /*n*/) { $c = $json[$n]; #-= in-string if ($state==='"') { |
︙ | ︙ | |||
280 281 282 283 284 285 286 | #-> end of sub-call (array/object) elseif ($waitfor && (strpos($waitfor, $c) !== false)) { return array($val, $n); // return current value and state } #-= in-array elseif ($state===']') { | | | | | > | < | < | < < | | | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | #-> end of sub-call (array/object) elseif ($waitfor && (strpos($waitfor, $c) !== false)) { return array($val, $n); // return current value and state } #-= in-array elseif ($state===']') { list($v, $n) = json_decode($json, $assoc, $limit, $n, 0, ",]"); $val[] = $v; if ($json[$n] == "]") { return array($val, $n); } } #-= in-object elseif ($state==='}') { list($i, $n) = json_decode($json, $assoc, $limit, $n, 0, ":"); // this allowed non-string indicies list($v, $n) = json_decode($json, $assoc, $limit, $n+1, 0, ",}"); $val[$i] = $v; if ($json[$n] == "}") { return array($val, $n); } } #-- looking for next item (0) else { #-> whitespace if (preg_match("/\s/", $c)) { // skip } #-> string begin elseif ($c == '"') { $state = '"'; } #-> object elseif ($c == "{") { list($val, $n) = json_decode($json, $assoc, $limit-1, $n+1, '}', "}"); if ($val && $n) { $val = $assoc ? (array)$val : (object)$val; } } #-> array elseif ($c == "[") { list($val, $n) = json_decode($json, $assoc, $limit-1, $n+1, ']', "]"); } #-> comment elseif (($c == "/") && ($json[$n+1]=="*")) { // just find end, skip over ($n = strpos($json, "*/", $n+1)) or ($n = strlen($json)); } |
︙ | ︙ | |||
378 379 380 381 382 383 384 | } /** * @stub | < > > > > > > > > > > > > > > > > > > > > > > > > | | < | < | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 | } /** * @stub * * Should return last PCRE error. * */ if (!function_exists("preg_last_error")) { if (!defined("PREG_NO_ERROR")) { define("PREG_NO_ERROR", 0); } if (!defined("PREG_INTERNAL_ERROR")) { define("PREG_INTERNAL_ERROR", 1); } if (!defined("PREG_BACKTRACK_LIMIT_ERROR")) { define("PREG_BACKTRACK_LIMIT_ERROR", 2); } if (!defined("PREG_RECURSION_LIMIT_ERROR")) { define("PREG_RECURSION_LIMIT_ERROR", 3); } if (!defined("PREG_BAD_UTF8_ERROR")) { define("PREG_BAD_UTF8_ERROR", 4); } function preg_last_error() { return PREG_NO_ERROR; } } /** * returns path of the system directory for temporary files * * @since 5.2.1 */ if (!function_exists("sys_get_temp_dir")) { function sys_get_temp_dir() { # check possible alternatives ($temp = ini_get("temp_dir")) or ($temp = $_SERVER["TEMP"]) or ($temp = $_SERVER["TMP"]) or ($temp = "/tmp"); # fin return($temp); } } /** * @stub * * Should return associative array with last error message. * */ if (!function_exists("error_get_last")) { function error_get_last() { return array( "type" => 0, "message" => $GLOBALS[php_errormsg], "file" => "unknonw", "line" => 0, ); } } /** * @flag quirky, exec, realmode * * Change owner of a symlink filename. * */ if (!function_exists("lchown")) { function lchown($fn, $user) { if (PHP_OS != "Linux") { return false; } $user = escapeshellcmd($user); $fn = escapeshellcmd($fn); exec("chown -h '$user' '$fn'", $uu, $state); return($state); } } /** * @flag quirky, exec, realmode * * Change group of a symlink filename. * */ if (!function_exists("lchgrp")) { function lchgrp($fn, $group) { return lchown($fn, ":$group"); |
︙ | ︙ | |||
609 610 611 612 613 614 615 | fwrite($fp, $line."\n"); } } /** | | < | 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 | fwrite($fp, $line."\n"); } } /** * @flag basic * @untested * * @compat * only implements a few basic regular expression lookups * no idea how to handle all of it */ if (!function_exists("strptime")) { function strptime($str, $format) { |
︙ | ︙ | |||
695 696 697 698 699 700 701 |
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | /** * ------------------------------ 5.0 --- * @group 5_0 |
︙ | ︙ | |||
891 892 893 894 895 896 897 | * date_sunset - undoc. * PHP_CONFIG_FILE_SCAN_DIR * clone * * @unimplementable * set_exception_handler * restore_exception_handler | | | | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | * date_sunset - undoc. * PHP_CONFIG_FILE_SCAN_DIR * clone * * @unimplementable * set_exception_handler * restore_exception_handler * debug_print_backtrace - in ext, needs4.3 * debug_backtrace - stub * class_implements * proc_terminate * proc_get_status * range - new param * microtime - new param * */ |
︙ | ︙ | |||
1127 1128 1129 1130 1131 1132 1133 | /** * constructs a QUERY_STRING (application/x-www-form-urlencoded format, non-raw) * from a nested array/hash with name=>value pairs * - only first two args are part of the original API - rest used for recursion * | | | | | 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 | /** * constructs a QUERY_STRING (application/x-www-form-urlencoded format, non-raw) * from a nested array/hash with name=>value pairs * - only first two args are part of the original API - rest used for recursion * * @param mixed $vars variable data for query string * @param string $int_prefix (optional) * @param string $subarray_pfix (optional) * @param integer $level * @return mixed */ if (!function_exists("http_build_query")) { function http_build_query($vars, $int_prefix="", $subarray_pfix="", $level=0) { #-- empty starting string $s = ""; ($SEP = ini_get("arg_separator.output")) or ($SEP = "&"); #-- traverse hash/array/list entries foreach ($vars as $index=>$value) { #-- add sub_prefix for subarrays (happens for recursed innovocation) if ($subarray_pfix) { if ($level) { $index = "[" . $index . "]"; } $index = $subarray_pfix . $index; |
︙ | ︙ | |||
1183 1184 1185 1186 1187 1188 1189 | * transform into 3to4 uuencode * - this is the bare encoding, not the uu file format * * @param string * @return string */ if (!function_exists("convert_uuencode")) { | | | | | | | | 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | * transform into 3to4 uuencode * - this is the bare encoding, not the uu file format * * @param string * @return string */ if (!function_exists("convert_uuencode")) { function convert_uuencode($bin) { #-- init vars $out = ""; $line = ""; $len = strlen($bin); # $bin .= "\252\252\252"; // PHP and uuencode(1) use some special garbage??, looks like "\000"* and "`\n`" simply appended #-- canvass source string for ($n=0; $n<$len; ) { #-- make 24-bit integer from first three bytes $x = (ord($bin[$n++]) << 16) + (ord($bin[$n++]) << 8) + (ord($bin[$n++]) << 0); #-- disperse that into 4 ascii characters $line .= chr( 32 + (($x >> 18) & 0x3f) ) . chr( 32 + (($x >> 12) & 0x3f) ) . chr( 32 + (($x >> 6) & 0x3f) ) . chr( 32 + (($x >> 0) & 0x3f) ); |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 | } } /** * decodes uuencoded() data again * | | | | | | 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 | } } /** * decodes uuencoded() data again * * @param string $from * @return string */ if (!function_exists("convert_uudecode")) { function convert_uudecode($from) { #-- prepare $out = ""; $from = strtr($from, "`", " "); #-- go through lines foreach(explode("\n", ltrim($from)) as $line) { if (!strlen($line)) { break; // end reached } #-- current line length prefix unset($num); $num = ord($line{0}) - 32; |
︙ | ︙ | |||
1637 1638 1639 1640 1641 1642 1643 | } /** * write-at-once file access (counterpart to file_get_contents) * * @param integer $filename | | | | | | | | | 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 | } /** * write-at-once file access (counterpart to file_get_contents) * * @param integer $filename * @param mixed $content * @param integer $flags * @param mixed $resource * @return integer */ if (!function_exists("file_put_contents")) { function file_put_contents($filename, $content, $flags=0, $resource=NULL) { #-- prepare $mode = ($flags & FILE_APPEND ? "a" : "w" ) ."b"; $incl = $flags & FILE_USE_INCLUDE_PATH; $length = strlen($content); // $resource && trigger_error("EMULATED file_put_contents does not support \$resource parameter.", E_USER_ERROR); #-- write non-scalar? if (is_array($content) || is_object($content)) { $content = implode("", (array)$content); } #-- open for writing $f = fopen($filename, $mode, $incl); if ($f) { // locking if (($flags & LOCK_EX) && !flock($f, LOCK_EX)) { return fclose($f) && false; } // write $written = fwrite($f, $content); fclose($f); #-- only report success, if completely saved return($length == $written); } } } |
︙ | ︙ | |||
2328 2329 2330 2331 2332 2333 2334 | * convenience wrapper * */ if (!function_exists("md5_file")) { function md5_file($filename, $raw_output=false) { #-- read file, apply hash function | | < < | 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 | * convenience wrapper * */ if (!function_exists("md5_file")) { function md5_file($filename, $raw_output=false) { #-- read file, apply hash function $r = md5(file_get_contents($filename, "rb")); #-- transform? and return if ($raw_output) { $r = pack("H*", $r); } return $r; } |
︙ | ︙ | |||
2754 2755 2756 2757 2758 2759 2760 | * @until unknown * * * @emulated * ... * * @missing | | | 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 | * @until unknown * * * @emulated * ... * * @missing * leak - occupy a given amount of memory * */ |
︙ | ︙ |
Added upgrade.php.shortened.
> | 1 | <?php if(!function_exists("gzdecode")){function gzdecode($gzdata,$maxlen=NULL){$len=strlen($gzdata);if($len<20){return;}$head=substr($gzdata,0,10);$head=unpack("n1id/C1cm/C1flg/V1mtime/C1xfl/C1os",$head);list($ID,$CM,$FLG,$MTIME,$XFL,$OS)=array_values($head);$FTEXT=1<<0;$FHCRC=1<<1;$FEXTRA=1<<2;$FNAME=1<<3;$FCOMMENT=1<<4;$head=unpack("V1crc/V1isize",substr($gzdata,$len-8,8));list($CRC32,$ISIZE)=array_values($head);if($ID!=0x1f8b){trigger_error("gzdecode: not in gzip format",E_USER_WARNING);return;}if($CM!=8){trigger_error("gzdecode: cannot decode anything but deflated streams",E_USER_WARNING);return;}$s=10;if($FLG&$FEXTRA){$s+=$XFL;}if($FLG&$FNAME){$s=strpos($gzdata,"\000",$s)+1;}if($FLG&$FCOMMENT){$s=strpos($gzdata,"\000",$s)+1;}if($FLG&$FHCRC){$s+=2;}$gzdata=substr($gzdata,$s,$len-$s);if($maxlen){$gzdata=gzinflate($gzdata,$maxlen);return($gzdata);}else{$gzdata=gzinflate($gzdata);}$chk=crc32($gzdata);if($CRC32!=$chk){trigger_error("gzdecode: checksum failed(real$chk!=comp$CRC32)",E_USER_WARNING);}elseif($ISIZE!=strlen($gzdata)){trigger_error("gzdecode: stream size mismatch",E_USER_WARNING);}else{return($gzdata);}}}if(!function_exists("preg_filter")){function preg_filter($pattern,$replacement,$subject,$limit=NULL,$count=NULL){$r=preg_replace($pattern,$replacement,$subject,$limit,$count);if(!is_array($subject)){return preg_match($pattern,$subject)?$r : NULL;}else{foreach((array)$subject as$i=>$s){if(!preg_match($pattern,$subject)){unset($r[$i]);}}return($r);}}}if(!function_exists("lcfirst")){function lcfirst($str){return strlen($str)? strtolower($str[0]). substr($str,1):"";}}if(!function_exists("ob_get_headers")){function ob_get_headers(){return(array)NULL;}}if(!function_exists("header_remove")){function header_remove($name){if($name=preg_replace("/[^-_.\w\d]+/","",$name))header("$name: \t");}}if(!function_exists("class_alias")){function class_alias($original,$alias){$abstract="";if(class_exists("ReflectionClass")){$oc=new ReflectionClass($original);$abstract=$oc->isAbstract()?"abstract":"";}eval("$abstract class$alias extends$original{/*identical subclass*/}");return get_parent_class($alias)==$original;}}if(!function_exists("parse_ini_string")){function parse_ini_string($ini,$sectioned=false,$raw=0){$r=array();$map=array("true"=>1,"yes"=>1,"1"=>1,"null"=>"","false"=>"","no"=>"","0"=>0);$section="";foreach(explode("\n",$ini)as$line){if(!strlen($line)){}elseif(($line[0]=="[")and preg_match("/\[([-_\w]+)\]/",$line,$uu)){$section=$uu[1];}elseif(($line[0]!="#")&&($line[0]!=";")&&($i=strpos($line,"="))){$n=trim(substr($line,0,$i));$v=trim(substr($line,$i+1));if(!$raw){$v=trim($v,'"');$v=trim($v,"'");if(isset($map[$v])){$v=$map[$v];}}if($i=strpos($n,"[")){$r[$section][substr($n,0,$i)][]=$v;}else{$r[$section][$n]=$v;}}}return$sectioned ?$r : call_user_func_array("array_merge",$r);}}if(!function_exists("array_replace")){function array_replace($target){$merge=func_get_args();array_shift($merge);for($i=0;$i<count($merge);$i++){foreach((array)$merge[$i]as$i=>$v){if(isset($target[$i])){$target[$i]=$v;}}}return$target;}}if(!defined("E_RECOVERABLE_ERROR")){define("E_RECOVERABLE_ERROR",4096);}if(!function_exists("json_encode")){function json_encode($var,$obj=FALSE){$json="";if(is_array($var)||($obj=is_object($var))){if(!$obj)foreach((array)$var as$i=>$v){if(!is_int($i)){$obj=1;break;}}foreach((array)$var as$i=>$v){$json .=($json ?",":"").($obj ?("\"$i\":"):"").(json_encode($v));}$json=$obj ?"{".$json."}":"[".$json."]";}elseif(is_string($var)){if(!utf8_decode($var)){$var=utf8_encode($var);}$var=str_replace(array("\"","\\","/","\b","\f","\n","\r","\t"),array("\\\"","\\\\","\\/","\\b","\\f","\\n","\\r","\\t"),$var);$json='"' .$var . '"';}elseif(is_bool($var)){$json=$var ?"true":"false";}elseif($var===NULL){$json="null";}elseif(is_int($var)||is_float($var)){$json="$var";}else{trigger_error("json_encode: don't know what a '".gettype($var)."' is.",E_USER_ERROR);}return($json);}}if(!function_exists("json_decode")){function json_decode($json,$assoc=FALSE,$limit=512,$n=0,$state=0,$waitfor=0){$val=NULL;static$lang_eq=array("true"=>TRUE,"false"=>FALSE,"null"=>NULL);static$str_eq=array("n"=>"\012","r"=>"\015","\\"=>"\\",'"'=>'"',"f"=>"\f","b"=>"\b","t"=>"\t","/"=>"/");if($limit<0)return;for(;$n<strlen($json);){$c=$json[$n];if($state==='"'){if($c=='\\'){$c=$json[++$n];if(isset($str_eq[$c])){$val .=$str_eq[$c];}elseif($c=="u"){$hex=hexdec(substr($json,$n+1,4));$n+=4;if($hex<0x80){$val .=chr($hex);}elseif($hex<0x800){$val .=chr(0xC0+$hex>>6). chr(0x80+$hex&63);}elseif($hex<=0xFFFF){$val .=chr(0xE0+$hex>>12). chr(0x80+($hex>>6)&63). chr(0x80+$hex&63);}}else{$val .="\\".$c;}}elseif($c=='"'){$state=0;}else{$val .=$c;}}elseif($waitfor&&(strpos($waitfor,$c)!==false)){return array($val,$n);}elseif($state===']'){list($v,$n)=json_decode($json,$assoc,$limit,$n,0,",]");$val[]=$v;if($json[$n]=="]"){return array($val,$n);}}elseif($state==='}'){list($i,$n)=json_decode($json,$assoc,$limit,$n,0,":");list($v,$n)=json_decode($json,$assoc,$limit,$n+1,0,",}");$val[$i]=$v;if($json[$n]=="}"){return array($val,$n);}}else{if(preg_match("/\s/",$c)){}elseif($c=='"'){$state='"';}elseif($c=="{"){list($val,$n)=json_decode($json,$assoc,$limit-1,$n+1,'}',"}");if($val&&$n){$val=$assoc ?(array)$val :(object)$val;}}elseif($c=="["){list($val,$n)=json_decode($json,$assoc,$limit-1,$n+1,']',"]");}elseif(($c=="/")&&($json[$n+1]=="*")){($n=strpos($json,"*/",$n+1))or($n=strlen($json));}elseif(preg_match("#^(-?\d+(?:\.\d+)?)(?:[eE]([-+]?\d+))?#",substr($json,$n),$uu)){$val=$uu[1];$n+=strlen($uu[0])-1;if(strpos($val,".")){$val=(float)$val;}elseif($val[0]=="0"){$val=octdec($val);}else{$val=(int)$val;}if(isset($uu[2])){$val*=pow(10,(int)$uu[2]);}}elseif(preg_match("#^(true|false|null)\b#",substr($json,$n),$uu)){$val=$lang_eq[$uu[1]];$n+=strlen($uu[1])-1;}else{trigger_error("json_decode: error parsing '$c' at position$n",E_USER_WARNING);return$waitfor ? array(NULL,1<<30): NULL;}}if($n===NULL){return NULL;}$n++;}return($val);}}if(!function_exists("preg_last_error")){if(!defined("PREG_NO_ERROR")){define("PREG_NO_ERROR",0);}if(!defined("PREG_INTERNAL_ERROR")){define("PREG_INTERNAL_ERROR",1);}if(!defined("PREG_BACKTRACK_LIMIT_ERROR")){define("PREG_BACKTRACK_LIMIT_ERROR",2);}if(!defined("PREG_RECURSION_LIMIT_ERROR")){define("PREG_RECURSION_LIMIT_ERROR",3);}if(!defined("PREG_BAD_UTF8_ERROR")){define("PREG_BAD_UTF8_ERROR",4);}function preg_last_error(){return PREG_NO_ERROR;}}if(!function_exists("sys_get_temp_dir")){function sys_get_temp_dir(){($temp=ini_get("temp_dir"))or($temp=$_SERVER["TEMP"])or($temp=$_SERVER["TMP"])or($temp="/tmp");return($temp);}}if(!function_exists("error_get_last")){function error_get_last(){return array("type"=>0,"message"=>$GLOBALS[php_errormsg],"file"=>"unknonw","line"=>0,);}}if(!function_exists("lchown")){function lchown($fn,$user){if(PHP_OS!="Linux"){return false;}$user=escapeshellcmd($user);$fn=escapeshellcmd($fn);exec("chown-h '$user' '$fn'",$uu,$state);return($state);}}if(!function_exists("lchgrp")){function lchgrp($fn,$group){return lchown($fn,":$group");}}if(!defined("PHP_INT_SIZE")){define("PHP_INT_SIZE",4);}if(!defined("PHP_INT_MAX")){define("PHP_INT_MAX",2147483647);}if(!defined("M_SQRTPI")){define("M_SQRTPI",1.7724538509055);}if(!defined("M_LNPI")){define("M_LNPI",1.1447298858494);}if(!defined("M_EULER")){define("M_EULER",0.57721566490153);}if(!defined("M_SQRT3")){define("M_SQRT3",1.7320508075689);}if(!function_exists("htmlspecialchars_decode")){if(!defined("ENT_COMPAT")){define("ENT_COMPAT",2);}if(!defined("ENT_QUOTES")){define("ENT_QUOTES",3);}if(!defined("ENT_NOQUOTES")){define("ENT_NOQUOTES",0);}function htmlspecialchars_decode($string,$quotes=2){$d=$quotes&ENT_COMPAT;$s=$quotes&ENT_QUOTES;return str_replace(array("<",">",($s ?""":"&.-;"),($d ?"'":"&.-;"),"&"),array("<",">","'","\"","&"),$string);}}if(!function_exists("property_exists")){function property_exists($obj,$propname){if(is_object($obj)){$props=get_object_vars($obj);}elseif(class_exists($obj)){$props=get_class_vars($obj);}if(!@$props){return false;}return @array_walk($props,"strtolower")&&in_array(strtolower($propname),$props);}}if(!function_exists("time_sleep_until")){function time_sleep_until($t){$delay=$t-time();if($delay<0){trigger_error("time_sleep_until: timestamp in the past",E_USER_WARNING);return false;}else{sleep((int)$delay);usleep(($delay-floor($delay))*1000000);return true;}}}if(!function_exists("fputcsv")){function fputcsv($fp,$fields,$delim=",",$encl='"'){$line="";foreach((array)$fields as$str){$line .=($line ?$delim :"").$encl . str_replace(array('\\',$encl),array('\\\\'. '\\'.$encl),$str).$encl;}fwrite($fp,$line."\n");}}if(!function_exists("strptime")){function strptime($str,$format){static$expand=array("%D"=>"%m/%d/%y","%T"=>"%H:%M:%S",);static$map_r=array("%S"=>"tm_sec","%M"=>"tm_min","%H"=>"tm_hour","%d"=>"tm_mday","%m"=>"tm_mon","%Y"=>"tm_year","%y"=>"tm_year","%W"=>"tm_wday","%D"=>"tm_yday","%u"=>"unparsed",);static$names=array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12,"Sun"=>0,"Mon"=>1,"Tue"=>2,"Wed"=>3,"Thu"=>4,"Fri"=>5,"Sat"=>6,);$format=str_replace(array_keys($expand),array_values($expand),$format);$preg=preg_replace("/(%\w)/","(\w+)",preg_quote($format));preg_match_all("/(%\w)/",$format,$positions);$positions=$positions[1];if(preg_match("#$preg#","$str",$extracted)){foreach($positions as$pos=>$strfc){$v=$extracted[$pos+1];if($n=$map_r[$strfc]){$vals[$n]=($v>0)?(int)$v :$v;}else{$vals["unparsed"].=$v ."";}}$vals["tm_wday"]=$names[substr($vals["tm_wday"],0,3)];if($vals["tm_year"]>=1900){$tm_year-=1900;}elseif($vals["tm_year"]>0){$vals["tm_year"]+=100;}if($vals["tm_mon"]){$vals["tm_mon"]-=1;}else{$vals["tm_mon"]=$names[substr($vals["tm_mon"],0,3)]-1;}}return isset($vals)?$vals : false;}}if(!defined("PHP_EOL")){define("PHP_EOL",((DIRECTORY_SEPARATOR=="\\")?"\015\012":(strncmp(PHP_OS,"D",1)?"\012":"\015")));}if(!function_exists("stripos")){function stripos($haystack,$needle,$offset=NULL){$haystack=strtolower($haystack);$needle=strtolower($needle);$pos=strpos($haystack,$needle,$offset);return($pos);}}if(!function_exists("strripos")){function strripos($haystack,$needle,$offset=NULL){$haystack=strtolower($haystack);$needle=strtolower($needle);if(isset($offset)&&($offset<0)){$haystack=substr($haystack,0,strlen($haystack)-1);}$pos=strrpos($haystack,$needle);if(isset($offset)&&($offset>0)&&($pos>$offset)){$pos=false;}return($pos);}}if(!function_exists("str_ireplace")){function str_ireplace($search,$replace,$subject,$count=NULL){if(is_array($search)){$replace=array_values($replace);foreach(array_values($search)as$i=>$srch){$subject=str_ireplace($srch,$replace[$i],$subject);}}else{$replace=addcslashes($replace,"$\\");$search="{". preg_quote($search)."}i";$subject=preg_replace($search,$replace,$subject);}return($subject);}}if(!function_exists("get_headers")){function get_headers($url,$parse=0){$c=parse_url($url);extract($c);if(!isset($port)){$port=80;}$f=fsockopen($host,$port,$errno,$errstr,$timeout=15);if(!$f){return;}socket_set_blocking($f,true);fwrite($f,"HEAD$path HTTP/1.0\015\012"."Host:$host\015\012"."Connection: close\015\012"."Accept:*/*,xml/*\015\012"."User-Agent:".trim(ini_get("user_agent"))."\015\012"."\015\012");$ls=array();while(!feof($f)&&($line=trim(fgets($f,1<<16)))){if($parse){if($l=strpos($line,":")){$name=substr($line,0,$l);$value=trim(substr($line,$l+1));if(isset($ls[$name])){$ls[$name].=",$value";}else{$ls[$name]=$value;}}else{$ls[]=$line;}}else{$ls[]=$line;}}fclose($f);return($ls);}}if(!function_exists("headers_list")){function headers_list(){trigger_error("headers_list(): not supported by this PHP version",E_USER_WARNING);return(array)NULL;}}if(!function_exists("fprintf")){function fprintf(){$args=func_get_args();$stream=array_shift($args);return fwrite($stream,call_user_func_array("sprintf",$args));}}if(!function_exists("vfprintf")){function vfprintf($stream,$format,$args=NULL){return fwrite($stream,vsprintf($format,$args));}}if(!function_exists("str_split")){function str_split($str,$chunk=1){$r=array();if($chunk<1){$r[]=$str;}else{$len=strlen($str);for($n=0;$n<$len;$n+=$chunk){$r[]=substr($str,$n,$chunk);}}return($r);}}if(!function_exists("http_build_query")){function http_build_query($vars,$int_prefix="",$subarray_pfix="",$level=0){$s="";($SEP=ini_get("arg_separator.output"))or($SEP="&");foreach($vars as$index=>$value){if($subarray_pfix){if($level){$index="[".$index ."]";}$index=$subarray_pfix .$index;}elseif(is_int($index)&&strlen($int_prefix)){$index=$int_prefix .$index;}if(is_array($value)){$s .=http_build_query($value,"",$index,$level+1);}else{$s .=$SEP .$index ."=". urlencode($value);}}if(!$subarray_pfix){$s=substr($s,strlen($SEP));}return($s);}}if(!function_exists("convert_uuencode")){function convert_uuencode($bin){$out="";$line="";$len=strlen($bin);for($n=0;$n<$len;){$x=(ord($bin[$n++])<<16)+(ord($bin[$n++])<<8)+(ord($bin[$n++])<<0);$line .=chr(32+(($x>>18)&0x3f)). chr(32+(($x>>12)&0x3f)). chr(32+(($x>>6)&0x3f)). chr(32+(($x>>0)&0x3f));if(($n % 45)==0){$out .=chr(32+45)."$line\n";$line="";}}if($trail=($len % 45)){$out .=chr(32+$trail)."$line\n";}$out=strtr("$out \n","","`");return($out);}}if(!function_exists("convert_uudecode")){function convert_uudecode($from){$out="";$from=strtr($from,"`","");foreach(explode("\n",ltrim($from))as$line){if(!strlen($line)){break;}unset($num);$num=ord($line{0})-32;if(($num<=0)||($num>62)){break;}$line=substr($line,1);$add="";for($n=0;strlen($add)<$num;){$x=((ord($line[$n++])-32)<<18)+((ord($line[$n++])-32)<<12)+((ord($line[$n++])-32)<<6)+((ord($line[$n++])-32)<<0);$add .=chr(($x>>16)&0xff). chr(($x>>8)&0xff). chr(($x>>0)&0xff);}$out .=substr($add,0,$num);$line="";}return($out);}}if(!function_exists("scandir")){function scandir($dirname,$desc=0){if(strpos($dirname,"file://")===0){$dirname=substr($dirname,7);if(strpos($dirname,"localh")===0){$dirname=substr($dirname,strpos($dirname,"/"));}}if($dh=opendir($dirname)){$ls=array();while($fn=readdir($dh)){$ls[]=$fn;}closedir($dh);if($desc){rsort($ls);}else{sort($ls);}return$ls;}return false;}}if(!function_exists("idate")){function idate($formatchar,$timestamp=NULL){if(strlen($formatchar)!=1){return false;}if(!isset($timestamp)){$timestamp=time();}$str=date($formatchar,$timestamp);return(int)$str;}}if(!function_exists("time_nanosleep")){function time_nanosleep($sec,$nano){sleep($sec);usleep($nano);}}if(!function_exists("strpbrk")){function strpbrk($haystack,$char_list){$len=strlen($char_list);$min=strlen($haystack);for($n=0;$n<$len;$n++){$l=strpos($haystack,$char_list{$n});if(($l!==false)&&($l<$min)){$min=$l;}}if($min){return(substr($haystack,$min));}else{return(false);}}}if(!function_exists("php_real_logo_guid")){function php_real_logo_guid(){return php_logo_guid();}function php_egg_logo_guid(){return zend_logo_guid();}}if(!function_exists("get_declared_interfaces")){function get_declared_interfaces(){trigger_error("get_declared_interfaces(): Current script won't run reliably with PHP4.",E_USER_WARNING);return((array)NULL);}}if(!function_exists("array_combine")){function array_combine($keys,$values){$keys=array_values($keys);$values=array_values($values);$r=array();foreach($values as$i=>$val){if($key=$keys[$i]){$r[$key]=$val;}else{$r[]=$val;}}return($r);}}if(!function_exists("array_walk_recursive")){function array_walk_recursive(&$input,$callback,$userdata=NULL){foreach($input as$key=>$value){if(is_array($value)){array_walk_recursive($input[$key],$callback,$userdata);}else{call_user_func_array($callback,array(&$input[$key],$key,$userdata));}}}}if(!function_exists("substr_compare")){function substr_compare($haystack,$needle,$offset=0,$len=0,$ci=0){if($len<=0){$len=strlen($needle);if(!$len){return(0);}}if($len+$offset>=strlen($haystack)){trigger_error("substr_compare: given length exceeds main_str",E_USER_WARNING);return(false);}if($offset){$haystack=substr($haystack,$offset,$len);}if($ci){$haystack=strtolower($haystack);$needle=strtolower($needle);}return(strncmp($haystack,$needle,$len));}}if(!function_exists("spl_classes")){function spl_classes(){trigger_error("spl_classes(): not built into this PHP version");return(array)NULL;}}if(!function_exists("class_parents")){function class_parents($obj){$all=get_declared_classes();$r=array();foreach($all as$potential_parent){if(is_subclass_of($obj,$potential_parent)){$r[$potential_parent]=$potential_parent;}}return($r);}}if(!function_exists("session_commit")&&function_exists("session_write_close")){function session_commit(){session_write_close();}}if(!function_exists("dns_check_record")){function dns_check_record($host,$type=NULL){return checkdnsrr($host,$type);}}if(!function_exists("dns_get_mx")){function dns_get_mx($host,$mx){$args=func_get_args();if($args[2]){$w=&$args[2];}else{$w=false;}return getmxrr($host,$mx,$w);}}if(!function_exists("setrawcookie")){function setrawcookie($name,$value=NULL,$expire=NULL,$path=NULL,$domain=NULL,$secure=0){if(isset($value)&&strpbrk($value,",;\r\t\n\f\014\013")){trigger_error("setrawcookie: value may not contain any of ',;\r\n' and some other control chars;thrown away",E_USER_WARNING);}else{$h="Set-Cookie:$name=$value".($expire ?";expires=". gmstrftime("%a,%d-%b-%y %H:%M:%S %Z",$expire):"").($path ?";path=$path":"").($domain ?";domain=$domain":"").($secure ?";secure":"");header($h);}}}if(!function_exists("file_put_contents")){function file_put_contents($filename,$content,$flags=0,$resource=NULL){$mode=($flags&FILE_APPEND ?"a":"w")."b";$incl=$flags&FILE_USE_INCLUDE_PATH;$length=strlen($content);if(is_array($content)||is_object($content)){$content=implode("",(array)$content);}$f=fopen($filename,$mode,$incl);if($f){if(($flags&LOCK_EX)&&!flock($f,LOCK_EX)){return fclose($f)&&false;}$written=fwrite($f,$content);fclose($f);return($length==$written);}}}if(!defined("FILE_USE_INCLUDE_PATH")){define("FILE_USE_INCLUDE_PATH",1);}if(!defined("FILE_IGNORE_NEW_LINES")){define("FILE_IGNORE_NEW_LINES",2);}if(!defined("FILE_SKIP_EMPTY_LINES")){define("FILE_SKIP_EMPTY_LINES",4);}if(!defined("FILE_APPEND")){define("FILE_APPEND",8);}if(!defined("FILE_NO_DEFAULT_CONTEXT")){define("FILE_NO_DEFAULT_CONTEXT",16);}if(!defined("E_STRICT")){define("E_STRICT",2048);}if(!defined("COUNT_NORMAL")){define("COUNT_NORMAL",0);}if(!defined("COUNT_RECURSIVE")){define("COUNT_RECURSIVE",1);}if(!function_exists("count_recursive")){function count_recursive($array,$mode=1){if(!$mode){return(count($array));}else{$c=count($array);foreach($array as$sub){if(is_array($sub)){$c+=count_recursive($sub);}}return($c);}}}if(!defined("PHP_INT_SIZE")){define("PHP_INT_SIZE",4);}if(!defined("PHP_INT_MAX")){define("PHP_INT_MAX",2147483647);}if(!defined("SORT_LOCALE_STRING")){define("SORT_LOCALE_STRING",5);}if(!function_exists("file_get_contents")){function file_get_contents($filename,$use_include_path=1){$f=fopen($filename,"rb",$use_include_path);if(!$f){return;}$content=fread($f,1<<21);fclose($f);return($content);}}if(!function_exists("fnmatch")){if(!defined("FNM_PATHNAME")){define("FNM_PATHNAME",1<<0);}if(!defined("FNM_NOESCAPE")){define("FNM_NOESCAPE",1<<1);}if(!defined("FNM_PERIOD")){define("FNM_PERIOD",1<<2);}if(!defined("FNM_LEADING_DIR")){define("FNM_LEADING_DIR",1<<3);}if(!defined("FNM_CASEFOLD")){define("FNM_CASEFOLD",0x50);}if(!defined("FNM_EXTMATCH")){define("FNM_EXTMATCH",1<<5);}function fnmatch($pattern,$fn,$flags=0x0000){if($flags&FNM_PERIOD){if(($fn[0]==".")&&($pattern[0]!=".")){return(false);}}$rxci="";if($flags&FNM_CASEFOLD){$rxci="i";}$wild=".";if($flags&FNM_PATHNAME){$wild="[^/".DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR."]";}static$cmp=array();if(isset($cmp["$pattern+$flags"])){$rx=$cmp["$pattern+$flags"];}else{$rx=preg_quote($pattern);$rx=strtr($rx,array("\\*"=>"$wild*?","\\?"=>"$wild","\\["=>"[","\\]"=>"]",));$rx="{^".$rx ."$}".$rxci;if(count($cmp)>=50){$cmp=array();}$cmp["$pattern+$flags"]=$rx;}return(preg_match($rx,$fn));}}if(!function_exists("glob")){if(!defined("GLOB_MARK")){define("GLOB_MARK",1<<0);}if(!defined("GLOB_NOSORT")){define("GLOB_NOSORT",1<<1);}if(!defined("GLOB_NOCHECK")){define("GLOB_NOCHECK",1<<2);}if(!defined("GLOB_NOESCAPE")){define("GLOB_NOESCAPE",1<<3);}if(!defined("GLOB_BRACE")){define("GLOB_BRACE",1<<4);}if(!defined("GLOB_ONLYDIR")){define("GLOB_ONLYDIR",1<<5);}if(!defined("GLOB_NOCASE")){define("GLOB_NOCASE",1<<6);}if(!defined("GLOB_DOTS")){define("GLOB_DOTS",1<<7);}function glob($pattern,$flags=0x0000){$ls=array();$rxci=($flags&GLOB_NOCASE)?"i":"";if($pattern){$parts2=explode("/",$pattern);$pat=preg_quote($pattern);$pat=strtr($pat,array("\\*"=>".*?","\\?"=>".?"));if($flags ^ GLOB_NOESCAPE){}if($flags ^ GLOB_BRACE){$pat=preg_replace("/\{(.+?)\}/e",'strtr("[$1]",",","")',$pat);}$parts=explode("/",$pat);$lasti=count($parts)-1;$dn="";foreach($parts as$i=>$p){if(!strpos($p,"*?")&&(strpos($p,".?")===false)){$dn .=$parts2[$i].($i!=$lasti ?"/":"");continue;}if($dh=opendir($dn ?$dn:'.')){$with_dot=($p[1]==".")||($flags&GLOB_DOTS);while($fn=readdir($dh)){if(preg_match("\007^$p$\007$rxci",$fn)){if(($fn[0]==".")&&!$with_dot){continue;}if($i==$lasti){if(is_dir("$dn$fn")){if($flags&GLOB_ONLYDIR){continue;}if($flags&GLOB_MARK){$fn .="/";}}$ls[]="$dn$fn";}elseif(is_dir("$dn$fn")){$remaind=implode("/",array_slice($parts2,$i+1));$ls=array_merge($ls,glob("$dn$fn/$remaind",$flags));}}}closedir($dh);break;}else{return($ls);}}}if(!$ls&&($flags&GLOB_NOCHECK)){$ls[]=$pattern;}if($flags ^ GLOB_NOSORT){sort($ls);}return($ls);}}if(!function_exists("array_key_exists")){function array_key_exists($key,$search){return isset($search[$key]);}}if(!function_exists("array_intersect_assoc")){function array_intersect_assoc(){$in=func_get_args();$cmax=count($in);$whatsleftover=array();foreach($in[0]as$i=>$v){for($c=1;$c<$cmax;$c++){if(!isset($in[$c][$i])||(@$in[$c][$i]!==$v)){continue 2;}}$whatsleftover[$i]=$v;}return$whatsleftover;}}if(!function_exists("array_diff_assoc")){function array_diff_assoc(){$in=func_get_args();$diff=array();foreach($in[0]as$i=>$v){for($c=1;$c<count($in);$c++){if(isset($in[$c][$i])&&($in[$c][$i]==$v)){continue 2;}}$diff[$i]=$v;}return$diff;}}if(!function_exists("html_entity_decode")){function html_entity_decode($string,$quote_style=ENT_COMPAT,$charset="ISO-8859-1"){$y=array_flip(get_html_translation_table(HTML_ENTITIES,$quote_style));return strtr($string,$y);}}if(!function_exists("str_word_count")){function str_word_count($string,$result=0){preg_match_all('/([\w](?:[-\'\w]?[\w]+)*)/',$string,$uu);if($result==1){return($uu[1]);}elseif($result>=2){$r=array();$l=0;foreach($uu[1]as$word){$l=strpos($string,$word,$l);$r[$l]=$word;$l+=strlen($word);}return($r);}else{return(count($uu[1]));}}}if(!function_exists("str_shuffle")){function str_shuffle($str){$r="";while(strlen($str)){$n=strlen($str)-1;if($n){$n=rand(0,$n);}$r .=$str{$n};$str=substr($str,0,$n). substr($str,$n+1);}return($r);}}if(!function_exists("get_include_path")){function get_include_path(){return(get_cfg_var("include_path"));}function set_include_path($new){return ini_set("include_path",$new);}function restore_include_path(){ini_restore("include_path");}}if(!defined("PATH_SEPARATOR")){define("PATH_SEPARATOR",((DIRECTORY_SEPARATOR=='\\')? ';' :':'));}if(!defined("PHP_SHLIB_SUFFIX")){define("PHP_SHLIB_SUFFIX",((DIRECTORY_SEPARATOR=='\\')? 'dll' :'so'));}if(!defined("PHP_SAPI")){define("PHP_SAPI",php_sapi_name());}if(!defined("__FUNCTION__")){define("__FUNCTION__",NULL);}if(!defined("PHP_PREFIX")&&isset($_ENV["_"])){define("PHP_PREFIX",substr($_ENV["_"],0,strpos($_ENV["_"],"bin/")));}if(!function_exists("str_rot13")){function str_rot13($str){static$from="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";static$to="NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm";return strtr($str,$from,$to);}}if(!function_exists("array_change_key_case")){if(!defined("CASE_LOWER")){define("CASE_LOWER",0);}if(!defined("CASE_UPPER")){define("CASE_UPPER",1);}function array_change_key_case($array,$case=CASE_LOWER){foreach($array as$i=>$v){if(is_string($i)){unset($array[$i]);$i=($case==CASE_LOWER)? strtolower($i): strtoupper($i);$array[$i]=$v;}}return($array);}}if(!function_exists("array_fill")){function array_fill($start_index,$num,$value){$r=array();$i=$start_index;$end=$num+$start_index;for(;$i<$end;$i++){$r[$i]=$value;}return($r);}}if(!function_exists("array_chunk")){function array_chunk($input,$size,$preserve_keys=false){$r=array();$n=-1;foreach($input as$i=>$v){if(($n<0)||(count($r[$n])==$size)){$n++;$r[$n]=array();}if($preserve_keys){$r[$n][$i]=$v;}else{$r[$n][]=$v;}}return($r);}}if(!function_exists("md5_file")){function md5_file($filename,$raw_output=false){$r=md5(file_get_contents($filename,"rb"));if($raw_output){$r=pack("H*",$r);}return$r;}}if(!function_exists("is_a")){function is_a($obj,$classname){$classnaqme=strtolower($classname);$obj_class=strtolower(get_class($obj));return($obj_class==$classname)or is_subclass_of($obj,$classname);}}if(!function_exists("fmod")){function fmod($x,$y){$r=$x/$y;$r-=(int)$r;$r*=$y;return($r);}}if(!function_exists("floatval")){function floatval($str){$str=ltrim($str);return(float)$str;}}if(!function_exists("is_infinite")){if(!defined("NAN")){define("NAN","NAN");}if(!defined("INF")){define("INF","INF");}function is_infinite($f){$s=(string)$f;return(($s=="INF")||($s=="-INF"));}function is_nan($f){$s=(string)$f;return($s=="NAN");}function is_finite($f){$s=(string)$f;return(!strpos($s,"N"));}}if(!function_exists("var_export")){function var_export($var,$return=false,$indent="",$output=""){if(is_object($var)){$output="class". get_class($var)."{\n";foreach(((array)$var)as$id=>$var){$output .="var \$$id=". var_export($var,true).";\n";}$output .="}";}elseif(is_array($var)){foreach($var as$id=>$next){if($output)$output .=",\n";else$output="array(\n";$output .=$indent . ' ' .(is_numeric($id)?$id : '"'.addslashes($id).'"'). '=>' . var_export($next,true,"$indent");}if(empty($output))$output="array(";$output .="\n{$indent})";}elseif(is_numeric($var)){$output="$var";}elseif(is_bool($var)){$output=$var ?"true":"false";}else{$output="'". preg_replace("/([\\\\\'])/",'\\\\$1',$var)."'";}if($return){return($output);}else{print($output);}}}if(!function_exists("strcoll")){function strcoll($str1,$str2){return strcmp($str1,$str2);}}if(!function_exists("diskfreespace")){function diskfreespace(){return disk_free_sapce();}function disktotalspace(){return disk_total_sapce();}}if(!function_exists("vprintf")){function vprintf($format,$args=NULL){call_user_func_array("fprintf",get_func_args());}}if(!function_exists("vsprintf")){function vsprintf($format,$args=NULL){$args=array_merge(array($format),array_values((array)$args));return call_user_func_array("sprintf",$args);}}if(!function_exists("import_request_variables")){function import_request_variables($types="GPC",$pfix=""){$alias=array("G"=>"_GET","P"=>"_POST","C"=>"_COOKIE","S"=>"_SERVER","E"=>"_ENV",);if(!isset($_REQUEST)){$_GET=&$HTTP_GET_VARS;$_POST=&$HTTP_POST_VARS;$_COOKIE=&$HTTP_COOKIE_VARS;}for($i=0;$i<strlen($types);$i++){if($FROM=$alias[strtoupper($c)]){foreach($$FROM as$key=>$val){if(!isset($GLOBALS[$pfix.$key])){$GLOBALS[$pfix .$key]=$val;}}}}}}if(!function_exists("hypot")){function hypot($num1,$num2){return sqrt($num1*$num1+$num2*$num2);}}if(!function_exists("log1p")){function log1p($x){return(log(1+$x));}function expm1($x){return(exp($x)-1);}}if(!function_exists("sinh")){function sinh($f){return((exp($f)-exp(-$f))/2);}function cosh($f){return((exp($f)+exp(-$f))/2);}function tanh($f){return(sinh($f)/cosh($f));}}if(!function_exists("asinh")){function asinh($x){return(log($x+sqrt($x*$x+1)));}function acosh($x){return(log($x+sqrt($x*$x-1)));}function atanh($x){return(log1p(2*$x/(1-$x))/2);}}if(!function_exists("mhash")){if(!defined("MHASH_CRC32")){define("MHASH_CRC32",0);}if(!defined("MHASH_MD5")){define("MHASH_MD5",1);}if(!defined("MHASH_SHA1")){define("MHASH_SHA1",2);}if(!defined("MHASH_TIGER")){define("MHASH_TIGER",7);}if(!defined("MHASH_MD4")){define("MHASH_MD4",16);}if(!defined("MHASH_SHA256")){define("MHASH_SHA256",17);}if(!defined("MHASH_ADLER32")){define("MHASH_ADLER32",18);}function mhash($hashtype,$text,$key){if(!($func=mhash_get_hash_name($hashtype))||!function_exists($func)){return trigger_error("mhash: cannot use hash algorithm #$hashtype/$func",E_USER_ERROR);}if(!$key){trigger_error("mhash: called without key",E_USER_WARNING);}$bsize=mhash_get_block_size($hashtype);if(strlen($key)>$bsize){$key=$func($key);$key=pack("H*",$key);}$key=str_pad($key,$bsize,"\0");$ipad=str_pad("",$bsize,"6");$opad=str_pad("",$bsize,"\\");$dgst=pack("H*",$func(($key ^$ipad).$text));$dgst=pack("H*",$func(($key ^$opad).$dgst));return($dgst);}function mhash_count(){return(MHASH_SHA1);}function mhash_get_hash_name($i){static$hash_funcs=array(MHASH_CRC32=>"crc32",MHASH_MD5=>"md5",MHASH_SHA1=>"sha1",);return(strtoupper($hash_funcs[$i]));}function mhash_get_block_size($i){return(64);}}?> |