PHP userland backwards compatibility layer that emulates PHP 5.5+ core functions.

⌈⌋ branch:  upgrade.php


Check-in [39c9fa23ab]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:upgradephp-14
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:39c9fa23ab988246d7706318d7994c7e2c78bedb
User & Date: mario 2010-06-22 17:03:23
Context
2010-06-22
17:03
upgradephp-15 check-in: 51e3884900 user: mario tags: trunk
17:03
upgradephp-14 check-in: 39c9fa23ab user: mario tags: trunk
17:03
upgradephp-13 check-in: b5c10771ec user: mario tags: trunk
Changes

Changes to README.

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
...
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
...
336
337
338
339
340
341
342

343
344
345
346
347
348
349
...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
...
465
466
467
468
469
470
471






472
473
474
475
476
477
478
479
480
481
482
483

PHP downwards compatibility functions

The "upgrade.php" package implements features and functions from
later PHP versions in pure PHP script and dynamically defines them
at runtime.  This allows you to use said functions on outdated
server setups with only including() a single script.  You are freed
from wasting time with backward compatibility problems or omitting
certain useful PHP functions or retyping workarounds then, while
your applications remain "PHP 4.1+ COMPATIBLE" even if features of
PHP5 were used.


It is useful in a variety of scenarios:

 If you write PHP scripts which are distributed later to a variety
  of web servers, which may or may not run the latest PHP versions.

 If your own web space providers PHP version is immemorial.

 You want to use a PHP5 function, but know that it won't be
  available elsewhere. Or you find yourself constantly writing some
  workarounds instead of using the most useful PHP function for it.

 Support of the gettext/bcmath/ftp/... extensions would make your
  script faster and easier to maintain, but would hinder server and
  provider independence. (See our ext/ for PHP extensions.)

 If you yourself want to use a PHP application or projects, which
  depends on features not available on your server and so breaks.

 You have a sourceforge.net project homepage ;-)


It however cannot help in other cases:

 PHP5s extended object orientation language semantics aren't
  emulated, and could never be.  You won't be able to write PHP4-
  compatible scripts if you want or have to use them.

 Newer PHP versions also sometimes change the function signatures
  and add/allow new arguments. Because existing and core functions
  cannot be overridden, upgradephp won't ever make them compatible
  between versions.

 PHPs safe_mode is a hurdle you either have to pay your webhoster
  their extra fee for 'full PHP support' or make the lengthy
  "But-how-does-this-help-security-if-there-is-no-such-Safe-Mode-
  in-Perl/Python-enabled?"-discussion (with the dumber providers).
  There is absolutely no safe_mode support in upgradephp, this is
  entirely your problem.

 PHP4.1 superglobals cannot be emulated for 4.0 versions.

 Features which cannot be emulated therefore include: PHP5-OO,
  superglobals, new function arguments, stream wrappers.


Other things to note:

 Speed won't suffer on up-to-date servers, because functions are
  only emulated/deifned if they are missing (all function_exists
  checks are built-in; you don't have to care).

 Some of the functions that get defined here, are just simple
  stubs; sometimes only there to prevent E_FATAL errors.

 Emulated functions sometimes run slower than the native variant
  would, but it generally shouldn't be slower than any workaround
  you used for the [advanced but not widely available] functions
  until now.

 Most emulation functions leave the error reporting up to any
  invoked parent functions (fopen, fwrite and call_user_func_array
  for example).


Remember that native functions will be used whereever available,
this emulation only helps running scripts on aging PHP versions.



      PEAR::PHP_Compat
      
      Alternatively to the "upgradephp" package, you could also give
      the PEAR package "PHP_Compat" (by Aidan Lister & Co.) from
      [http://pear.php.net/] a try. It comes under the PHP license
      and contains cleaner code in some areas (exotic array funcs and
      PHP4.0 code).

      It is more thoroughly commented and emulates PHP error messages
      completely.  In some circumstances you could benefit from its
      divided function definitions (each in a separate file), while it
      is possible to reassamble everything into a single script.  You
      could then even load it in conjunction with upgrade.php then.

      Note: no code from PHP_Compat has been reused here (this is more
      a license thing, than NIH syndrome).



Usage

Simply include("upgrade.php"); in any of your scripts, if you want
to use some of the newer PHP4.3 or PHP5 functions like stripos() or
so.



You could additionally check the PHP_VERSION, and only include the
emulation wrapper if you depend on features from a certain PHP
interpreter release:

  <?example
     if (PHP_VERSION < "4.3.0") { include(".../upgrade.php"); }
  ?>

Currently following functions can be emulated:



 gzdecode


 ob_get_headers
 xmlentities
 stripos
 strripos
 str_ireplace
 get_headers
 headers_list
................................................................................
 odbc_fetch_object
 odbc_fetch_into
 odbc_free_result
 odbc_next_result
 odbc_num_fields
 odbc_num_rows

On a side note: You don't have to include() this func emulation

script yourself. Leave this to your users if they use an older PHP
version; a note often suffices. It however may be senseful to ship


this together with your scripts - that's also why it was released
as Public Domain (=compatible to ALL open source licenses, including
the GNU GPL).










It is safe to extract a few function bodies/definitions out of the
script to make a shorter version (load only the needed functions);
but you should keep the "if (function_exists(...))" wrapper code
always.
(PHP_Compat makes a better source, if you really need only a few
emulated functions.)




Omissions

A few PHP features are specifically NOT implemented, and so still
had to be taken care of in your scripts:

................................................................................
  and original gettext functions don't normally read this, that's a
  useless feature (just for fun). You save 2K by ripping it out.

 "ext/mime" simulates the mime_content_type() function, either by
  accessing PECL::fileinfo or reading and evaluating the magic.mime
  database itself (likely slower and a bit unclean of course)




dtools/

Please run the "updoc" script once to update your PHP manual, if you
are planning to use the upgrade.php script. Create a symlink from your
installed multi-file PHP manual to ease using this and the "doctests"
................................................................................
Please also have a peek into the README files accompaning the script
snippets distributed in this directory.



Other Notes

 Don't care about the *.meta files everywhere. They are used in
  other projects for plugin / include script management only and
  have little value else.

 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/> and also
  <http://freshmeat.net/p/upgradephp>.



License

Everything in here is Public Domain. There are no restrictions on how
or where you could use it. You may redistribute it under any license
................................................................................
to implement.



ChangeLog








v13
  - bcmath functions changed to use faster /usr/bin/dc, wrappers for GMP
    fixed and php_big_int.so usage possible
  - gettext_plural0 merged into old code and speed improved
  -

v12
  - strripos() handling of positive offsets was fixed
  - strpbrk() fixed to not return string, if nothing found
  - php_strip_whitespace() and php_check_syntax() moved into ext/exotic
  + ext/bcmath using /usr/bin/bc
  + initial mhash (HMAC) implementation with MD5 and SHA1





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|





|









|
<
>
>










>
>
>

>
>







 







<
>
|
<
>
>
|
|
|

>
>
>
>
>
>
>
>
>
|
|
|
<
<
<
>
>







 







>







 







<
<
<
<



|
|







 







>
>
>
>
>
>




<







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
...
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
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
...
413
414
415
416
417
418
419




420
421
422
423
424
425
426
427
428
429
430
431
...
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471

PHP downwards compatibility functions

The "upgrade.php" package implements features and functions from
later PHP versions in pure PHP script and dynamically defines them
at runtime. The emulated functions use exactly the same names as
the originals, and cannot perturb if the native functions exist.

So this is really a drop-in replacement, and allows you to use all
PHP features regardless of the current PHP interpreter. If you just
include() this single script you are freed from wasting time with
backward compatibility problems or omitting certain more useful PHP
functions or retyping workarounds then. Your applications remain
"PHP 4.1+ COMPATIBLE" while you in fact use PHP5.2 features.


this is useful:

- for distribution (of e.g. open source projects)  
- if your own providers PHP version is immemorial
- you want to test new functions, but not install a new PHP ver
- usage of gettext/bcmath/ftp/... extension would be nice in your
  project, but may not be available on all target web servers
- if some other PHP project has a unmet dependency on your server
- you have a sourceforge.net project homepage ;-)

tt however cannot help:

- extended PHP5 object-orientation semantics can't be emulated
- function signatures in newer PHP versions also sometimes change,
  and these cannot be overriden or extended by upgradephp
- doesn't help against amateur providers safe_mode
- compatibility with below PHP 4.0 cannot be reached


other things to note:

- as already said, speed won't suffer on up-to-date servers, because
  functions are only emulated/deifned if they are missing
- some functions are just simple stubs
- emulated functions code is often slower than the native - but few
  significantly slow your scripts (SQL accesses do)
- not all PHP errors are exactly mimicked,
  upgradephp leaves this often to parent functions (e.g. fopen)
- memory shouldn't increase significantly, because if(func_exists)
  "interpretes away" most code 


Remember that native functions will be used whereever available,
this emulation just helps getting scripts run on aging PHP versions.
































      PEAR::PHP_Compat
      
      Alternatively to the "upgradephp" package, you could also give
      the PEAR package "PHP_Compat" (by Aidan Lister & Co.) from
      [http://pear.php.net/] a try. It comes under the PHP license
      and contains cleaner code in some areas (exotic array funcs and
      PHP4.0 code for example).

      It is more thoroughly commented and emulates PHP error messages
      completely.  In some circumstances you could benefit from its
      divided function definitions (each in a separate file), while it
      is possible to reassamble everything into a single script.  You
      could even load it in conjunction with upgrade.php then.

      Note: no code from PHP_Compat has been reused here (this is more
      a license thing, than NIH syndrome).



Usage

Simply include("upgrade.php"); in any of your scripts, if you want
to rely on some PHP4.3 or PHP5.2 functions.


   include("upgrade.php");

You could additionally check the PHP_VERSION, and only include the
emulation wrapper if you depend on features from a certain PHP
interpreter release:

  <?example
     if (PHP_VERSION < "4.3.0") { include(".../upgrade.php"); }
  ?>

Currently following functions can be emulated:
 json_encode
 json_decode
 strptime
 gzdecode
 htmlspecialchars_decode
 fputcsv
 ob_get_headers
 xmlentities
 stripos
 strripos
 str_ireplace
 get_headers
 headers_list
................................................................................
 odbc_fetch_object
 odbc_fetch_into
 odbc_free_result
 odbc_next_result
 odbc_num_fields
 odbc_num_rows



Redistribution


You are encouraged to distribute "upgrade.php" together with
other / your projects. That's also why it was released as Public
Domain (=compatible to ALL open source licenses, including the
GNU GPL and LGPL).

You could load it automatically then using the PHP_VERSION check,
or simply leave this to your users if they use an older PHP version;
a note often suffices.

Of course you might want to distribute only "upgrade.php" and any
required ext/ module. Just purge the rest (dtools/ and contrib/ or
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 for such purposes.


Omissions

A few PHP features are specifically NOT implemented, and so still
had to be taken care of in your scripts:

................................................................................
  and original gettext functions don't normally read this, that's a
  useless feature (just for fun). You save 2K by ripping it out.

 "ext/mime" simulates the mime_content_type() function, either by
  accessing PECL::fileinfo or reading and evaluating the magic.mime
  database itself (likely slower and a bit unclean of course)

Other snippets in ext/ are probably incomplete or just TODO stubs.


dtools/

Please run the "updoc" script once to update your PHP manual, if you
are planning to use the upgrade.php script. Create a symlink from your
installed multi-file PHP manual to ease using this and the "doctests"
................................................................................
Please also have a peek into the README files accompaning the script
snippets distributed in this directory.



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/p/upgradephp> for update notifications.



License

Everything in here is Public Domain. There are no restrictions on how
or where you could use it. You may redistribute it under any license
................................................................................
to implement.



ChangeLog


v14
  - initial comment restructuring
  - added json_encode/decode functions, basic strptime parsing
  - php5.1 functions fputcsv, property_exists, ... and constants
  - added dtools/php-commandline/PhpFunctionCall console script

v13
  - bcmath functions changed to use faster /usr/bin/dc, wrappers for GMP
    fixed and php_big_int.so usage possible
  - gettext_plural0 merged into old code and speed improved


v12
  - strripos() handling of positive offsets was fixed
  - strpbrk() fixed to not return string, if nothing found
  - php_strip_whitespace() and php_check_syntax() moved into ext/exotic
  + ext/bcmath using /usr/bin/bc
  + initial mhash (HMAC) implementation with MD5 and SHA1

Changes to contrib/exceptions.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?php
/*
   simplistic exception handling for PHP4
   --------------------------------------
   
   As you might know, PHP5 introduced exceptions, like those from Java. 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 we 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
   ----------
  
................................................................................
   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 similar to Google to find that out
*/


#-- base class for exceptions
if (!class_exists("exception")) {
   class Exception
   {





|



|
|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?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
   ----------
  
................................................................................
   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
   {

Deleted contrib/fix.meta.

1
2
3
4
5
6
7
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
<
<
<
<
<
<
<














Changes to contrib/fix.php.

1
2








3
4
5
6
7
8
9
..
28
29
30
31
32
33
34

35
36
37
38
39
40
41
<?php
/*








   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)
................................................................................


 #-- implementation
 function ewiki_recursive_unset(&$TO, $FROM) {
    foreach ($FROM as $var=>$value) {
       if (isset($TO[$var]) && ($TO[$var]==$FROM[$var])) {
          unset($TO[$var]);

       }
    }
 }
 function ewiki_recursive_stripslashes(&$var) {
    if (is_array($var)) {
       foreach ($var as $key=>$item) {
          ewiki_recursive_stripslashes($var[$key]);


>
>
>
>
>
>
>
>







 







>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?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)
................................................................................


 #-- 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]);

Deleted contrib/http.meta.

1
2
3
4
5
6
7
8
9
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
<
<
<
<
<
<
<
<
<


















Changes to contrib/http.php.

1
2










3
4
5
6
7
8
9
...
228
229
230
231
232
233
234

235
236
237
238
239
240
241
...
502
503
504
505
506
507
508

509
510
511
512
513
514
515
...
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
<?php
/*










   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
................................................................................
      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);

      }
      fclose($this->socket);
      unset($this->socket);

      #-- for raw http pings
      if ($asis) { 
         return($DATA);
................................................................................
   

   #-- strip any content transformation
   function decodeTransferEncodings() {
      $enc = trim(strtok(strtolower($this->headers["Transfer-Encoding"]), ",;"));
      if ($enc) {
         switch ($enc) {

            case "chunked":
               $this->decodeChunkedEncoding();
               break;
            case "base64":
               $this->content = base64_decode($this->content);
               $this->len = strlen($this->content);
               break;
................................................................................


   #-- scripts on HTTP/1.1 servers may send fragmented response
   function decodeChunkedEncoding() {

      $data = "";	# decoded data
      $p = 0;		# current string position


      while ($p < strlen($this->content)) {

         #-- read len token
         $n = strtok(substr($this->content, $p, 20), "\n");

         $p += strlen($n)+1;


         #-- make integer
         $n = 0 + (int) (trim($n));



         if (!$n) {
            break;
         }


         #-- read data
         $data .= substr($this->content, $p, $n);
         $p += $n;

      }

      $this->content = $data;
      unset($data);
      $this->len = strlen($this->content);
   }



>
>
>
>
>
>
>
>
>
>







 







>







 







>







 







>


<


>

>


|
>
>
>
|
|

>



|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
...
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
<?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
................................................................................
      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);
................................................................................
   

   #-- 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;
................................................................................


   #-- scripts on HTTP/1.1 servers may send fragmented response
   function decodeChunkedEncoding() {

      $data = "";	# 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
         $data .= substr($this->content, $p, $n);
         $p += $n + 1;
#echo "CHUNK3($p,$n) ";
      }

      $this->content = $data;
      unset($data);
      $this->len = strlen($this->content);
   }

Deleted contrib/xmlrpc.meta.

1
2
3
4
5
6
7
8
9
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
<
<
<
<
<
<
<
<
<


















Changes to contrib/xmlrpc.php.

1









2
3
4
5
6
7
8
<?php define("XMLRPC_VERSION", "0.3.10");









#
#  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

>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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

Added dtools/_notdefined.







>
>
>
1
2
3
#!/usr/bin/perl -p

s/^(\s*)(define\("(.+?)".+\);)/$1if (!defined("$3")) { $2 }/;

Added dtools/php-commandline/PhpFunctionCall.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/php -qC
<?php

   #-- function name
   $func = $_SERVER["argv"][0];
   $func = substr($func, strrpos($func, "/") + 1);

   #-- args
   $args = $_SERVER["argv"];
   array_shift($args);

   #-- stdin as arg
   if (!count($args)) {
      if (($f = fopen("php://stdin", "rb"))
      and ($input = fread($f, 1<<22))) {
         array_unshift($args, $input);
         fclose($f);
      }
   }

   #-- do
   $output = call_user_func_array($func, $args);
   echo $output;

?>

Added dtools/php-commandline/README.































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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


  BEWARE: GIMMICK!!

  If you run Linux and work on the console occasionally, you probably love
  commandline tools. If you further develop PHP scripts, then you probably
  sometimes wish to test PHP functions on the fly and more easily (without
  typing yet another test script).

  If that's the case, here is a simple script to simplify this. To install
  follow these steps:


  1. Create a $HOME/bin/php directory
     (and add ~/bin/php/ to your shell PATH, of course)

  2. Move the contents of this ./ dir into ~/bin/php/

  3. Run "./make_symlinks" in this directory.

  4. Eventually adapt the interpreter shebang #! in the PhpFuncCall script.


  This will create a lot of symlinks to the "PhpFunctionCall" script. You
  then can run PHP functions on the terminal like:


   localhost:~$   base64_encode  AbcDef_1234


  Of course this is not useful for all PHP functions, because some must be
  used in conjunction or do not return displayable results. And some have
  already been removed from the list. You can of course create special PHP
  scripts, like the example 'phpecho' that call other PHP code or function
  groups, of course.

  If you run an older PHP version, then -sure-, you might want to include
  upgrade.php from within 'PhpFunctionCall'.
  


  WINDOWS

  No. Using that under Windows with its frustrating commandline window makes
  little sense.


Added dtools/php-commandline/make_symlinks.





























































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/bin/sh

SCRIPT=PhpFunctionCall
FUNCS="json_encode json_decode inet_ntop inet_pton error_get_last strptime
htmlspecialchars_decode zend_version strlen strcmp strncmp strcasecmp
strncasecmp each error_reporting define defined get_parent_class
method_exists class_exists interface_exists function_exists
get_included_files get_required_files is_subclass_of is_a get_class_vars
get_object_vars get_class_methods trigger_error user_error set_error_handler
restore_error_handler set_exception_handler restore_exception_handler
get_declared_classes get_declared_interfaces get_defined_functions
get_defined_vars create_function get_resource_type get_loaded_extensions
extension_loaded get_extension_funcs get_defined_constants debug_backtrace
debug_print_backtrace xmlrpc_encode xmlrpc_decode xmlrpc_decode_request
xmlrpc_encode_request xmlrpc_get_type xmlrpc_set_type xmlrpc_is_fault
utf8_encode utf8_decode token_get_all token_name constant bin2hex sleep
usleep time_nanosleep time mktime gmmktime strftime gmstrftime strtotime
date idate gmdate getdate localtime checkdate flush wordwrap
htmlspecialchars htmlentities html_entity_decode get_html_translation_table
sha1 sha1_file md5 md5_file crc32 iptcparse iptcembed getimagesize
image_type_to_mime_type phpinfo phpversion phpcredits php_logo_guid
php_real_logo_guid php_egg_logo_guid zend_logo_guid php_sapi_name php_uname
php_ini_scanned_files strnatcmp strnatcasecmp substr_count strspn strcspn
strtok strtoupper strtolower strpos stripos strrpos strripos strrev hebrev
hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr
stristr strrchr str_shuffle str_word_count str_split strpbrk substr_compare
strcoll money_format substr substr_replace quotemeta ucfirst ucwords strtr
addslashes addcslashes rtrim str_replace str_ireplace str_repeat count_chars
chunk_split trim ltrim strip_tags similar_text explode implode setlocale
localeconv nl_langinfo soundex levenshtein chr ord parse_str str_pad chop
strchr sprintf printf vprintf vsprintf fprintf vfprintf sscanf fscanf
parse_url urlencode urldecode rawurlencode rawurldecode http_build_query
readlink linkinfo symlink link unlink exec system escapeshellcmd
escapeshellarg passthru shell_exec proc_open proc_close proc_terminate
proc_get_status proc_nice rand srand getrandmax mt_rand mt_srand
mt_getrandmax getservbyname getservbyport getprotobyname getprotobynumber
getmyuid getmygid getmypid getmyinode getlastmod base64_decode base64_encode
convert_uuencode convert_uudecode abs ceil floor round sin cos tan asin acos
atan atan2 sinh cosh tanh asinh acosh atanh expm1 log1p pi is_finite is_nan
is_infinite pow exp log log10 sqrt hypot deg2rad rad2deg bindec hexdec
octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip
getenv putenv getopt microtime gettimeofday getrusage uniqid
quoted_printable_decode convert_cyr_string get_current_user set_time_limit
get_cfg_var get_magic_quotes_gpc get_magic_quotes_runtime
import_request_variables error_log call_user_func call_user_func_array
call_user_method call_user_method_array serialize unserialize var_dump
var_export debug_zval_dump print_r unregister_tick_function highlight_file
show_source highlight_string php_strip_whitespace php_check_syntax ini_get
ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path
restore_include_path setcookie setrawcookie header headers_sent headers_list
connection_aborted connection_status ignore_user_abort parse_ini_file
is_uploaded_file move_uploaded_file gethostbyaddr gethostbyname
gethostbynamel dns_check_record checkdnsrr dns_get_mx getmxrr dns_get_record
intval floatval doubleval strval gettype settype is_null is_resource is_bool
is_long is_float is_int is_integer is_double is_real is_numeric is_string
is_array is_object is_scalar is_callable ereg ereg_replace eregi
eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind
rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate
fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file
file_get_contents file_put_contents fgetcsv flock get_meta_tags
set_file_buffer get_headers realpath fnmatch fsockopen pfsockopen pack
unpack get_browser crypt opendir closedir chdir chroot getcwd rewinddir
readdir dir scandir glob fileatime filectime filegroup fileinode filemtime
fileowner fileperms filesize filetype file_exists is_writable is_writeable
is_readable is_executable is_file is_dir is_link stat lstat chown chgrp
chmod touch clearstatcache disk_total_space disk_free_space diskfreespace
mail ezmlm_hash openlog syslog closelog define_syslog_variables lcg_value
metaphone ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush
ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents
ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort
arsort sort rsort usort uasort uksort shuffle array_walk
array_walk_recursive count end prev next reset current key min max in_array
array_search extract compact array_fill range array_multisort array_push
array_pop array_shift array_unshift array_splice array_slice array_merge
array_merge_recursive array_keys array_values array_count_values
array_reverse array_reduce array_pad array_flip array_change_key_case
array_rand array_unique array_intersect array_uintersect
array_intersect_assoc array_uintersect_assoc array_intersect_uassoc
array_uintersect_uassoc array_diff array_udiff array_diff_assoc
array_udiff_assoc array_diff_uassoc array_udiff_uassoc array_sum
array_filter array_map array_chunk array_combine array_key_exists pos sizeof
key_exists assert assert_options version_compare ftok str_rot13
stream_get_filters output_add_rewrite_var output_reset_rewrite_vars
date_sunrise date_sunset spl_classes class_parents class_implements
use_soap_error_handler is_soap_fault simplexml_load_file
simplexml_load_string simplexml_import_dom session_name session_module_name
session_save_path session_id session_regenerate_id session_decode
session_register session_unregister session_is_registered session_encode
session_start session_destroy session_unset session_set_save_handler
session_cache_limiter session_cache_expire session_set_cookie_params
session_get_cookie_params session_write_close session_commit posix_kill
posix_getpid posix_getppid posix_getuid posix_setuid posix_geteuid
posix_seteuid posix_getgid posix_setgid posix_getegid posix_setegid
posix_getgroups posix_getlogin posix_getpgrp posix_setsid posix_setpgid
posix_getpgid posix_getsid posix_uname posix_times posix_ctermid
posix_ttyname posix_isatty posix_getcwd posix_mkfifo posix_getgrnam
posix_getgrgid posix_getpwnam posix_getpwuid posix_getrlimit
posix_get_last_error posix_errno posix_strerror preg_match preg_match_all
preg_replace preg_replace_callback preg_split preg_quote preg_grep
pcntl_fork pcntl_waitpid pcntl_wait pcntl_signal pcntl_wifexited
pcntl_wifstopped pcntl_wifsignaled pcntl_wexitstatus pcntl_wtermsig
pcntl_wstopsig pcntl_exec pcntl_alarm pcntl_getpriority pcntl_setpriority
mime_content_type iconv ob_iconv_handler iconv_get_encoding
iconv_set_encoding iconv_strlen iconv_substr iconv_strpos iconv_strrpos
iconv_mime_encode iconv_mime_decode iconv_mime_decode_headers gd_info
imagetypes jpeg2wbmp png2wbmp image2wbmp imagelayereffect imagecolormatch
imagefilter dom_import_simplexml ctype_alnum ctype_alpha ctype_cntrl
ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space
ctype_upper ctype_xdigit readgzfile gzrewind gzclose gzeof gzgetc gzgets
gzgetss gzread gzopen gzpassthru gzseek gztell gzwrite gzputs gzfile
gzcompress gzuncompress gzdeflate gzinflate gzencode ob_gzhandler
zlib_get_coding_type"


# start
if [ -e $SCRIPT ]
then

   for F in $FUNCS
   do

      ln -s $SCRIPT $F

   done

fi

Added dtools/php-commandline/phpecho.







>
>
>
1
2
3
#!/bin/sh

echo "<?php print_r($1); ?>" | php

Changes to ext/fakezlib.php.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
   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 were better off simply switching to someone else!
*/


 #-- fake zlib
 if (!function_exists("gzopen")) {

    function gzopen($fp, $mode) {







|







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
   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 seriously were better off simply switching to someone else...
*/


 #-- fake zlib
 if (!function_exists("gzopen")) {

    function gzopen($fp, $mode) {

Added ext/filter.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
<?php

/**
 * @todo
 *
 * filter_*() functions can probably be reimplemented for PHP5.0 and PHP4.x
 *
 *
 */

/*

    [1230] => filter_input
    [1231] => filter_var
    [1232] => filter_input_array
    [1233] => filter_var_array
    [1234] => filter_list
    [1235] => filter_has_var
    [1236] => filter_id

    [1071] => INPUT_POST
    [1072] => INPUT_GET
    [1073] => INPUT_COOKIE
    [1074] => INPUT_ENV
    [1075] => INPUT_SERVER
    [1076] => INPUT_SESSION
    [1077] => INPUT_REQUEST
    [1078] => FILTER_FLAG_NONE
    [1079] => FILTER_REQUIRE_SCALAR
    [1080] => FILTER_REQUIRE_ARRAY
    [1081] => FILTER_FORCE_ARRAY
    [1082] => FILTER_NULL_ON_FAILURE
    [1083] => FILTER_VALIDATE_INT
    [1084] => FILTER_VALIDATE_BOOLEAN
    [1085] => FILTER_VALIDATE_FLOAT
    [1086] => FILTER_VALIDATE_REGEXP
    [1087] => FILTER_VALIDATE_URL
    [1088] => FILTER_VALIDATE_EMAIL
    [1089] => FILTER_VALIDATE_IP
    [1090] => FILTER_DEFAULT
    [1091] => FILTER_UNSAFE_RAW
    [1092] => FILTER_SANITIZE_STRING
    [1093] => FILTER_SANITIZE_STRIPPED
    [1094] => FILTER_SANITIZE_ENCODED
    [1095] => FILTER_SANITIZE_SPECIAL_CHARS
    [1096] => FILTER_SANITIZE_EMAIL
    [1097] => FILTER_SANITIZE_URL
    [1098] => FILTER_SANITIZE_NUMBER_INT
    [1099] => FILTER_SANITIZE_NUMBER_FLOAT
    [1100] => FILTER_SANITIZE_MAGIC_QUOTES
    [1101] => FILTER_CALLBACK
    [1102] => FILTER_FLAG_ALLOW_OCTAL
    [1103] => FILTER_FLAG_ALLOW_HEX
    [1104] => FILTER_FLAG_STRIP_LOW
    [1105] => FILTER_FLAG_STRIP_HIGH
    [1106] => FILTER_FLAG_ENCODE_LOW
    [1107] => FILTER_FLAG_ENCODE_HIGH
    [1108] => FILTER_FLAG_ENCODE_AMP
    [1109] => FILTER_FLAG_NO_ENCODE_QUOTES
    [1110] => FILTER_FLAG_EMPTY_STRING_NULL
    [1111] => FILTER_FLAG_ALLOW_FRACTION
    [1112] => FILTER_FLAG_ALLOW_THOUSAND
    [1113] => FILTER_FLAG_ALLOW_SCIENTIFIC
    [1114] => FILTER_FLAG_SCHEME_REQUIRED
    [1115] => FILTER_FLAG_HOST_REQUIRED
    [1116] => FILTER_FLAG_PATH_REQUIRED
    [1117] => FILTER_FLAG_QUERY_REQUIRED
    [1118] => FILTER_FLAG_IPV4
    [1119] => FILTER_FLAG_IPV6
    [1120] => FILTER_FLAG_NO_RES_RANGE
    [1121] => FILTER_FLAG_NO_PRIV_RANGE


*/

?>

Changes to ext/ftp.php.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   Provides the usual ftp_() functions (or at least work-alikes)
   for PHP versions compiled without.

   Hint: If you want to use it with PHP versions with compiled-in FTP
   support, then simply let your text editor replace all occourences
   of "ftp_" into "xftp_" or something similar.

   FreeWare, 2004, milky*userssfnet
*/

if (!function_exists("ftp_connect")) {

 #-- config
 define("FTP_DEBUG", 0);
 define("FTP_PASV", 0);   // default data transfer mode







|







3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   Provides the usual ftp_() functions (or at least work-alikes)
   for PHP versions compiled without.

   Hint: If you want to use it with PHP versions with compiled-in FTP
   support, then simply let your text editor replace all occourences
   of "ftp_" into "xftp_" or something similar.

   Public Domain, 2004, milky*userssfnet
*/

if (!function_exists("ftp_connect")) {

 #-- config
 define("FTP_DEBUG", 0);
 define("FTP_PASV", 0);   // default data transfer mode

Deleted ext/gettext.meta.

1
2
3
4
5
6
api: PHP
type: functions
title: gettext()
description: emulates gettext functionality
priority: auto
category: library
<
<
<
<
<
<












Changes to ext/gettext.php.

1
2







3
4
5
6
7
8
9
..
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
...
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
...
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
<?php
/*







   This include script simulates gettext() functionality.
    - It could read translation data from .mo and .po files.
    - Lookup of plural forms mostly work (but not 100% compliant,
      no real interpreter for Plural-Forms: expression).
    - Categories/codesets are ignored.

   Besides using setlocale() you should change the $_ENV["LANG"] var
................................................................................
   What's often more user-friendly than hardwired server-side values.
*/


#-- emulate only if not present in current PHP interpreter
if (!function_exists("gettext")) {


   #-- all-in-one combined implementation
   #   (in original API only the first parameter is present)
   function gettext($msg, $msg2=NULL, $domain=NULL, $category=NULL, $plural=NULL) {
      global $_GETTEXT;

      #-- get default params if corresponding args are empty
      if (!isset($domain)) {
         $domain = $_GETTEXT["%domain"];
      }
      if (empty($_GETTEXT[$domain])) {
         bindtextdomain($domain);  // auto load from system dirs
      }

      #-- plural array position
      if (!isset($plural)) {
         $pli = 0;
      }
      elseif ($ph = $_GETTEXT[$domain]["%plural-c"]) {
         $pli = gettext___plural_guess($ph, $plural);
      }
      else {
         $pli = ($plural != 1) ? 1 : 0;   // English
      }

      #-- look up string
      if (($trans = $_GETTEXT[$domain][$msg])
      or ($pli) and ($trans = $_GETTEXT[$domain][$msg2]))
      {
         // handle plural entries
         if (is_array($trans)) {
            if (!isset($trans[$pli])) {
               $pli = 0;   // missing translation
            }
................................................................................
   }


   #-- sets current translation data source
   #   (must have been loaded beforehand)
   function textdomain($default="NULL") {
      global $_GETTEXT;
      $prev = $_GETTEXT["%domain"];
      if (isset($default)) {
         $_GETTEXT["%domain"] = $default;
      }
      return $prev;
   }


   #-- loads data files
   function bindtextdomain($domain, $directory="/usr/share/locale:/usr/local/share/locale:./locale") {
      global $_GETTEXT;
      if (isset($_GETTEXT["domain"]) && (count($_GETTEXT["domain"]) > 3)) {
         return;  // don't load twice
      }
      $_GETTEXT[$domain]["%dir"] = $directory;
      $_GETTEXT["%locale"] = setlocale(LC_CTYPE, 0);

      #-- allowed languages
      $langs = "$_ENV[LANGUAGE],$_ENV[LC_ALL],$_ENV[LC_MESSAGE],$_ENV[LANG],"
             . $_GETTEXT["%locale"] . ",$_SERVER[HTTP_ACCEPT_LANGUAGE],C,en";


          
      #-- add shortened language codes (en_UK.UTF-8 -> + en_UK, en)
      foreach (explode(",",$langs) as $d) {
         $d = trim($d);
         // $dir2[] = $d;
         $d = strtok($d, "@.-+=%:; ");
         if (strlen($d)) {
            $dir2[] = $d;
         }
         if (strpos($d, "_")) {
            $dir2[] = strtok($d, "_");
         }
      }
      
      #-- search for matching directory and load data file
      foreach (explode(":", $directory) as $directory) {
         foreach ($dir2 as $lang) {
            $base_fn = "$directory/$lang/LC_MESSAGES/$domain";



            #-- binary format
            if (file_exists($fn = "$base_fn.mo") && ($f = fopen($fn, "rb")))
            {
               gettext___load_mo($f, $domain);
               break 2;
            }
................................................................................
            }
         }
      }//foreach
      
      #-- extract headers
      if ($head = $_GETTEXT[$domain][""]) {
         foreach (explode("\n", $head) as $line) {
            $header = strtok(":", $line);
            $line = trim(strtok("\n"));
            $_GETTEXT[$domain]["%po-header"][strtolower($header)] = $line;
         }
      
         #-- plural-forms header
         if (function_exists("gettext___plural_guess")
         and ($h = $_GETTEXT[$domain]["%po-header"]["plural-forms"]))
         {
            $h = preg_replace("/[(){}\[\]^\s*\\]+/", "", $h);  // rm whitespace
            gettext___plural_guess($h, 0);  // pre-decode into algorithm type integer
            $_GETTEXT[$domain]["%plural-c"] = $h;
         }
      }

      #-- set as default textdomain
      if (empty($_GETTEXT["%domain"])) {
         textdomain($domain);
      }
      return($domain);
   }


   #-- load string data from binary .mo files (ign checksums)


>
>
>
>
>
>
>







 







<







|









|







|







 







|

|








|


|
|


|
|
>
>


|






|
|


|

|


>
>







 







|

|




|



|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
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
...
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
...
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
<?php
/*
  api: PHP
  type: functions
  title: gettext()
  description: emulates gettext functionality
  priority: auto
  category: library

   This include script simulates gettext() functionality.
    - It could read translation data from .mo and .po files.
    - Lookup of plural forms mostly work (but not 100% compliant,
      no real interpreter for Plural-Forms: expression).
    - Categories/codesets are ignored.

   Besides using setlocale() you should change the $_ENV["LANG"] var
................................................................................
   What's often more user-friendly than hardwired server-side values.
*/


#-- emulate only if not present in current PHP interpreter
if (!function_exists("gettext")) {


   #-- all-in-one combined implementation
   #   (in original API only the first parameter is present)
   function gettext($msg, $msg2=NULL, $domain=NULL, $category=NULL, $plural=NULL) {
      global $_GETTEXT;

      #-- get default params if corresponding args are empty
      if (!isset($domain)) {
         $domain = $_GETTEXT['%domain'];
      }
      if (empty($_GETTEXT[$domain])) {
         bindtextdomain($domain);  // auto load from system dirs
      }

      #-- plural array position
      if (!isset($plural)) {
         $pli = 0;
      }
      elseif ($ph = $_GETTEXT[$domain]['%plural-c']) {
         $pli = gettext___plural_guess($ph, $plural);
      }
      else {
         $pli = ($plural != 1) ? 1 : 0;   // English
      }

      #-- look up string
      if (isset($_GETTEXT[$domain][$msg]) && ($trans = $_GETTEXT[$domain][$msg])
      or ($pli) and ($trans = $_GETTEXT[$domain][$msg2]))
      {
         // handle plural entries
         if (is_array($trans)) {
            if (!isset($trans[$pli])) {
               $pli = 0;   // missing translation
            }
................................................................................
   }


   #-- sets current translation data source
   #   (must have been loaded beforehand)
   function textdomain($default="NULL") {
      global $_GETTEXT;
      $prev = isset($_GETTEXT['%domain']) ? $_GETTEXT['%domain'] : NULL;
      if (isset($default)) {
         $_GETTEXT['%domain'] = $default;
      }
      return $prev;
   }


   #-- loads data files
   function bindtextdomain($domain, $directory="/usr/share/locale:/usr/local/share/locale:./locale") {
      global $_GETTEXT;
      if (isset($_GETTEXT[$domain]) && (count($_GETTEXT[$domain]) > 3)) {
         return;  // don't load twice
      }
      $_GETTEXT[$domain]['%dir'] = $directory;
      $_GETTEXT['%locale'] = setlocale(LC_CTYPE, 0);

      #-- allowed languages
      $langs = @$_ENV['LANGUAGE'] . ',' . @$_ENV['LC_ALL'] . ','
             . @$_ENV['LC_MESSAGE'] .',' . @$_ENV['LANG'] . ','
             . @$_GETTEXT['%locale'] . ',' . @$_SERVER['HTTP_ACCEPT_LANGUAGE']
             . ',C,en';
          
      #-- add shortened language codes (en_UK.UTF-8 -> + en_UK, en)
      foreach (explode(',', $langs) as $d) {
         $d = trim($d);
         // $dir2[] = $d;
         $d = strtok($d, "@.-+=%:; ");
         if (strlen($d)) {
            $dir2[] = $d;
         }
         if (strpos($d, '_')) {
            $dir2[] = strtok($d, '_');
         }
      }

      #-- search for matching directory and load data file
      foreach (explode(':', $directory) as $directory) {
         foreach ($dir2 as $lang) {
            $base_fn = "$directory/$lang/LC_MESSAGES/$domain";

#echo "GETTEXT:$lang:$base_fn\n";

            #-- binary format
            if (file_exists($fn = "$base_fn.mo") && ($f = fopen($fn, "rb")))
            {
               gettext___load_mo($f, $domain);
               break 2;
            }
................................................................................
            }
         }
      }//foreach
      
      #-- extract headers
      if ($head = $_GETTEXT[$domain][""]) {
         foreach (explode("\n", $head) as $line) {
            $header = strtok(':', $line);
            $line = trim(strtok("\n"));
            $_GETTEXT[$domain]['%po-header'][strtolower($header)] = $line;
         }
      
         #-- plural-forms header
         if (function_exists("gettext___plural_guess")
         and ($h = @$_GETTEXT[$domain]['%po-header']["plural-forms"]))
         {
            $h = preg_replace("/[(){}\[\]^\s*\\]+/", "", $h);  // rm whitespace
            gettext___plural_guess($h, 0);  // pre-decode into algorithm type integer
            $_GETTEXT[$domain]['%plural-c'] = $h;
         }
      }

      #-- set as default textdomain
      if (empty($_GETTEXT['%domain'])) {
         textdomain($domain);
      }
      return($domain);
   }


   #-- load string data from binary .mo files (ign checksums)

Added ext/pdo.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
<?php
/*
   api: PHP
   
   TODO.
   However, PDO cannot be emulated fully, not on PHP4 especially, because
   the SPL and meta object semantics won't work there. Eventually a subset
   can be reimplemented however. (Would be more useful than ADO and PEARDB
   at least.)
*/


#-- stub
if (!function_exists()) {
   function pdo_drivers() {
      return array();
   }
}


#-- PDO
if (!class_exists("pdo")) {
}

?>

Changes to ext/posix.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/*
   POSIX subsystem functions are emulated using regular commandline
   utilities or by invoking Perl.  Of course not the full spectrum
   of features can be simulated this way.  And normally all these
   functions should be present.
*/

if (!function_exists("posix_mkfifo") && strlen($_ENV["SHELL"]) && !ini_get("safe_mode")) {

   function posix_mkfifo($pathname, $mode=0400) {
      $cmd = "/usr/bin/mkfifo -m 0" . decoct($mode) . " " . escape_shell_arg($pathname);
      exec($cmd, $uu, $error);




|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/*
   POSIX subsystem functions are emulated using regular commandline
   utilities or by invoking Perl.  Of course not the full spectrum
   of features can be simulated this way. You shouldn't rely on the
   emulation here, and just abort on PHP version without POSIX ext.
*/

if (!function_exists("posix_mkfifo") && strlen($_ENV["SHELL"]) && !ini_get("safe_mode")) {

   function posix_mkfifo($pathname, $mode=0400) {
      $cmd = "/usr/bin/mkfifo -m 0" . decoct($mode) . " " . escape_shell_arg($pathname);
      exec($cmd, $uu, $error);

Added tests/json.













































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

include("../upgrade.php");

$a = array(
  "x" => "y",
  "text" => "Hallchen
",
  "abc" => TRUE,
  "int" => 512,
  "float" => 3.14159,
  "null" => NULL,
  "sub" => array(1,2,3),
  "sub2" => array(1,2,"a"=>3),
);

for ($n=0; $n<1000; $n++)
$js = json_encode($a);

echo "$js\n";

?>

Added tests/json2.





















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<?php

include("../upgrade.php");
error_reporting(E_ALL);

$s = ' { "A" : [ 1 , 2 ] , "B" : [ 3.1 , 4.2e10 ]   } ';
$s =<<<END
{"menu": {
    "header": "SVG Viewer",
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},
        null,
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},
        {"id": "OriginalView", "label": "Original View"},
        null,
        {"id": "Quality"},
        {"id": "Pause"},
        {"id": "Mute"},
        null,
        {"id": "Find", "label": "Find..."},
        {"id": "FindAgain", "label": "Find Again"},
        {"id": "Copy"},
        {"id": "CopyAgain", "label": "Copy Again"},
        {"id": "CopySVG", "label": "Copy SVG"},
        {"id": "ViewSVG", "label": "View SVG"},
        {"id": "ViewSource", "label": "View Source"},
        {"id": "SaveAs", "label": "Save As"},
        null,
        {"id": "Help"},
        {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]
}}
END;

for ($n=0;$n<1000;$n++) {
  $a = json_decode($s, 0);
}
print_r($a);

?>

Added tests/strftime.































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

include("../upgrade.php");


$format = "time=%T date=%D";
$str = strftime($format, time());

$r = strptime($str, $format);

echo "$str\n";
print_r($r);


?>

Deleted upgrade.meta.

1
2
3
4
5
6
7
8
9
10
11
api: PHP
type: emulation
priority: auto
category: library
sort: -200
provides: upgrade-php
title: PHP-Upgrade
description: backwards-compatility layer for older PHP versions
license: Public Domain
url: http://freshmeat.net/p/upgradephp
version: 13
<
<
<
<
<
<
<
<
<
<
<






















Changes to 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







































































































































































































































































































































































































































































































































































































32
33

34
35
36










37
38






















39
40
41
42
43
44
45
...
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
...
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
...
823
824
825
826
827
828
829




830


831

















832











































833
834
835


836
837
838
839
840
841
842
...
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
....
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
....
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
....
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
....
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
<?php
/*
   This include() script adds missing PHP functions to earlier interpreter
   versions, so you can make downwards compatible scripts without having
   to stick to the least common denominator. It only defines the ones that
   are really missing - the faster native functions will be used whenever
   available.







   - many of the emulation functions are one-liners
   - a few features have been added that never made it into one of the
     official versions (CVS code and the ever-absent "gzdecode" and
     "file_put_contents" for example)
   - a few very extravagant functions (array_u?diff*_u*assoc?) and other
     extensions have been separated out into ext/
   - the advanced OO-capabilities and language syntax extensions of PHP5

     and ZE2 cannot seriously be emulated here, this emulation only takes 
     care of procedural interfaces
   - with only this part loaded, you get "PHP 4.1 COMPATIBILITY"








   - this is PuplicDomain (no copyright, no license, no warranty) so you
     can melt it into anything, regardless of your preferred license (you
     may strip this paragraph and turn it all into GPL, BSD, GNU LGPL,
     Artistic, MPL, PHP license, M$ EULA, or whatever you like best)



   
   Get update notes via "http://freshmeat.net/projects/upgradephp" or
   google for it. Any contribution is appreciated. <milky*userssfnet>

*/




#------------------------------------------------------------------ CVS ---
// most of this appeared in 5.0







































































































































































































































































































































































































































































































































































































// ...















#------------------------------------------------------------------ 6.0 ---
// following functions were never implemented in PHP
























#-- inflates a string enriched with gzip headers
#   (this is the logical counterpart to gzencode(), but don't tell anyone!)
if (!function_exists("gzdecode")) {
   function gzdecode($data, $maxlen=NULL) {

................................................................................
        "<"=>"&lt;", ">"=>"&gt;", "\""=>"&quot;", 
      ));
   }
}






#------------------------------------------------------------------ 5.0 ---




















































# set_exception_handler - unimpl.
# restore_exception_handler - unimpl.
# debug_print_backtrace - unimpl.
# class_implements - unimplementable
# proc_terminate - unimpl?
# proc_get_status - unimpl.
# --
# proc_nice
# dns_get_record
# date_sunrise - undoc.
# date_sunset - undoc.




#-- constant: end of line
if (!defined("PHP_EOL")) {
   define("PHP_EOL", ( (DIRECTORY_SEPARATOR == "\\") ?"\015\012" :(strncmp(PHP_OS,"D",1)?"\012":"\015") )  ); #"
}




#-- case-insensitive string search function,
#   - finds position of first occourence of a string c-i
#   - parameters identical to strpos()
if (!function_exists("stripos")) {
   function stripos($haystack, $needle, $offset=NULL) {
................................................................................
         return($length == $written);
      }
   }
}


#-- file-related constants
if (!defined("FILE_APPEND")) {
   define("FILE_USE_INCLUDE_PATH", 1);
   define("FILE_IGNORE_NEW_LINES", 2);
   define("FILE_SKIP_EMPTY_LINES", 4);
   define("FILE_APPEND", 8);

   define("FILE_NO_DEFAULT_CONTEXT", 16);
}


#-- more new constants for 5.0
if (!defined("E_STRICT")) {
   define("E_STRICT", 2048);  // _STRICT is a special case of _NOTICE (_DEBUG)
   # PHP_CONFIG_FILE_SCAN_DIR
}


#-- array count_recursive()

if (!defined("COUNT_RECURSIVE")) {
   define("COUNT_NORMAL", 0);       // count($array, 0);
   define("COUNT_RECURSIVE", 1);    // not supported
}


#-- we introduce a new function, because we cannot emulate the
#   newly introduced second parameter to count()
if (!function_exists("count_recursive")) {
   function count_recursive($array, $mode=1) {
      if (!$mode) {
................................................................................
   }
}






























#------------------------------------------------------------------ 4.3 ---











































# money_format - unimpl?
# sha1, sha1_file - too much code to pack it into here; and this
#                   has already been implemented elsewhere, btw




#-- simplified file read-at-once function
if (!function_exists("file_get_contents")) {
   function file_get_contents($filename, $use_include_path=1) {

      #-- open file, let fopen() report error
................................................................................



#-- shell-like filename matching (* and ? globbing characters)
if (!function_exists("fnmatch")) {

   #-- associated constants
   define("FNM_PATHNAME", 1<<0);  // no wildcard ever matches a "/"
   define("FNM_NOESCAPE", 1<<1);  // backslash can't escape meta chars
   define("FNM_PERIOD",   1<<2);  // leading dot must be given explicit
   define("FNM_LEADING_DIR", 1<<3);  // not in PHP
   define("FNM_CASEFOLD", 0x50);  // match case-insensitive
   define("FNM_EXTMATCH", 1<<5);  // not in PHP
   
   #-- implementation
   function fnmatch($pattern, $str, $flags=0x0000) {
      
      #-- 'hidden' files
      if ($flags & FNM_PERIOD) {
         if (($str[0] == ".") && ($pattern[0] != ".")) {
................................................................................
}


#-- file search and name matching (with shell patterns)
if (!function_exists("glob")) {

   #-- introduced constants
   define("GLOB_MARK", 1<<0);
   define("GLOB_NOSORT", 1<<1);
   define("GLOB_NOCHECK", 1<<2);
   define("GLOB_NOESCAPE", 1<<3);
   define("GLOB_BRACE", 1<<4);
   define("GLOB_ONLYDIR", 1<<5);
   define("GLOB_NOCASE", 1<<6);
   define("GLOB_DOTS", 1<<7);
   // unlikely to work under Win(?), without replacing the explode() with
   // a preg_split() incorporating the native DIRECTORY_SEPARATOR as well

   #-- implementation
   function glob($pattern, $flags=0x0000) {
      $ls = array();
      $rxci = ($flags & GLOB_NOCASE) ? "i" : "";
................................................................................
   function restore_include_path() {
      ini_restore("include_path");
   }
}


#-- constants for 4.3
if (!defined("PATH_SEPARATOR")) {
   define("PATH_SEPARATOR", ((DIRECTORY_SEPARATOR=='\\') ? ';' :':'));
   define("PHP_SHLIB_SUFFIX", ((DIRECTORY_SEPARATOR=='\\') ? 'dll' :'so'));
}
if (!defined("PHP_SAPI")) {
   define("PHP_SAPI", php_sapi_name());
}
if (!defined("__FUNCTION__")) {
   define("__FUNCTION__", NULL);   // empty string would signalize main()
}


#-- not identical to what PHP reports (it seems to `which` for itself)
if (!defined("PHP_PREFIX") && isset($_ENV["_"])) { 
   define("PHP_PREFIX", substr($_ENV["_"], 0, strpos($_ENV["_"], "bin/")));
}






#------------------------------------------------------------------ 4.2 ---
................................................................................
}


#-- well, if you need it
if (!function_exists("array_change_key_case")) {
   
   #-- introduced constants
   define("CASE_LOWER", 0);
   define("CASE_UPPER", 1);
   
   #-- implementation
   function array_change_key_case($array, $case=CASE_LOWER) {
   
      #-- loop through
      foreach ($array as $i=>$v) {
         #-- do anything for strings only
................................................................................
}


#-- floats
if (!function_exists("is_infinite")) {

   #-- constants as-is
   define("NAN", "NAN");
   define("INF", "INF");   // there is also "-INF"
   
   #-- simple checks
   function is_infinite($f) {
      $s = (string)$f;
      return(  ($s=="INF") || ($s=="-INF")  );
   }
   function is_nan($f) {
................................................................................
}


#-- HMAC from RFC2104, but see also PHP_Compat and Crypt_HMAC
if (!function_exists("mhash")) {

   #-- constants
   define("MHASH_CRC32", 0);
   define("MHASH_MD5", 1);       // RFC1321
   define("MHASH_SHA1", 2);      // RFC3174
   define("MHASH_TIGER", 7);
   define("MHASH_MD4", 16);      // RFC1320
   define("MHASH_SHA256", 17);
   define("MHASH_ADLER32", 18);
   
   #-- implementation
   function mhash($hashtype, $text, $key) {
   
      #-- hash function
      if (!($func = mhash_get_hash_name($hashtype)) || !function_exists($func)) {
         return trigger_error("mhash: cannot use hash algorithm #$hashtype/$func", E_USER_ERROR);

|
|
|
|
|
|
>
>
>
>
>
>
|
<
<
<
<
<
<
<
>
|
|
|
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
|
|
|
>
|



>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
|
|

>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
<
<
<
<
<
|
>


<
<
<
|
>
>







 







<
|
|
|
<
>
|
<



<
|
|
<



>
|
<
<
<







 







>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
>
>







 







|
|
|
|
|
|







 







|
|
|
|
|
|
|
|







 







<
|
|
<
|
<
<
|
<
<



|
<
<







 







|
|







 







|
|







 







|
|
|
|
|
|
|







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
...
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
....
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460

1461
1462

1463
1464
1465

1466
1467

1468
1469
1470
1471
1472



1473
1474
1475
1476
1477
1478
1479
....
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567


1568
1569
1570
1571
1572
1573
1574
1575
1576
....
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
....
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
....
1890
1891
1892
1893
1894
1895
1896

1897
1898

1899


1900


1901
1902
1903
1904


1905
1906
1907
1908
1909
1910
1911
....
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
....
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
....
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
<?php
/**
 * api:		php
 * title:	upgrade.php
 * description:	backwards compatibility for older PHP interpreters
 * version:	14
 * license:	Public Domain
 * url:		http://freshmeat.net/p/upgradephp
 * type:	functions
 * category:	library
 * priority:	auto
 * sort:	-200
 * provides:	upgrade-php
 *







 *
 * You get PHP version independence by including() this script. It provides
 * downwards compatibility to older PHP installations 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, and to free you from rewriting or
 * cumbersome workarounds - instead of using the real & more powerful funcs.
 * 
 * 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.
 * 
 * And further this is PUBLIC DOMAIN (no copyright, no license, no warranty)



 * so threrefore 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, Artist, PHPL, ...)
 *
 * Get update notes via "http://freshmeat.net/projects/upgradephp" or
 * google for it. Any contribution is appreciated. <milky*userssfnet>
 *
 */



/**
 *                                   ------------------------------ CVS ---

 * @group CVS
 * @since CVS
 *
 * planned, but as of yet unimplemented functions
 * - some of these might appear in 6.0 or ParrotPHP
 *
 * @emulated
 *    sys_get_temp_dir
 *
 */



/**
 * returns path of the system directory for temporary files
 *
 */
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);
   }
}





/**
 *                                   ------------------------------ 5.2 ---
 * @group 5_2
 * @since 5.2
 *
 * Additions of PHP 5.2.0
 * - some listed here, might have appeared earlier or in release candidates
 *
 * @emulated
 *    json_encode
 *    json_decode
 *    error_get_last
 *    preg_last_error
 *    lchown
 *    lchgrp
 *    E_RECOVERABLE_ERROR
 *    M_SQRTPI
 *    M_LNPI
 *    M_EULER
 *    M_SQRT3
 *
 * @missing
 *    sys_getloadavg
 *    inet_ntop
 *    inet_pton
 *    array_fill_keys
 *    array_intersect_key
 *    array_intersect_ukey
 *    array_diff_key
 *    array_diff_ukey
 *    array_product
 *    pdo_drivers
 *    ftp_ssl_connect
 *    XmlReader
 *    XmlWriter
 *    PDO*
 *
 * @unimplementable
 *    stream_*
 *
 */



/**
 * @since unknown
 */
if (!defined("E_RECOVERABLE_ERROR")) { define("E_RECOVERABLE_ERROR", 4096); }



/**
 * Converts PHP variable or array into "JSON" (a JavaScript value expression
 * or "object notation").
 *
 * @compat
 *    output seems identical to PECL versions
 * @bugs
 *    doesn't take care with unicode too much
 *
 */
if (!function_exists("json_encode")) {
   function json_encode($var, /*emu_args*/$obj=FALSE) {
   
      #-- prepare JSON string
      $json = "";
      
      #-- add array entries
      if (is_array($var) || ($obj=is_object($var))) {

         #-- check if array is associative
         if (!$obj) foreach ((array)$var as $i=>$v) {
            if (!is_int($i)) {
               $obj = 1;
               break;
            }
         }

         #-- concat invidual entries
         foreach ((array)$var as $i=>$v) {
            $json .= ($json ? "," : "")    // comma separators
                   . ($obj ? ("\"$i\":") : "")   // assoc prefix
                   . (json_encode($v));    // value
         }

         #-- enclose into braces or brackets
         $json = $obj ? "{".$json."}" : "[".$json."]";
      }

      #-- strings need some care
      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 . '"';
      }

      #-- basic types
      elseif (is_bool($var)) {
         $json = $var ? "true" : "false";
      }
      elseif ($var === NULL) {
         $json = "null";
      }
      elseif (is_int($var) || is_float($var)) {
         $json = "$var";
      }

      #-- something went wrong
      else {
         trigger_error("json_encode: don't know what a '" .gettype($var). "' is.", E_USER_ERROR);
      }
      
      #-- done
      return($json);
   }
}



/**
 * Parses JSON (JavaScript value expression) into PHP variable
 * (array or object).
 *
 * @compat
 *    behaves similiar to PECL version
 *    but is less quiet on errors
 *    might ignore some misformed representations
 * @bugs
 *    doesn't decode unicode \uXXXX string escapes
 *
 */
if (!function_exists("json_decode")) {
   function json_decode($json, $assoc=FALSE, /*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", "/"=>"/");

      #-- flat char-wise parsing
      for (/*n*/; $n<strlen($json); /*n*/) {
         $c = $json[$n];

         #-= in-string
         if ($state==='"') {
            if ($c == '\\') {
               $c = $json[++$n];
               if (isset($str_eq[$c])) {
                  $val .= $str_eq[$c];
               }
               elseif ($c == "u") {
                  $val .= "\\u";
               }
               else {
                  $val .= "\\" . $c;
               }
            }
            elseif ($c == '"') {
               $state = 0;
            }
            else {
               $val .= $c;
            }
         }

         #-> 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, 0, $n, 0, ",]");
            $val[] = $v;
            if ($json[$n] == "]") { return array($val, $n); }
         }

         #-= in-object
         elseif ($state==='}') {
            list($i, $n) = json_decode($json, 0, $n, 0, ":");   // this allowed non-string indicies
            list($v, $n) = json_decode($json, 0, $n+1, 0, ",}");
            $val[$i] = $v;
            if ($json[$n] == "}") { return array($val, $n); }
         }

         #-- looking for next item (0)
         else {
         
            #-> whitesapce
            if (preg_match("/\s/", $c)) {
               // skip
            }

            #-> string begin
            elseif ($c == '"') {
               $state = '"';
            }

            #-> object
            elseif ($c == "{") {
               list($val, $n) = json_decode($json, $assoc, $n+1, '}', "}");
               if ($val && $n && !$assoc) {
                  $obj = new stdClass();
                  foreach ($val as $i=>$v) {
                     $obj->{$i} = $v;
                  }
                  $val = $obj;
                  unset($obj);
               }
            }
            #-> array
            elseif ($c == "[") {
               list($val, $n) = json_decode($json, $assoc, $n+1, ']', "]");
            }

            #-> comment
            elseif (($c == "/") && ($json[$n+1]=="*")) {
               // just find end, skip over
               ($n = strpos($json, "*/", $n+1)) or ($n = strlen($json));
            }

            #-> numbers
            elseif (preg_match("#^(-?\d+(?:\.\d+)?)(?:[eE](-?\d+))?#", substr($json, $n), $uu)) {
               $val = $uu[1];
               $n += strlen($uu[0]) - 1;
               $val = strpos($val, ".") ? (float)$val : (int)$val;
               if (isset($uu[2])) {
                  $val *= pow(10, (int)$uu[2]);
               }
            }

            #-> boolean or null
            elseif (preg_match("#^(true|false|null)\b#", substr($json, $n), $uu)) {
               $val = $lang_eq[$uu[1]];
               $n += strlen($uu[1]) - 1;
            }

            #-- parsing error
            else {
               // PHPs native json_decode() breaks here usually and QUIETLY
              trigger_error("json_decode: error parsing '$c' at position $n", E_USER_WARNING);
               return $waitfor ? array(NULL, 1<<30) : NULL;
            }

         }//state
         
         #-- next char
         if ($n === NULL) { return NULL; }
         $n++;
      }//for

      #-- final result
      return ($val);
   }
}




/**
 * @stub
 * @cannot-reimplement
 *
 */
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;
   }
}




/**
 * @stub
 *
 * Returns 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
 *
 * Change owner/group 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);
   }
}
if (!function_exists("lchgrp")) {
   function lchgrp($fn, $group) {
      return lchown($fn, ":$group");
   }
}














/**
 *                                   ------------------------------ 5.1 ---
 * @group 5_1
 * @since 5.1
 *
 * Additions in PHP 5.1
 * - most functions here appeared in -rc1 already
 * - and were backported to 4.4 series?
 *
 * @emulated
 *    property_exists
 *    time_sleep_until
 *    fputcsv
 *    strptime
 *    ENT_COMPAT
 *    ENT_QUOTES
 *    ENT_NOQUOTES
 *    htmlspecialchars_decode
 *    PHP_INT_SIZE
 *    PHP_INT_MAX
 *    M_SQRTPI
 *    M_LNPI
 *    M_EULER
 *    M_SQRT3
 *
 * @missing
 *    strptime
 *
 * @unimplementable
 *    ...
 *
 */



/**
 * Constants for future 64-bit integer support.
 *
 */
if (!defined("PHP_INT_SIZE")) { define("PHP_INT_SIZE", 4); }
if (!defined("PHP_INT_MAX")) { define("PHP_INT_MAX", 2147483647); }



/**
 * @flag bugfix
 * @see #33895
 *
 * Missing constants in 5.1, originally appeared in 4.0.
 */
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); }




#-- removes entities &lt; &gt; &amp; and &quot; eventually from HTML string
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("&lt;", "&gt;", ($s ? "&quot;" : "&.-;"), ($d ? "&#039;" : "&.-;"), "&amp;"),
         array("<",    ">",    "'",                      "\"",                     "&"),
         $string
      );
   }
}


/**
 * @flag quirky, needs5
 *
 * Checks for existence of object property, should return TRUE even for NULL values.
 *
 * @compat
 *    uses (array) conversion to test, but that might not always work
 * @bugs
 *    probably can't handle static classes well
 */
# doesn't return true for NULL values, can't handle public/private
if (!function_exists("property_exists")) {
   function property_exists($obj, $prop) {
      if (!is_object($obj) && class_exists($obj)) {
         $obj = new $obj();
      }
      if (is_object($obj)) {
         return isset($obj->{$prop}) || in_array($prop, array_keys((array)$obj));
      }
   }
}


#-- halt execution, until given timestamp
// I wonder who always comes up with such useless function ideas
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;
      }
   }
}



/**
 * @untested
 *
 * Writes an array as CSV text line into opened filehandle.
 *
 */
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");
   }
}



/**
 * @stub
 * @untested
 * @flag basic
 *
 * @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) {
      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,
      );

      #-- transform $format into extraction regex
      $format = str_replace(array_keys($expand), array_values($expand), $format);
      $preg = preg_replace("/(%\w)/", "(\w+)", preg_quote($format));

      #-- record the positions of all STRFCMD-placeholders
      preg_match_all("/(%\w)/", $format, $positions);
      $positions = $positions[1];
      
      #-- get individual values
      if (preg_match("#$preg#", "$str", $extracted)) {

         #-- get values
         foreach ($positions as $pos=>$strfc) {
            $v = $extracted[$pos + 1];

            #-- add
            if ($n = $map_r[$strfc]) {
               $vals[$n] = ($v > 0) ? (int)$v : $v;
            }
            else {
               $vals["unparsed"] .= $v . " ";
            }
         }
         
         #-- fixup some entries
         $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;
         }
         
         #-- calculate wday
         // ... (mktime)
      }
      return isset($vals) ? $vals : false;
   }
}










/**
 *                                   --------------------------- FUTURE ---

 * @group FUTURE
 * @since unknown
 *
 * Following functions aren't implemented in current PHP versions allthough
 * they are logical and required counterparts to existing features or exist
 * in the according external library.
 *
 * @emulated
 *    gzdecode
 *    ob_get_headers
 *    xmlentities
 *
 * @missing
 *    ...
 *
 * @unimplementable
 *    ... 
 *
 */





#-- inflates a string enriched with gzip headers
#   (this is the logical counterpart to gzencode(), but don't tell anyone!)
if (!function_exists("gzdecode")) {
   function gzdecode($data, $maxlen=NULL) {

................................................................................
        "<"=>"&lt;", ">"=>"&gt;", "\""=>"&quot;", 
      ));
   }
}





/**
 *                                   ------------------------------ 5.0 ---
 * @group 5_0
 * @since 5.0
 *
 * PHP 5.0 introduces the Zend Engine 2 with new object-orientation features
 * which cannot be reimplemented/defined for PHP4. The additional procedures
 * and functions however can.
 *
 * @emulated
 *    stripos
 *    strripos
 *    str_ireplace
 *    get_headers
 *    headers_list
 *    fprintf
 *    vfprintf
 *    str_split
 *    http_build_query
 *    convert_uuencode
 *    convert_uudecode
 *    scandir
 *    idate
 *    time_nanosleep
 *    strpbrk
 *    get_declared_interfaces
 *    array_combine
 *    array_walk_recursive
 *    substr_compare
 *    spl_classes
 *    class_parents
 *    session_commit
 *    dns_check_record
 *    dns_get_mx
 *    setrawcookie
 *    file_put_contents
 *    COUNT_NORMAL
 *    COUNT_RECURSIVE
 *    count_recursive
 *    FILE_USE_INCLUDE_PATH
 *    FILE_IGNORE_NEW_LINES
 *    FILE_SKIP_EMPTY_LINES
 *    FILE_APPEND
 *    FILE_NO_DEFAULT_CONTEXT
 *    E_STRICT
 *
 * @missing
 *    proc_nice
 *    dns_get_record
 *    date_sunrise - undoc.
 *    date_sunset - undoc.
 *    PHP_CONFIG_FILE_SCAN_DIR
 *
 * @unimplementable
 *    set_exception_handler
 *    restore_exception_handler
 *    debug_print_backtrace
 *    class_implements
 *    proc_terminate
 *    proc_get_status





 *
 */






#-- constant: end of line
if (!defined("PHP_EOL")) { define("PHP_EOL", ( (DIRECTORY_SEPARATOR == "\\") ? "\015\012" : (strncmp(PHP_OS, "D", 1) ? "\012" : "\015") )  ); } # "D" for Darwin


#-- case-insensitive string search function,
#   - finds position of first occourence of a string c-i
#   - parameters identical to strpos()
if (!function_exists("stripos")) {
   function stripos($haystack, $needle, $offset=NULL) {
................................................................................
         return($length == $written);
      }
   }
}


#-- file-related constants

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); }



#-- more new constants for 5.0

if (!defined("E_STRICT")) { define("E_STRICT", 2048); }  // _STRICT is a special case of _NOTICE (_DEBUG)
# PHP_CONFIG_FILE_SCAN_DIR



#-- array count_recursive()
if (!defined("COUNT_NORMAL")) { define("COUNT_NORMAL", 0); }      // count($array, 0);
if (!defined("COUNT_RECURSIVE")) { define("COUNT_RECURSIVE", 1); }    // not supported





#-- we introduce a new function, because we cannot emulate the
#   newly introduced second parameter to count()
if (!function_exists("count_recursive")) {
   function count_recursive($array, $mode=1) {
      if (!$mode) {
................................................................................
   }
}





/**
 *                                   ------------------------------ 4.4 ---
 * @group 4_4
 * @since 4.4
 *
 * PHP 4.4 is a bugfix and backporting version created after PHP 5. It went
 * mostly unchanged, but changes a few language semantics (e.g. references).
 *
 * @emulated
 *    PHP_INT_SIZE
 *    PHP_INT_MAX
 *    SORT_LOCALE_STRING
 *
 */

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); }






/**
 *                                   ------------------------------ 4.3 ---
 * @group 4_3
 * @since 4.3
 *
 *  Additions in 4.3 version of PHP interpreter.
 *
 * @emulated
 *    file_get_contents
 *    array_key_exists
 *    array_intersect_assoc
 *    array_diff_assoc
 *    html_entity_decode
 *    str_word_count
 *    str_shuffle
 *    get_include_path
 *    set_include_path
 *    restore_include_path
 *    fnmatch
 *    FNM_PATHNAME
 *    FNM_NOESCAPE
 *    FNM_PERIOD
 *    FNM_LEADING_DIR
 *    FNM_CASEFOLD
 *    FNM_EXTMATCH
 *    glob
 *    GLOB_MARK
 *    GLOB_NOSORT
 *    GLOB_NOCHECK
 *    GLOB_NOESCAPE
 *    GLOB_BRACE
 *    GLOB_ONLYDIR
 *    GLOB_NOCASE
 *    GLOB_DOTS
 *    __FUNCTION__
 *    PATH_SEPARATOR
 *    PHP_SHLIB_SUFFIX
 *    PHP_SAPI
 *    PHP_PREFIX
 *
 * @missing
 *    sha1_file
 *    sha1 - too much code, and has been reimplemented elsewhere
 *
 * @unimplementable
 *    money_format


 *
 */


#-- simplified file read-at-once function
if (!function_exists("file_get_contents")) {
   function file_get_contents($filename, $use_include_path=1) {

      #-- open file, let fopen() report error
................................................................................



#-- shell-like filename matching (* and ? globbing characters)
if (!function_exists("fnmatch")) {

   #-- associated constants
   if (!defined("FNM_PATHNAME")) { define("FNM_PATHNAME", 1<<0); }  // no wildcard ever matches a "/"
   if (!defined("FNM_NOESCAPE")) { define("FNM_NOESCAPE", 1<<1); }  // backslash can't escape meta chars
   if (!defined("FNM_PERIOD")) { define("FNM_PERIOD",   1<<2); }  // leading dot must be given explicit
   if (!defined("FNM_LEADING_DIR")) { define("FNM_LEADING_DIR", 1<<3); }  // not in PHP
   if (!defined("FNM_CASEFOLD")) { define("FNM_CASEFOLD", 0x50); }  // match case-insensitive
   if (!defined("FNM_EXTMATCH")) { define("FNM_EXTMATCH", 1<<5); }  // not in PHP
   
   #-- implementation
   function fnmatch($pattern, $str, $flags=0x0000) {
      
      #-- 'hidden' files
      if ($flags & FNM_PERIOD) {
         if (($str[0] == ".") && ($pattern[0] != ".")) {
................................................................................
}


#-- file search and name matching (with shell patterns)
if (!function_exists("glob")) {

   #-- introduced constants
   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); }
   // unlikely to work under Win(?), without replacing the explode() with
   // a preg_split() incorporating the native DIRECTORY_SEPARATOR as well

   #-- implementation
   function glob($pattern, $flags=0x0000) {
      $ls = array();
      $rxci = ($flags & GLOB_NOCASE) ? "i" : "";
................................................................................
   function restore_include_path() {
      ini_restore("include_path");
   }
}


#-- constants for 4.3

   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); }   // empty string would signalize main()




#-- not identical to what PHP reports (it seems to `which` for itself)
if (!defined("PHP_PREFIX") && isset($_ENV["_"])) { define("PHP_PREFIX", substr($_ENV["_"], 0, strpos($_ENV["_"], "bin/"))); }








#------------------------------------------------------------------ 4.2 ---
................................................................................
}


#-- well, if you need it
if (!function_exists("array_change_key_case")) {
   
   #-- introduced constants
   if (!defined("CASE_LOWER")) { define("CASE_LOWER", 0); }
   if (!defined("CASE_UPPER")) { define("CASE_UPPER", 1); }
   
   #-- implementation
   function array_change_key_case($array, $case=CASE_LOWER) {
   
      #-- loop through
      foreach ($array as $i=>$v) {
         #-- do anything for strings only
................................................................................
}


#-- floats
if (!function_exists("is_infinite")) {

   #-- constants as-is
   if (!defined("NAN")) { define("NAN", "NAN"); }
   if (!defined("INF")) { define("INF", "INF"); }   // there is also "-INF"
   
   #-- simple checks
   function is_infinite($f) {
      $s = (string)$f;
      return(  ($s=="INF") || ($s=="-INF")  );
   }
   function is_nan($f) {
................................................................................
}


#-- HMAC from RFC2104, but see also PHP_Compat and Crypt_HMAC
if (!function_exists("mhash")) {

   #-- constants
   if (!defined("MHASH_CRC32")) { define("MHASH_CRC32", 0); }
   if (!defined("MHASH_MD5")) { define("MHASH_MD5", 1); }       // RFC1321
   if (!defined("MHASH_SHA1")) { define("MHASH_SHA1", 2); }      // RFC3174
   if (!defined("MHASH_TIGER")) { define("MHASH_TIGER", 7); }
   if (!defined("MHASH_MD4")) { define("MHASH_MD4", 16); }      // RFC1320
   if (!defined("MHASH_SHA256")) { define("MHASH_SHA256", 17); }
   if (!defined("MHASH_ADLER32")) { define("MHASH_ADLER32", 18); }
   
   #-- implementation
   function mhash($hashtype, $text, $key) {
   
      #-- hash function
      if (!($func = mhash_get_hash_name($hashtype)) || !function_exists($func)) {
         return trigger_error("mhash: cannot use hash algorithm #$hashtype/$func", E_USER_ERROR);