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

βŒˆβŒ‹ βŽ‡ branch:  upgrade.php


Check-in [51e3884900]

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

Overview
Comment:upgradephp-15
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 51e388490038df1cb5bc3ce7d0c98bb3888b4a53
User & Date: mario 2010-06-22 17:03:27
Context
2010-06-22
17:03
upgradephp-16 check-in: 02e65f8aad user: mario tags: trunk
17:03
upgradephp-15 check-in: 51e3884900 user: mario tags: trunk
17:03
upgradephp-14 check-in: 39c9fa23ab user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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

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
· fprintf
· vfprintf
· str_split
· http_build_query
· convert_uuencode
· convert_uudecode
· scandir
· idate
· time_nanosleep
· strpbrk
· php_real_logo_guid
· php_egg_logo_guid
· 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_recursive
· file_get_contents
· fnmatch
· glob
· 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
· str_rot13
· array_change_key_case
· array_fill
· array_chunk
· md5_file
· is_a
· fmod
· floatval
· is_infinite
· is_nan
· is_finite
· var_export
· strcoll
· diskfreespace
· disktotalspace
· vprintf
· vsprintf
· import_request_variables
· hypot
· log1p
· expm1
· sinh
· cosh
· tanh
· asinh
· acosh
· atanh
· mhash
· mhash_count
· mhash_get_hash_name
· mhash_get_block_size
· array_udiff_uassoc
· array_udiff_assoc
· array_diff_uassoc
· array_udiff
· array_uintersect_uassoc
· array_uintersect_assoc
· array_uintersect
· array_intersect_uassoc
· dc___exec
· bcscale
· bcadd
· bcsub
· bcmul
· bcdiv
· bcmod
· bcpow
· bcpowmod
· bcsqrt
· bccomp
· bc___scaledown
· gettext
· gettext___plural_guess
· ngettext
· dngettext
· dcngettext
· dcgettext
· dgettext
· textdomain
· bindtextdomain
· gettext___load_mo
· gettext___load_po
· bind_textdomain_codeset
· _
· mime_content_type
· image_type_to_mime_type
· image_type_to_extension
· exif_imagetype
· array_filter
· array_map
· is_callable
· array_search
· array_reduce
· is_scalar
· localeconv
· call_user_func_array
· call_user_method_array
· array_sum
· constant
· is_null
· pathinfo
· escapeshellarg
· is_uploaded_file
· move_uploaded_file
· strncasecmp
· wordwrap
· php_uname
· php_sapi_name
· posix_mkfifo
· posix_getcwd
· posix_kill
· posix_uname
· ctype_alnum
· ctype_alpha
· ctype_digit
· ctype_xdigit
· ctype_cntrl
· ctype_space
· ctype_upper
· ctype_lower
· ctype_graph
· ctype_punct
· ctype_print
· odbc_connect
· odbc_pconnect
· odbc_close
· odbc_exec
· odbc_do
· odbc_prepare
· odbc_execute
· odbc_fetch_array
· odbc_fetch_row
· 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:

· predefined STDIN, STDOUT and STDERR constants
· UPLOAD_ERR_* constants (introduced with 4.2, officially 4.3)
· ob_* (eventually possible)
· clone (PHP5 language feature, but workaround exists in PHP_Compat)
· ini_get_all (ingenious trick in PHP_Compat)

It may be possible that a script in ext/ later adds support. Often
PHP_Compat already provides loadable definitions of above features.


ext/
――――
The ext/ subdirectory in here provides a few more or less useful
emulations for various PHP extensions or function groups.

· "ext/array" provides a few exotic array diff functions (for
  associative arrays and for using multiple callback functions)

· "ext/exotic" contains some rarely needed functions, which have
  been removed from the main file for that and other reasons

· "ext/bcmath" provides the mathematical functions with arbitrary
  precision on Unix systems, but emulation also works on top of
  GMP or big_int

· "ext/dba" allows you to use scripts written for the dba module,
  if your interpreter only has dbm_*() functions; but only provides
  the minimum functionality

· "ext/ftp" emulates the ftp extension using only the bare socket
  and networking functions (should work anywhere), even has some
  features not found in the original

· "ext/gettext" simulates most of what gettext/libintl provides, and
  seems to read .mo data files correctly - plural support is however
  weak. There is also support for .po files, but since the libintl
  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"
utility:

· The "dtools/updoc" commandline script updates your local PHP
  documentation to carry hints about emulated functions. It'll simply
  add a small "EMU" on top of the supported functions` description
  pages (in the line typically listing the PHP versions).

· "ckavail.php" was used to check for added functions between
   different PHP interpreter versions, purely a development script.

· "dtools/doctests" greps your local PHP manual for function use
  examples, and executes them with the given PHP interpreter and
  the "upgrade.php" script loaded of course. This way you get live
  tests, but also see:

· "dtools/compact" creates a collapsed version of the upgrade.php
  script (saved into contrib/)



tests/
――――――
Contains stupidly short scripts, that have been used to compare
behaviour of the original functions to that of the emulated ones.

Use the "tests/_runparts" shell script (Linux) to get all tests run
automatically. You must specify the names of two different PHP
interpreter versions, whose output for each test will be shown side
by side. If you don't have two, then simply give the name of your
only PHP (-cgi) interpreter twice or simply use "false" or "cat" as
the second argument.



contrib/
――――――――
Holds a few library scripts, which are believed to be of higher
quality than any of the PEAR counterparts. Probably inappropriate to
place it in this tarball, but they usefully take advantage of the
upgrade.php provided gzdecode(). (PEARs HTTP and XML-RPC classes
don't even know about content-coding, btw).

· "contrib/http" can be used to contact Web form scripts, or PHP
  code utilizing "ext/phprequest" more efficiently. It especially
  supports content-coding as per RFC2616 (HTTP standard) for saving
  a lot of bandwidth and getting answers faster.

· "contrib/xmlrpc" likewise can compress output and is used to
  access XML-RPC and IETF XML+RPC Web services. It takes advantage
  of supported XML and EPI-XML-RPC extensions, but runs gracefully
  (not 100% exact XML parser) without. It was also made to provide
  downwards compatibility. Currently you shouldn't run it against
  old and not-HTTP standards-compliant servers and clients (=avoid
  compression unless you use it also as server or client at the
  other side).

· "contrib/hiddenerrors" shows a nice way to hide all disturbing
  error messages from users, but keeping them available for
  development. It is especially useful, when premature _NOTICEs or
  _WARNINGs could garbage (XML or binary) output or if this could
  prevent sending any further/required HTTP headers().

· "contrib/fix.php" fights magic_quotes and register_globals
  (though here it's often better to let users of outdated PHP setups
  run into the open knife, or die() with an error message)

· "contrib/phprequest" enables your PHP interpreter to receive HTTP
  requests with "application/vnd.php.serialized" encoding (even
  compressed) instead of the older "multipart/form-data" and the
  more simple "application/x-www-form-urlencoded" var post formats;
  this is faster and type-safe if you control both ends of the wire;
  see "contrib/README.http" for hints about the upcoming "PHP-RPC"

· "contrib/exceptions" provide a scheme for PHP4-compatible
  exception management using simple wrapper calls and agreements

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
as you wish, and you don't need to tell anyone where you got it from.
It has absolutely no impact on the rest of YOUR project; you are free
to include it as if you had written it yourself.

You could prepend the license preamble (GNU GPL, LGPL, BSD, MPL, MSFT
EULA, PHP, CDDL, Artistic, ...) of your choice if you want to.



Author
――――――
The current maintainer can be contacted under <milky*users·sf·net>

Please drop me a line, if you found something important missing, or
a really frustrating bug, and if you have feature wishes, or if you
can name one of the functions that the php developers were too lazy
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
  + incomplete ext/odbc
  + ext/exceptions for PHP4
  + extremely fast but incomplete plural form handling in gettext module
  - core script rewritten with more exhaustive comments

v11
  - shortened (whitespace- and comment-free) script was added
  - first gettext emulation version

v10
  (unreleased)

...
  (visit the BerliOS download page and diff it yourself)

v1
  - initial release (non-public)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted contrib/exceptions.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
/*
   simplistic exception handling for PHP4
   --------------------------------------
   
   As you might know, PHP5 introduced exceptions, similiar to Javas. This
   feature of course cannot be used for PHP4-compatible scripts, and it can
   in no way be emulated by a functional API emulation like "upgrade.php".

   To use an exception-like scheme in PHP4 you'd have to agree on conventions
   - lots of. And exceptions won't look object-oriented anymore and not be
   compliant with the PHP5 scheme - the names are in fact held incompatible
   to avoid conflicts in the language semantics (reserved words).
   

   interfaces
   ----------
  
    - class Exception 
    - global variable $_EXCEPTION (- should better be a list of excptn objs?)
    - _try() function
    - _throw() function
    - _catch() function


   howto
   -----
   
    - prefix a block of commands with _try();
      this will initialize exception handling (evtl. resets internal vars)
    - errors are thrown, by calling _throw() with an Exception-class derived
      object instance as parameter, and returning immediately
    - exceptions are "catched" in if() statements, the _catch() function
      with a classname as parameter returns false or the $_EXCEPTION object
    - you shouldn't use set_exception_handler(), but $_EXCEPTION="funcname";

    #-- main code      
    _try();
    {
       sub_call();
    }
    if ($e = _catch("Special_Case")) {
       echo $e->broken_file();
    }
    if ($e = _catch("Exception")) {
       echo "Something broke, I'd say.";
    }
    
    #-- error-prone
    function sub_call() {
       // ...
       _throw(new Exception("error",255)); return();
    }

    
   note
   ----
   
   Please don't send hatemails only because you feel the syntax is too
   far away from PHP5s native exception handling and counter to that in
   other languages. And the underscores in this agreement are just to
   prevent conflicts with PHP5 constructs - this is not yet another case
   of PHP-underscoritis ;)
   
   -> there has been another PHP framework which implemented exceptions
      long before PHP5 came out; I just don't know anymore which it was
      //@TODO: build a search engine similiar to Google to find that out
*/


#-- base class for exceptions
if (!class_exists("exception")) {
   class Exception
   {
      #-- attributes
      var $message = "";
      var $code = 0;
      var $file = NULL;
      var $line = NULL;
      var $backtrace = NULL;
      
      #-- constructor
      function Exception($message="", $code=0) {
      
         #-- values
         $this->message = $message;
         $this->code = $code;
         
         #-- debugging
         $this->backtrace = debug_backtrace();
         array_shift($this->backtrace);
         $this->file = @$this->backtrace[0]["file"];
         $this->line = @$this->backtrace[0]["line"];
      }
      
      #-- get_ wrappers
      function getMessage() {
         return($this->message);
      }
      function getCode() {
         return($this->code);
      }
      function getFile() {
         return($this->file);
      }
      function getLine() {
         return($this->line);
      }
      function getTrace() {
         return($this->backtrace);
      }
      function getTraceAsString() {
         return(var_export($this->backtrace, TRUE));
      }
      
      #-- output
      function __toString() {
         return($this->message);
      }
   }
}



#-- initialize exception handling for next block
function _try()
{
   global $_EXCEPTION;

   #-- clean up
   if (!is_string($_EXCEPTION) || !function_exists($_EXCEPTION)) {
      $_EXCEPTION = new Object();
   }
}


#-- use for throwing errors
function _throw($obj) {
   global $_EXCEPTION;

   #-- quick
   if (is_string($_EXCEPTION) && function_exists($_EXCEPTION)) {
      $_EXCEPTION($obj);
   }

   #-- what do we do if there's already an exception?
   if ($_EXCEPTION) {
      // ???
      trigger_error("_throw: there is already an unhandled exception on the stack", E_USER_ERROR);
   }

   #-- generate object from error message
   if (!is_object($obj)) {
      $_EXCEPTION = new Exception("$obj");
   }

   #-- pass
   $_EXCEPTION = $obj;

   return(true);
   // break 5;  (after throwing an exception, you should
   //           exit from your current function quickly)
}


#-- check if exception thrown
function &_catch($classname="Exception") {
   global $_EXCEPTION;
   static $e;

   #-- checked for a specific error type / exception class
   if (is_object($_EXCEPTION) && (($classname == "*") || is_a($_EXCEPTION, $classname))) {
      $e = &$_EXCEPTION;   //@FIX: remove reference passing, seems unnecessary
      unset($_EXCEPTION);  // this doesn't clean the global var  [but _try() does]
   }
   else {
      $e = false;
   }

   #-- give out extracted exception   
   return $e;
}


#-- functional additions
if (!function_exists("debug_backtrace")) {
   function debug_backtrace() {
      return array();
   }
}


#-- sets global state
if (!function_exists("set_exception_handler")) {
   // quick hack, should use a different func name
   function set_exception_handler($func) {
      global $_EXCEPTION;
      $_EXCEPTION = $func;
   }
}


?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































Deleted contrib/fix.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
/*
  api: PHP
  type: intercept
  title: PHP fixes
  descriptions: removes bogus magic_quotes and left over superglobals
  priority: auto
  category: library
  conflicts: strike_register_globals, strip_wonderful_slashes

   Outdated and bogus PHP settings (register_globals and magic_quotes) are
   defended by this script, so code cannot be negatively impacted. It can
   always be loaded as it doesn't cause problems or speed disadvantages on
   correctly configured servers. THE "PHP.INI" SHOULD BE FIXED PREFERABLY.
*/

 #-- strike register_globals (injected variables)
 if (ini_get("register_globals") == "1") {
    ewiki_recursive_unset($GLOBALS, $_REQUEST);
    ini_set("register_globals", 0);
 }

 #-- strip any \'s if magic_quotes (variable garbaging) is still enabled
 if (ini_get("magic_quotes_gpc") && get_magic_quotes_gpc()) {
    ewiki_recursive_stripslashes($_REQUEST);
    ewiki_recursive_stripslashes($_GET);
    ewiki_recursive_stripslashes($_POST);
    ewiki_recursive_stripslashes($_COOKIE);
    ewiki_recursive_stripslashes($_ENV);
    ewiki_recursive_stripslashes($_SERVER);
    ini_set("magic_quotes_gpc", 0);
 }

 #-- now that one is really dumb
 set_magic_quotes_runtime(0);


 #-- implementation
 function ewiki_recursive_unset(&$TO, $FROM) {
    foreach ($FROM as $var=>$value) {
       if (isset($TO[$var]) && ($TO[$var]==$FROM[$var])) {
          unset($TO[$var]);
          unset($TO[$var]);   // double unset to work around ZE-num/assoc-hashcode bug
       }
    }
 }
 function ewiki_recursive_stripslashes(&$var) {
    if (is_array($var)) {
       foreach ($var as $key=>$item) {
          ewiki_recursive_stripslashes($var[$key]);
       }
    }
    else {
       $var = stripslashes($var);
    }
 }

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































Deleted contrib/hiddenerrors.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
/*
   The error handler provided here will feed all errors and warnings
   into HTTP headers of the form "X-Error-NNNNN: ...", so they can't
   disturb page output or make XML documents invalid. This allows to
   turn on complete error_reporting() without any functionality loss
   due to premature output.
   You of course need a good Web browser that can easily display all
   response headers then for developing.
*/

set_error_handler("ewiki_http_header_errors");
ini_set("html_errors", 0);

function ewiki_http_header_errors($errno, $msg, $file, $line, $lvars) {

   static $error_types = array(
      E_PARSE => "PARSE ERROR",
      E_ERROR => "ERROR",
      E_WARNING => "WARNING",
      E_NOTICE => "NOTICE",
      E_STRICT => "STRICT",
      E_USER_ERROR => "USER ERROR",
      E_USER_WARNING => "USER WARNING",
      E_USER_NOTICE => "USER NOTICE",
   );
   ($errtype = $error_types[$errno]) or ($errtype = "UNDEF ERROR");
   
   #-- check for @ and disabled errors
   $emask = get_cfg_var("error_reporting");
   if (! ($emask & $errno)) {
      return;
   }

   #-- output
   $msg = strtr($msg, "\r\n\t\f", "    ");
   $msg = "$errtype: $msg in $file, line #$line";
   if (headers_sent()) {
      print "\n<!--<div class=\"php-error\">$msg</div>-->\n";
   }
   else {
      $no = crc32($msg);
      $no = ($no & 0xFFFF) ^ ($no >> 16);
      header("X-Error-$no: $msg");
      if ($errno == E_FATAL) { header("Status: 500 Something bad happened"); }
   }
}

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Deleted contrib/http.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
<?php
/*
  api: PHP
  type: functions
  category: library
  priority: optional
  provides: http-request
  title: HTTP requests
  description: implements HTTP protocol, various request methods supported
  url: http://freshmeat.net/p/upgradephp
  version: 11.3

   This snippet implements HTTP queries, and allows for most request
   methods, content types and encodings. It is useful for contacting
   scripts made to serve HTML forms.
    - does neither depend upon wget or curl, nor any other extension
    - you can add ->$params (form variables) on the fly, it's a hash
    - if the initial URL contains a query string, the vars will be
      extracted first
    - set the ->$enc very carefully, because many CGI apps and HTTP
      servers can't deal with it (else "gzip" and "deflate" are nice)
    - there are abbreviations for the content ->$type values (namely
      "form" , "url" and "php")
    - user:password@ pairs may be included in the initially given URL
    - headers always get normalized to "Studly-Caps"
    - won't support keep-alive connections
    - for PUT and other methods, the ->$params var may just hold the
      request body
    - files can be added to the ->params array as hash with specially
      named fields: "content"/"data", and "filename"/"name" , "type"
    - you can add authentication information using the standard notation
      "http://user:passw@www.example.com/..." for ->$url and ->$proxy

   A response object will have a ->$content field, ->$headers[] and
   ->len, ->type attributes as well. You could also ->decode() the
   body, if it is app/vnd.php.serialized or app/x-www-form-urlencoded.
   
   Public Domain (use freely, transform into any other license, like
   LGPL, BSD, MPL, ...; but if you change this into GPL please be so
   kind and leave your users a hint where to find the free version).
*/


#-- request objects
class http_request {

   var $method = "GET";
   var $proto = "HTTP/1.1";
   var $url = "";
   var $params = array();   // URL/form post vars, or single request body str
   var $headers = array();
   var $cookies = array();
   var $type = "url";       // content-type, abbrv. for x-www-form-...
   var $enc = false;        // "gzip" or "deflate"
   var $error="", $io_err=0, $io_err_s="";
   var $active_client = 1;  // enables redirect-following
   var $redirects = 3;
   var $proxy = false;      // set to "http://host:NN/"
   var $timeout = 15;


   #-- constructor
   function http_request($method="GET", $url="", $params=NULL) {
      $this->headers["User-Agent"] = "http_query/17.2 {$GLOBALS[ewiki_config][ua]}";
      $this->headers["Accept"] = "text/html, application/xml;q=0.9, text/xml;q=0.7, xml/*;q=0.6, text/plain;q=0.5, text/*;q=0.1, image/png;q=0.8, image/*;q=0.4, */*+xml;q=0.3; application/x-msword;q=0.001, */*;q=0.075";
      $this->headers["Accept-Language"] = "en, eo, es;q=0.2, fr;q=0.1, nl;q=0.1, de;q=0.1";
      $this->headers["Accept-Charset"] = "iso-8859-1, utf-8";
      $this->headers["Accept-Feature"] = "textonly, tables, !tcpa, !javascript, !activex, !graphic";
      $this->headers["Accept-Encoding"] = "deflate, gzip, compress, x-gzip, x-bzip2";
      //$this->headers["Referer"] = '$google';
      $this->headers["TE"] = "identity, chunked, binary, base64";
      $this->headers["Connection"] = "close";
      //$this->headers["Content-Type"] = & $this->type;
      if (isset($params)) {
         $this->params = $params;
      }
      if (strpos($method, "://")) {
         $url = $method;  # glue for incompat PEAR::Http_Request
         $method = "GET";
      }
      $this->method($method);
      $this->setURL($url);
   }


   #-- sets request method
   function method($str = "GET") {
      $this->method = $str;
   }

   #-- special headers
   function setcookie($str="name=value", $add="") {
      $this->cookies[strtok($str,"=")] = strtok("\000").$add;
   }


   #-- deciphers URL into server+path and query string
   function setURL($url) {
      if ($this->method == "GET") {
         $this->url = strtok($url, "?");
         if ($uu = strtok("\000")) {
            $this->setQueryString($uu);
         }
      }
      else {
         $this->url = $url;
      }
   }
   
   
   #-- decodes a query strings vars into the $params hash
   function setQueryString($qs) {
      $qs = ltrim($qs, "?");
      parse_str($qs, $this->params);
   }


   #-- returns params as querystring for GET requests
   function getQueryString() {
      $qs = "";
      if (function_exists("http_build_query")) {
         $qs = http_build_query($this->params);
      }
      else {
         foreach ($this->params as $n=>$v) {
            $qs .= "&" . urlencode($n) . "=" . urlencode($v);
         }
         $qs = substr($qs, 1);
      }
      return($qs);
   }


   #-- transforms $params into request body
   function pack(&$path) {
      $m = strtoupper($this->method);

      #-- GET, HEAD
      if (($m == "GET") || ($m == "HEAD")) {
         $BODY = "";
         $path .= (strpos($path, "?") ? "&" : "?") . $this->getQueryString();
      }

      #-- POST
      elseif (($m == "POST") && is_array($this->params)) {

         #-- known encoding types
         $type = $this->type($this->type, 0);
         if ($type == "url") {
            $BODY = $this->getQueryString($prep="");
         }
         elseif ($type == "php") {
            $BODY = serialize($this->params);
         }
         elseif ($type == "form") {
            // boundary doesn't need checking, unique enough
            $bnd = "snip-".dechex(time())."-".md5(serialize($this->params))
                 . "-".dechex(rand())."-snap";
            $BODY = "";
            foreach ($this->params as $i=>$v) {
               $ct = "text/plain";
               $inj = "";
               if (is_array($v)) {
                  ($ct = $v["ct"].$v["type"].$v["content-type"]) || ($ct = "application/octet-stream");
                  $inj = ' filename="' . urlencode($v["name"].$v["file"].$v["filename"]) . '"';
                  $v = $v["data"].$v["content"].$v["body"];
               }
               $BODY .= "--$bnd\015\012"
                     . "Content-Disposition: form-data; name=\"".urlencode($i)."\"$inj\015\012"
                     . "Content-Type: $ct\015\012"
                     . "Content-Length: " . strlen($v) . "\015\012"
                     . "\015\012$v\015\012";
            }
            $BODY .= "--$bnd--\015\012";
            $ct = $this->type("form") . "; boundary=$bnd";
         }
         #-- ignore
         else {
            $this->error = "unsupported POST encoding";
          // return(false);
            $BODY = & $this->params;
         }

         $this->headers["Content-Type"] = isset($ct) ? $ct : $this->type($type, 1);
      }

      #-- PUT, POST, PUSH, P*
      elseif ($m[0] == "P") {
         $BODY = & $this->$params;
      }

      #-- ERROR (but don't complain)
      else {
         $this->error = "unsupported request method '{$this->method}'";
       //  return(false);
         $BODY = & $this->params;
      }

      return($BODY);
   }


   #-- converts content-type strings from/to shortened nick
   function type($str, $long=1) {
      $trans = array(
         "form" => "multipart/form-data",
         "url" => "application/x-www-form-urlencoded",
         "php" => "application/vnd.php.serialized",
      );
      $trans["multi"] = &$trans["form"];
      if ($long) {
         $new = $trans[$str];
      }
      else {
         $new = array_search($str, $trans);
      }
      return( $new ? $new : $str );
   }


   #-- initiate the configured HTTP request ------------------------------
   function go($force=0, $asis=0) {

      #-- prepare parts
      $url = $this->prepare_url();
      if (!$url && !$force) { return; }
      $BODY = $this->body($url);
      if (($BODY===false) && !$force) { return; }
      $HEAD = $this->head($url);

      #-- open socket
      if (!$this->connect($url)) {
         return;
      }

      #-- send request data
      fwrite($this->socket, $HEAD);
      fwrite($this->socket, $BODY);
      $HEAD = false;
      $BODY = false;

      #-- read response, end connection
      while (!feof($this->socket) && (strlen($DATA) <= 1<<22)) {
         $DATA .= fread($this->socket, 32<<10);
#echo "fread(".strlen($DATA).") ";
      }
      fclose($this->socket);
      unset($this->socket);

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

      #-- decode response
      $r = new http_response();
      $r->from($DATA);        // should auto-unset $DATA

      #-- handle redirects
      if ($this->active_client) {
         $this->auto_actions($r);
      }

      #-- fin      
      return($r);
   }

   #-- alias
   function start($a=0, $b=0) { 
      return $this->go($a, $b);
   }
   
   
   #-- creates socket connection
   function connect(&$url) {
      if ((isset($this->socket) and !feof($this->socket))
      or ($this->socket = fsockopen($url["host"], $url["port"], $this->io_err, $this->io_err_s, $this->timeout))) {
         socket_set_blocking($this->socket, true);
         socket_set_timeout($this->socket, $this->timeout, 555);
         return(true);
      }
      else {
         $this->error = "no socket/connection";
         return(false);
      }
   }


   #-- separate URL into pieces, prepare special headers
   function prepare_url() {
      $this->setURL($this->url);
      if (!$this->proxy) {
         $url = parse_url($this->url);
         if (strtolower($url["scheme"]) != "http") {
            $this->error = "unsupported protocol/scheme";
            return(false);
         }
         if (!$url["host"]) { return; }
         if (!$url["port"]) { $url["port"] = 80; }
         if (!$url["path"]) { $url["path"] = "/"; }
         if ($url["query"]) { $url["path"] .= "?" . $url["query"]; }
         $proxy = "";
      }
      else {
         $url = parse_url($this->proxy);
         $url["path"] = $this->url;
         $proxy = "Proxy-";
         $this->headers["Proxy-Connection"] = $this->headers["Connection"];
      }

      #-- inj auth headers
      if ($url["user"] || $url["pass"]) {
         $this->headers[$proxy."Authorization"] = "Basic " . base64_encode("$url[user]:$url[pass]");
      }
      
      return($url);
   }


   #-- generates request body (if any), must be called before ->head()
   function body(&$url) {

      #-- encoding of variable $params as request body (according to reqmethod)
      $BODY = $this->pack($url["path"]);
      if ($BODY === false) {
         return false;
      }
      elseif ($len = strlen($BODY)) {
         $this->headers["Content-Length"] = $len;
      }
      $enc_funcs = array("gzip"=>"gzencode", "deflate"=>"gzinflate", "bzip2"=>"bzcompress", "x-bzip2"=>"bzcompress", "compress"=>"gzcompress");
      if ((strlen($BODY) >= 1024) && ($f = $enc_funcs[$this->enc]) && function_exists($f)) {
         $BODY = $f($BODY);
         $this->headers["Content-Encoding"] = $this->enc;
         $this->headers["Content-Length"] = strlen($BODY);
      }
      return($BODY);
   }


   #-- generates request head part
   function head(&$url) {
   
      #-- inject cookie header (if any)
      if ($this->cookies) {
         $c = "";
         foreach ($this->cookies as $i=>$v) {
            $c .= "; " . urlencode($i) . "=" . urlencode($v);
         }
         $this->headers["Cookie"] = substr($c, 2);
         $this->headers["Cookie2"] = '$Version="1"';
      }
      
      #-- request head
      $CRLF = "\015\012";
      $HEAD  = "{$this->method} {$url[path]} {$this->proto}$CRLF";
      $HEAD .= "Host: {$url[host]}$CRLF";
      foreach ($this->headers as $h=>$v) {
         $HEAD .= trim($h) . ": " . strtr(trim($v), "\n", " ") . $CRLF;
      }
      $HEAD .= $CRLF;
      return($HEAD);
   }

   #-- perform some things automatically (redirects)
   function auto_actions(&$r) {

      #-- behaviour table
      static $bhv = array(
         "failure" => "204,300,304,305,306",
         "clean_::POST" => "300,301,302,303,307",
         "clean_::PUT" => "300,301,302,303,307",
         "clean_::GET" => "300",  // $params:=undef
         "GET_::POST" => "303",
         "GET_::PUT" => "303",    // downgrade $method:=GET
      );
   
      #-- failure
      if (strstr($this->behaviour_table["failure"], $r->status)) {
         return;
      }

      #-- HTTP redirects
      if (($pri_url=$r->headers["Location"]) || ($pri_url=$r->headers["Uri"])) {

         if ((($this->redirects--) >= 0) && ($r->status >= 300) && ($r->status < 400)) {
            $m = strtoupper($this->method);
            if (strstr($this->behaviour_table["clean_::$m"], $r->status)) {
               unset($this->params);
            }
            if (strstr($this->behaviour_table["GET_::$m"], $r->status)) {
               $this->method("GET");
            }
            $this->setURL($pri_url);
            $this->go();
         }
      }
   }
   
   #-- aliases for compatiblity to PEAR::HTTP_Request
   function sendRequest() {
      return $this->go();
   }
   function setBasicAuth($user, $pw) {
      $this->url = preg_replace("#//(.+?@)?#", "//$user@$pw", $this->url);
   }
   function setMethod($m) {
      $this->method($m);
   }
   function setProxy($host, $port=8080, $user="", $pw="") {
      $auth = ($pw ? "$user:$pw@" : ($user ? "$user@" : ""));
      $this->proxy = "http://$auth$server:$port";
   }
   function addHeader($h, $v) {
      $this->headers[$h] = $v;
   }
   function getResponseStatus() {
      $this->headers[$h] = $v;
   }
}
class http_query extends http_request {
   /* this is just an alias */
}




#-- every query result will be encoded in such an object --------------------
class http_response {

   var $status = 520;
   var $status_str = "";
   var $headers_str = "";
   var $headers = array();
   var $len = 0;
   var $type = "message/x-raw";
   var $content = "";
   
   
   function http_response() {
   }
   

   #-- fill object from given HTTP response BLOB   
   function from(&$SRC) {
      $this->breakHeaders($SRC);  // split data into body + headers
      $SRC = false;
      $this->decodeHeaders();     // normalize header names
      $this->headerMeta();
      $this->decodeTransferEncodings();    // chunked
      $this->decodeContentEncodings();     // gzip, deflate
      $this->len = strlen($this->content);
   }


   #-- separates headers block from response body part
   function breakHeaders(&$DATA) {
      $l = strpos($DATA, "\012\015\012"); $skip = 3;
      $r = strpos($DATA, "\012\012");
      if ($r && ($r<$l)) { $l = $r; $skip = 2; }
      if (!$l) { $l = strlen($DATA); }
      $this->headers_str = rtrim(substr($DATA, 0, $l), "\015");
      $this->content = substr($DATA, $l + $skip);
      $this->body = & $this->content;
      $this->data = & $this->content;  // aliases
      $this->ct = & $this->type;
   }


   #-- splits up the $headers_str into an array and normalizes header names
   function decodeHeaders() {

      #-- normalize linebreaks
      $str = & $this->headers_str;
//      $str = str_replace("\n ", " ", $str);
      $str = str_replace("\r", "", $str);
      
      #-- strip headline
      $nl = strpos($str, "\n") + 1;
      $this->proto = strtok(substr($str, 0, $nl), " ");
      $this->status = (int) strtok(" ");
      $this->status_str = strtok("\000\r\n");
      if ($this->status == 100) {
         $this->full_duplex = 1;
      }

      #-- go through lines, split name:value pairs
      foreach (explode("\n", substr($str, $nl)) as $line) {

         $i = trim(strtok($line, ":"));
         $v = trim(strtok("\000"));

         #-- normalize name look&feel
         $i = strtr(ucwords(strtolower(strtr($i, "-", " "))), " ", "-");

         #-- add to, if key exists
         if (!empty($this->headers[$i])) {
            $this->headers[$i] .= ", ".$v;
         }
         else {
            $this->headers[$i] = $v;
         }

      }
   }


   #-- extract interesting values
   function headerMeta() {
      $this->len = strlen($this->content);
      $this->type = trim(strtok(strtolower($this->headers["Content-Type"]), ";"));
   }
   

   #-- strip any content transformation
   function decodeTransferEncodings() {
      $enc = trim(strtok(strtolower($this->headers["Transfer-Encoding"]), ",;"));
      if ($enc) {
         switch ($enc) {
#echo "ENC($enc) ";
            case "chunked":
               $this->decodeChunkedEncoding();
               break;
            case "base64":
               $this->content = base64_decode($this->content);
               $this->len = strlen($this->content);
               break;
            case "identity": case "binary":
            case "7bit": case "8bit":
               break;
            default:
               trigger_error("http_response::decodeTransferEncodings: unkown TE of '$enc'\n", E_WARNING);
         }
      }
   }


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

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


   #-- uncompress response body
   function decodeContentEncodings() {
      $enc = trim(strtok(strtolower($this->headers["Content-Encoding"]), ";,"));
      $dat = &$this->content;
      if ($enc == "deflate") {
         $dat = gzinflate($dat);
      }
      elseif (($enc == "gzip") || ($enc == "x-gzip")) {
         if (function_exists("gzdecode")) {
            $dat = gzdecode($dat);
         }
         else {
            $dat = gzinflate(substr($dat, 10, strlen($dat)-18));
         }
      }
      elseif ($enc == "compress") {
         $dat = gzuncompress($dat);
      }
      elseif (($enc == "x-bzip2") || ($enc == "bzip2")) {
         if (function_exists("bzdecompress")) {
            $dat = bzdecompress($dat);
         }
         else trigger_error("http_response::decodeContentEncoding: bzip2 decoding isn't supported with this PHP interpreter version", E_WARNING);
      }
      $this->len = strlen($this->content);
   }


   #-- can handle special content-types (multipart, serialized, form-data)
   function decode() {
      $t = http_request::type($this->type, 0);
      if ($t == "php") {
         return(unserialize($this->content));
      }
      elseif ($t == "url") {
         parse_str($this->content, $r);
         return($r);
      }
      elseif ($t == "form") {
         // oh, not yet exactly
      }
   }

   #-- aliases for compatiblity to PEAR::HTTP_Request
   function getResponseBody() {
      return $this->content;
   }
   function getResponseStatus() {
      return $this->status;
   }
   function getResponseCode() {
      return $this->status;
   }
   function getResponseHeader($i=NULL) {
      if (!isset($i)) {
         return $this->headers;
      }
      $i = strtolower($i);
      foreach ($this->headers as $h=>$v) {
         if (strtolower($h)==$i) {
            return $v;
         }
      }
   }
}



?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted contrib/http.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

Note: This class and file will be renamed into "xhttp..." in the near
feature, to prevent clashes with the old PEAR class.

http.php
――――――――
This script provides the easy to use "http_request" class ("http_query"
is an alias). You can contact forms or simply retrieve files with it.
Unlike fopen_wrappers, you get the response headers alongside and the
received file will be decompressed on-the-fly (it should also be faster
due to more supported compression methods).

There are some options, you can set before starting the request. Most
important aspect is, that you can add form ->params[] one after the
other for GET and POST requests. You can also use a proxy or include
authentication passwords in the initially given url, and of course
inject or override a few ->headers[] when it makes sense.



usage
―――――
It is really easy, you only must take care to always give the method
parameter before the URL ("GET" or "POST" in most cases), look at
the following:

  <?example

      #-- prepare
      $query = new http_request("GET", "http://example.com/form.php");
      $query->params["q"] = "search-this-...";

      #-- do request
      $result = $query->go();

      #-- use result
      if ($result && ($result->status == 200)) {
         echo $result->content;
      }
  ?>

Note, that we could have included the "q" parameter simply appended to
the URL in such simple cases ("http://example.com/form.php?q=search-...").

You can also do "POST" requests (normal for forms), but that you than
must decide about the encoding format. There are two for POST requests,
the default is always urlencoding (like with GET requests) with
  <?example 
      $query->type = "url";    // corresponds to "app/x-www-form-urlencoded"
  ?>
but many bigger forms however require the MIME type for form-data:
  <?example 
      $query->type = "form";    // translates to "multipart/form-data"
  ?>
You see, there are easy to remember abbreviations for this.

The form variables you want to transport are simply appended to the URL
for GETs or "url"-coded requests, but you could use the $query->params[]
array also here.

If you do a "POST" request, you do likewise; or you could also just assign
the $query->params a string blob to transfer as content (if the remote app
can deal with it or expects that, or you already have encoded eveything
into a valid form request).
If you just want to add upload-files to a "POST" request, then do this as
follows:
  <?example
      $query->params["fileformname"] = array(
         "filename" => "original-name.zip",
         "type" => "application/octet-stream",
         "content" => "$READ_FROM_FILE_DATA...",
      );
  // or
      $query->params["2nd_file"] = array(
         "ct" => "x.ml/my-format",
         "name" => "../../where/is/it/from.txt",
         "data" => file_get_contents(".../from.txt"),
      );
  ?>
"body" is a third alias for the "content" field here. If you don't set
the "type" or "ct" flag it will get "application/octet-stream" per default
(this is a good default). You could simply load the "ext/mime" script to
have the best possible MIME type here.



     start an request
     ――――――――――――――――
     Use the ->go() method to start a prepared HTTP request. The only
     alias existing today is ->start(); simply derive or edit this class
     to add your preferred name for this likewise (->do() cannot be used
     as it is a PHP reserved word, sorry ;)

     There are two options to ->go(), the first $force will override a few
     problems, and with the second ($asis) set to 1 or true, you won't get
     a result object, but the plain HTTP response blob (headers and response
     body as one large string variable).



     authentication
     ――――――――――――――
     If the remote site requires authentification, you would simply give
     this within the URL:
      <?example
         $query = new http_request("GET", "http://user:passw@example.com/...");
           // or later:
         $query->setURL("http://username:pw2@server.../")
           // or even:
         $query->url = "http://name:password@localhost/form.php";
      ?>



     proxy
     ―――――
     You can also acccess a form or remote file using a proxy server easily,
     just follow this:
      <?example
         $query = new http_request("PUT", "...");
         $query->proxy = "http://servername.proxy.org:3219/";
           // ...
         $result = $query->go();
      ?>
     You could also give a password or username for your proxy server, if
     you need it (works the same as for above).




reponses
――――――――
The $result value from the above examples should normally be an object,
it will be a scalar (false) only if something went really wrong.

It will have at least a ->status field, which is typically 200 for
succeeded requests. Everything above 500 means an server error, values
above 400 a transport and request error (= we did something wrong) and
a 300 response status means a redirection was issued.

For fulfilled requests you can access the returned file/data simply as
"$result->content" or "$result->body" or even "$result->data" (two aliases
again).

You will also have a "$result->headers[]" array, which will hold all
response HTTP headers in normalized form. Typically this means:
  <?example
      echo $result->headers["Content-Type"] . "\n";
      echo $result->headers["Date"] . "\n";
      echo $result->headers["Last-Modified"] . "\n";
      echo $result->headers["Content-Length"] . "\n";
      echo $result->headers["Etag"] . "\n";    // (beware of the lcased "t" !)
      echo $result->headers["Content-Encoding"] . "\n";
      ...
      print_r($result->headers);  // much better here ;)
  ?>
[[ Elsewhere the field names would be completely lowercased or fully
uppercase, we have CamelCase here, with the hyphens still in of course. ]]

Please note, that a known "Content-Encoding" was already removed from the
received ->content. And there is also a more correct "$result->len" and a
"$result->type" shorthand.

A few response types are understand as application data, and in this case
you can call the $result->decode() function and get a PHP variable/array
from the body.



     redirects
     ―――――――――
     If you expect HTTP redirects (->status codes from 300 till 375), then
     the default settings are ok for you, many will automatically be catched
     and the form data or file request will succeed at the replied URL.

     To tack/catch these cases yourself, simply disable that behaviour with:
      <?example
         $query->active_client = 0;
      ?>



PHP-RPC
―――――――
Not yet!  But this is probably what it will look like:

  If you control both ends of the Wire, you shouldn't use the slow and
  buggy (not everything works with everything else) XML-RPC protocol for
  calling remote functions, but instead use the high speed PHP serialize
  encoding to transfer data.

  The "http_request" class can natively encode values as such. The MIME
  type "application/vnd.php.serialized" has been registered explicitely
  for this purpose (as alternative to "multipart/form-data" encoding,
  and it is type-safe as opposed to the "/x-www-form-urlencoded" format).
  Perl and JS implementations exist (probably also one for Python), so
  plattform-independence should be given.

  PHP-RPC shall inherit (not yet negotiated) some structure from the old
  XML-RPC protocol. That is, a few names are identical. If you start an
  request you would therefore do following:

<?php

    function phprpc($server, $function, $args=array()) {

       #-- init
       $query = new http_request("POST", $server);

       #-- set content
       $query->type = "php";  // here corresponds to "app/vnd.php.serialized"
       $query->params
         = array(
              "method" => $function,
              "params" => $args,
           );

       #-- start
       $result = $query->go();
       if ($result && ($result->status == 200)) {

          $r = $result->decode();
          if ($good = $r["result"]) {
             return($good);
          }
          return($r);
       }
    }
?>

  You of course need a server part to make use of this. Simply try the
  "ext/phprequest", in which case you would do the following:

<?php

   include("ext/phprequest.php")
   if (count($_POST) && ($method = $_POST["method"])
   and ($params = $_POST["params"]))
   {
      #-- call known/registered functions
      $method = strtolower($method);
      if ($method == "my.func") {
         $r = call_user_func_array("my_func", $params);
      }
      elseif ($method == "system.time") {
         $r = time();
      }
      elseif ($method == "sytem.listmethods") {
         $r = get_defined_functions();
         $r = $r["user"];
      }

      #-- if succeeded
      if ($r) { 
         header("Content-Type: application/vnd.php.serialized");
         header("Content-Encoding: deflate");
         $r = array("result" => $r);
         die(gzdeflate(serialize($r));
      }
   }

   #-- your normal script can go on here
   //...
?>

  You can inject this into anywhere as it only engages, if a PHP-RPC
  request was detected. 



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































Deleted contrib/phprequest.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
/*
   Allows http "POST" and "PUSH" requests with a Content-Type of
   "application/vnd.php.serialized". This isn't used in the wild.
*/

if (empty($_POST)
and (strtoupper($_SERVER["REQUEST_METHOD"][0]) == "P")
and (strtolower(trim(strtok($_SERVER["CONTENT_TYPE"], ";,(")))
     == "application/vnd.php.serialized"))   
{
   #-- search for bare request body
   if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
      $_POST = $GLOBALS["HTTP_RAW_POST_DATA"];
   }
   else {
      $f = fopen("php://input", "rb");
      $_POST = fread($f, 1<<22);
      fclose($f);
   }

   #-- uncompress and decode, if something found
   if ($_POST) {

      #-- strip known/supported encodings
      $enc = trim(strtok(strtolower($_SERVER["HTTP_CONTENT_ENCODING"]), ",;"));
      if ($enc == "deflate") {
         $_POST = gzinflate($_POST);
      }
      elseif ($enc == "compress") {
         $_POST = gzuncompress($_POST);
      }
      elseif ($enc == "gzip") {
         $_POST = function_exists("gzdecode") ? gzdecode($_POST) : gzinflate(substr($_POST, 10, strlen($_POST) - 18));
      }
      elseif (($enc == "x-bzip2") or ($enc == "bzip2")) {
         $_POST = function_exists("bzdecompress") ? bzdecompress($_POST) : NULL;
      }

      #-- decipher
      if ($_POST) {
         $_POST = unserialize($_POST);
      }
      #-- merge
      if ($_POST) {
         $_REQUEST = array_merge($_REQUEST, $_POST);
      }

   }
}

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































Deleted contrib/xmlrpc.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
<?php define("XMLRPC_VERSION", "0.3.10");
# api: PHP
# type: api
# provides: rpc, xml-rpc
# version: 0.3.10
# category: library
# priority: optional
# title: XML-RPC client and server
# description: serves remote procedure calls
# homepage: http://freshmeat.net/p/upgradephp
#
#  Supports XML-RPC (text/xml) and XML+RPC (application/rpc+xml) compressed,
#  and can be used as client or server interface. Works without XMLRPC and
#  XML extensions, but utilizes them for optimal speed whenever available.
#
#   XXXX   XXXX MMM     MMM LLL              RRRRRRR   PPPPPPP    CCCCCCC
#    XXXX XXXX  MMMM   MMMM LLL      +++     RRRRRRRR  PPPPPPPP  CCCCCCCCC
#     XXXXXXX   MMMMM MMMMM LLL      +++     RRR   RRR PPP   PPP CCC    CCC
#      XXXXX    MMMMMMMMMMM LLL  +++++++++++ RRR   RRR PPP   PPP CCC
#       XXX     MMM MMM MMM LLL  +++++++++++ RRRRRRRR  PPPPPPPP  CCC
#      XXXXX    MMM  M  MMM LLL      +++     RRRRRRR   PPPPPPP   CCC
#     XXXXXXX   MMM     MMM LLL      +++     RRR  RRR  PPP       CCC    CCC
#    XXXX XXXX  MMM     MMM LLLLLLL          RRR   RRR PPP       CCCCCCCCC
#   XXXX   XXXX MMM     MMM LLLLLLL          RRR   RRR PPP        CCCCCCC
#
#  This is Public Domain. (c) 2004 WhoEver wants to. [milky*erphesfurt·de]


#-- config
define("XMLRPC_PLUS", 0);        # use XML+RPC per default
define("XMLRPC_AUTO_TYPES", 0);  # detect base64+datetime strings and automatically generate the according xmlrpc object representations then
define("XMLRPC_AUTO_UTF8", 1);   # de/convert anything from and to UTF-8 automatically - if yourscripts use Latin1 natively, but the RPC server expects/sends UTF-8
define("XMLRPC_CHARSET", "utf-8");  # used in responses and requests
define("XMLRPC_AUTODISCOVERY", 0);  # "connections" automatically create methods
define("XMLRPC_FAST", 1);        # use PHPs XML-RPC extension where possible
define("XMLRPC_OO", 1);          # return XML-RPC/HTTP errors as objects
define("XMLRPC_DEBUG", 0);       # output error hints, write /tmp dumps - set this to 1, 2 or 3

#-- _server() settings
define("XMLRPC_LOG", "/tmp/xmlrpc.".@$_SERVER["SERVER_NAME"].".log");

#-- general data
#  (don't change the following, most are auto-configured values)
define("XMLRPC_UA", "xml+rpc/".XMLRPC_VERSION." (PHP/".PHP_VERSION."; ".PHP_OS.")");
define("XMLRPC_MIME_NEW", "application/rpc+xml");
define("XMLRPC_MIME_OLD", "text/xml");
define("XMLRPC_MIME", XMLRPC_MIME_OLD);
define("XMLRPC_ACCEPT", XMLRPC_MIME_NEW.", ".XMLRPC_MIME_OLD."; q=0.5");
define("XMLRPC_EPI", function_exists("xmlrpc_decode_request"));

#-- init
error_reporting(0);
if (isset($_SERVER["HTTP_CONTENT_TYPE"]) && empty($_SERVER["CONTENT_TYPE"])) {
   $_SERVER["CONTENT_TYPE"] = $_SERVER["HTTP_CONTENT_TYPE"];   // older CGI implementations
}




############################################################################
#                                                                          #
#  client part                                                             #
#                                                                          #
############################################################################


#-- Issue a request, call can take any number of arguments.
#     $result = xmlrpc("http://example.com/RPC2/", "method1", $arg1 ...);
#     $result = xmlrpc("xml+rpc://here.org/RPC3/", "ns.function", ...);
#   Results automatically have <datetime> values converted into Unix
#   timestamps and <base64> unpacked into strings.
#
function xmlrpc($server, $method=NULL /*, ... */) {
   if ($method) {
      $params = func_get_args();
      shift($params); shift($params);
      return
        xmlrpc_request($server, $method, $params);
   }
   else {
      return
        new xmlrpc_connection($server);
   }
}



#--  Generate and send request, decode response.
function xmlrpc_request($url, $method, $params=array(), $plus=XMLRPC_PLUS, $gzip=0) {
   global $xmlrpc_response_headers, $xmlrpc_error;
   
   #-- init whole lib for request (we are not-OO here)
   $xmlrpc_error = false;
   $xmlrpc_response_headers = array();
   
   #-- encapsulate req, transmit it
   $socket = xmlrpc_request_send($url, $method, $params, $plus, $gzip);
   if (!$socket) {
      return xmlrpc_error(-32768, "no connection", 0, "GLOBALVARS");
   }

   #-- wait for, read response
   $response = "";
   while (!feof($socket) && (strlen($DATA) <= 768<<10)) {
      $response .= fread($socket, 4<<10);
   }
   fclose($socket);
   if (XMLRPC_DEBUG >= 3) {
      echo "<code>$response</code>";
   }

   #-- decode answer and give results
   return xmlrpc_response_decode($response);
}


#-- an alias
function xmlrpc_call($url, $method, $params=array(), $plus=XMLRPC_PLUS, $gzip=0) {
   return xmlrpc_request($url, $method, $params, $plus, $gzip);
}



#-- marshall request parameters into array, hash, xml string
function xmlrpc_request_send($url, $method, &$params, $plus, $gzip, $blocking=true) {

   #-- get connection data
   $c = parse_url($url);
   ($host = $c["host"]);
   ($port = @$c["port"]) or ($port = 80);
   ($path = $c["path"]) or ($path = "/");
   if (strpos($c["scheme"], "+")) {
      $plus++;
   }
   if (strpos($c["scheme"], "gzip")) {
      $gzip++;
   }
   if (!$host) { return(NULL); }
   $inj = "";
   if ($str = $c["user"]) {
      if ($c["pass"]) { $str .= ":" . $c["pass"]; }
      $inj = "Authorization: Basic " . base64_encode($str) . "\n";
   }
   
   #-- mk request HTTP+XML block from params
   $request = xmlrpc_request_marshall($method, $params);
   $request = xmlrpc_request_http($request, $path, $host, $plus, $gzip, $inj);

   #-- connect, send request
   if ($socket = fsockopen($host, $port, $io_err, $io_err_s, 30)) {
      socket_set_blocking($socket, $blocking);
      socket_set_timeout($socket, 17, 555);
   }
   else {
      echo "Could not connect to '<b>$host</b>:$port$path' - error $io_err: $io_err_s.<br>\n";
      return(NULL);
   }
   fputs($socket, $request);

   #-- done here
   return($socket);
}


#-- marshall function call into XML+HTTP string
function xmlrpc_request_marshall($method, &$params) {

   #-- use xmlrpc-epi
   if (XMLRPC_FAST && XMLRPC_EPI) {
      $query = xmlrpc_encode_request($method, $params);
      return($query);
   }

   #-- build query
   $query = array(
      "methodCall" => array(
         "methodName" => array( ",0"=>$method ),
         "params" => array()
      )
   );
   foreach ($params as $i=>$p) {
      $query["methodCall"]["params"]["param,$i"] = xmlrpc_compact_value($p);
   }
   $query = array2xml($query, 1, 'encoding="'.XMLRPC_CHARSET.'" ');

   #-- encode?
   if (XMLRPC_AUTO_UTF8) {
      $query = utf8_encode($query);
   }
   
   return($query);   
}


#-- enclose body into HTTP request string
function xmlrpc_request_http(&$query, $path, $host, $plus, $gzip, $inj_header="") {

   #-- build request
   $n = "\015\012";
   $request = "POST $path HTTP/1.0$n"
            . "Host: $host$n"
            . ($inj_header ? str_replace("\n", $n, $inj_header) : "")
            . "User-Agent: " . XMLRPC_UA . "$n"
            . "Accept: ".XMLRPC_ACCEPT."$n"
            . (!XMLRPC_DEBUG ? "Accept-Encoding: deflate$n" : "")
            . "Content-Type: ".($plus ? XMLRPC_MIME_NEW : XMLRPC_MIME_OLD)
                              ."; charset=".XMLRPC_CHARSET."$n";

   #-- compress?
   if ($gzip) {
      $query = gzdeflate($query);
      $request .= "Content-Encoding: deflate$n";
   }
   $request .= "Content-Length: " . strlen($query) . "$n" . "$n";
   $request .= $query . "$n";

   return($request);
}


#-- unpack response from HTTP and XML representation
function xmlrpc_response_decode(&$response) {
   global $xmlrpc_response_headers;

   #-- split into headers and content
   $l1 = strpos($response, "\n\n");
   $l2 = strpos($response, "\n\r\n");
   if ($l2 && (!$l1 || ($l2<$l1))) {
      $head = substr($response, 0, $l2);
      $response = substr($response, $l2+3);
   }
   else {
      $head = substr($response, 0, $l1);
      $response = substr($response, $l2+2);
   }

   #-- decode headers, decompress body
   foreach (explode("\n", $head) as $line) {
      $xmlrpc_response_headers[strtolower(trim(strtok($line, ":")))] = trim(strtok("\000"));
   }
   if ($enc = trim(@$xmlrpc_response_headers["content-encoding"])) {
      if (($enc == "gzip") || ($enc == "x-gzip")) {
         $response = gzinflate(substr($response, 10, strlen($response)-18));
      }
      elseif (($enc == "compress") || ($enc == "x-compress")) {
         $response = gzuncompress($response);
      }
      elseif (($enc == "deflate") || ($enc == "x-deflate")) {
         $response = gzinflate($response);
      }
   }

   $r = xmlrpc_response_unmarshall($response);
   if (XMLRPC_DEBUG) {var_dump($r);}
   return($r);
}


#-- decode XML-RPC from string into array and extract its actual meaning
function xmlrpc_response_unmarshall(&$response) {
   global $xmlrpc_response_headers;

   #-- strip encoding
   if (XMLRPC_AUTO_UTF8) {
      xmlrpc_decode_utf8xml($response, @$xmlrpc_response_headers["content-type"].@$xmlrpc_response_headers["content-charset"]);
   }

   if (XMLRPC_DEBUG >= 4) { fwrite(fopen("/tmp/xmlrpc:resp_in_xml","w"), $response); }
   
   #-- use xmlrpc-epi
   if (XMLRPC_FAST && XMLRPC_EPI) {
      $r = xmlrpc_decode_request($response, $uu);
      xmlrpc_epi_decode_xtypes($r);
      if (is_array($r) && (count($r)==2) && isset($r["faultCode"]) && isset($r["faultString"])) {
         return xmlrpc_error($r["faultCode"], $r["faultString"], 1, "GLOBALVARS");
      }
      else {
         return($r);
      }
   }


   #-- unmarshall XML
   $response = xml2array($response);

   #-- fetch content (one returned element)
   if ($r = @$response["methodResponse,0"]["params,0"]["param,0"]["value,0"]) {
      $r = xmlrpc_decode_value($r);
      return($r);
   }
  
   #-- error cases
   #  (we should rather return an error object here)
   if (($r = @$response["methodResponse,0"]["fault,0"]["value,0"]) && ($r = xmlrpc_decode_value($r))) { 
      return xmlrpc_error($r["faultCode"], $r["faultString"], 1, "GLOBALVARS");
   }
   else {
      return xmlrpc_error(-32600, "xml+rpc: invalid response", 0, "GLBLVRS");
   }
   return(NULL);
}



#-- Establish a virtual XML+RPC or XML-RPC server connection (a pseudo
#   handshake is used to determine supported protocol / extensions).
class xmlrpc_connection {

   #-- init
   function xmlrpc_connection($url, $autodiscovery=0) {
      global $xmlrpc_response_headers;
      $this->server = $url;
      $this->plus = 0;
      $this->gzip = 0;

      #-- handshake to check supported protocol
      $funcs = $this->call("system.getVersion");
      $this->plus = (strpos($xmlrpc_response_headers["accept"], XMLRPC_MIME_NEW) !== false);
      $this->gzip = (strpos($xmlrpc_response_headers["accept_encoding"], "deflate") !== false);
      
      #-- auto-discovery, create 'method' names
      if ($funcs && (XMLRPC_AUTODISCOVERY || $autodiscovery)) {
         foreach ($funcs as $fn) {
            $short = $fn;
            if ($l = strpos($fn, ".")) {
               $short = substr($fn, $l + 1);
               if (substr($fn, 0, $l) == "system") { continue; }
            }
            $this->short = create_function("", "return xmlrpc_request('{$this->server}','$fn',func_get_args(),{$this->plus},{$this->gzip});");
         }
      }
   }
   
   #-- generical call (needs func name)
   function call($method /*, ... */) {
      $params = func_get_args();
      shift($params);
      $r = xmlrpc_request($this->serverm, $method, $params, $this->plus, $this->gzip);
      return($r);
   }
}

#-- an alias
class xmlrpc extends xmlrpc_connection {
}




############################################################################
#                                                                          #
#  server implementation                                                   #
#                                                                          #
############################################################################


#-- Check request and execute function if registered in $xmlrpc_methods[]
#   array.
function xmlrpc_server() {

   global $xmlrpc_methods;

   #-- server is active
   define("XMLRPC_SERVER", getmypid());
   if (XMLRPC_DEBUG) { error_reporting(E_ALL^E_NOTICE); }
   ob_start();

   #-- standard reply headers
   header("Accept: ".XMLRPC_MIME_NEW.", ".XMLRPC_MIME_OLD."; q=0.5");
   header("Accept-Encoding: deflate");
   header("X-Server: " . XMLRPC_UA);
   header("Connection: close");
   header("Cache-Control: private");

   #-- fixes for PHP/Apache
   if (function_exists("getallheaders")) {
      foreach (getallheaders() as $i=>$v) {
         $_SERVER[strtoupper(strtr("HTTP_$i", "-", "_"))] = $v;
      }
   }

   #-- check and get call
   $allowed = array(
      "REQUEST_METHOD" => array("POST", "PUT", "CALL"),
      "CONTENT_TYPE" => array(XMLRPC_MIME_NEW, XMLRPC_MIME_OLD),
   );
   foreach ($allowed as $WHAT=>$WHICH) {
      if (!in_array(trim(strtok($WRONG=$_SERVER[$WHAT], ";,(")), $WHICH)) {
         header("Status: 400 Go Away, Stupid!");
         if (!$WRONG) {
            $WRONG = "undefined";
         }
         die("<h2>Error</h2>Your request was bogus, <b>$WHAT</b> must be <i>"
             . implode("</i> or <i>", $WHICH) . "</i>, but yours was '<tt>$WRONG</tt>'.\n");
      }
   }
   if (!($xml_request = xmlrpc_fetch_post_chunk())) {
      header("Status: 500 How Sad");
      die("<h2>Error</h2>Could not fetch POST data.\n");
   }

   #-- decipher incoming XML request string
   $method = "";
   if (XMLRPC_FAST && XMLRPC_EPI) {
      $params = xmlrpc_decode_request($xml_request, $method);
      xmlrpc_epi_decode_xtypes($params);
   }
   else {
      $params = xmlrpc_request_unmarshall($xml_request, $method);
   }

   
   #-- add the few system.methods()
   //if (empty($xmlrpc_methods)) {
   //   $xmlrpc_methods = get_defined_functions();
   //}
   $xmlrpc_methods["system"] = "xmlrpc_system_methods";   # a class

   #-- call
   $result = xmlrpc_exec_method($method, $params);

   #-- send back result
   if (isset($result)) {
      if (isset($result)) {
         $resp["methodResponse"]["params"]["param"] = xmlrpc_compact_value($result);
      }
      else {
         $resp["methodResponse"]["params"] = array();
      }

      xmlrpc_send_response($resp);
   }
   else {
      $result = xmlrpc_error(0, "No Result");
      xmlrpc_send_response($result);
   }
}



#-- decode <methodCall> XML string into understandable chunks,
#   gives $params as return value and $method name via pass-by-ref
function xmlrpc_request_unmarshall(&$xml_request, &$method) {

   #-- mangle charset
   if (XMLRPC_AUTO_UTF8) {
      xmlrpc_decode_utf8xml($xml_request, $_SERVER["CONTENT_TYPE"].$_SERVER["HTTP_CONTENT_CHARSET"]);
   }

   #-- decode XML string into PHP arrays
   $call = xml2array($xml_request, 1);
   $xml_request = NULL;

   $call = $call["methodCall,0"];
   if (!$call) {
      xmlrpc_send_response(xmlrpc_error(-32600, "Bad Request, <methodCall> missing"));
   }
   $method = $call["methodName,0"][",0"];
   if (!$method) {
      xmlrpc_send_response(xmlrpc_error(-32600, "Bad Request, <methodName> missing"));
   } 

   $params = array();
   foreach ($call["params,1"] as $uu => $param) {
      $params[] = xmlrpc_decode_value($param["value,0"]);
   }

   return($params);
}



#-- Call the requested method (using the XML-method to PHP-function mapping
#   table and hints).
function xmlrpc_exec_method($method, $params) {

   global $xmlrpc_methods;
   if (XMLRPC_DEBUG >= 2) { error_reporting(E_ALL^E_NOTICE); }

   #-- check if allowed call
   $rf = strtr($method, ".", "_");
   $cl = strtok($method, ".");
   if (!$xmlrpc_methods[$method] && !$xmlrpc_methods[$cl]
      && !in_array($method, $xmlrpc_methods)
      && !in_array($rf, $xmlrpc_methods) && !in_array($cl, $xmlrpc_methods) )
   {
      xmlrpc_send_response(xmlrpc_error(-32601));
   }

   #-- real function call
   if ($php_func_name = $xmlrpc_methods[$method]) {
      $rf = $method = $php_func_name;
   }
   if (function_exists($rf)) {
      $result = call_user_func_array($rf, $params);
      if (XMLRPC_DEBUG >= 4) { fwrite(fopen("/tmp/xmlrpc:func_call_res","w"),serialize(array($rf,$result,$params))); }
      return($result);
   }
   #-- PHP object method calls
   else {
      $class = strtok($method, ".");
      $method = strtok("\000");
      if ($uu = $xmlrpc_methods[$class]) {
         $class = $uu;
      }
      if ($class && class_exists($class) && $method) {
         $obj = new $class;
         if (method_exists($obj, $method)) {
            $result = call_user_method_array($method, $obj, $params);  //<DEPRECATED>
            return($result);
         }
      }
   }

   #-- else error
   xmlrpc_send_response(xmlrpc_error(-32601));
}



#-- Get POST data from PHP (if it gives it to us).
function xmlrpc_fetch_post_chunk() {
   global $HTTP_RAW_POST_DATA;

   $data = false;
   if ($f = fopen("php://input", "rb")) {
      $data = fread($f, 0x0100000);
      fclose($f);
   }
   if (empty($data)) {
      ini_set("always_populate_raw_post_data", "true");  // well, maybe(!?)
      $data = $HTTP_RAW_POST_DATA;
      $HTTP_RAW_POST_DATA = "";
   }
   $enc = trim(strtolower($_SERVER["HTTP_CONTENT_ENCODING"]));
   $funcs = array("deflate"=>"gzinflate", "gzip"=>"gzdecode", "compress"=>"gzuncompress", "x-gzip"=>"gzdecode", "x-bzip2"=>"bzuncompress");
   if ($enc && ($pf = $funcs[$enc]) && function_exists($pf)) {
      $data = $pf($data);
   }
   return($data);
}


#-- converts UTF-8 documents into Latin-1 ones
function xmlrpc_decode_utf8xml(&$xml, $ct) {
   if (strpos(strtolower($ct), "utf-8") or preg_match('/<\?xml[^>]+encoding=["\']utf-8/i', $xml)) {
      $xml = utf8_decode($xml);
      $xml = preg_replace('/(<\?xml[^>]+encoding=["\'])utf-8(["\'])/i', '$1iso-8859-1$2', $xml, 1);
   }
}



#-- Creates an error object.
function xmlrpc_error($no=-32500, $str="", $type=1, $into_vars=0) {
   global $xmlrpc_error, $xmlrpc_errorcode;
   $errors = array(
           0 => "No Result",
      -32300 => "Transport error",
      -32400 => "Internal Server Error",
      -32500 => "Application error",
      -32600 => "Invalid message format / Bad request",
      -32601 => "Method does not exist",
      -32602 => "Parameter type mismatch",
      -32603 => "Internal XML-RPC error",
      -32604 => "Too many parameters",
      -32700 => "Not well-formed XML",
      -32701 => "Unsupported encoding - only ISO-8859-1 and UTF-8 capable",
      -32702 => "Invalid characters, encoding mismatch",
   );
   #-- build response xml/array
   if (!($str) && !($str = $errors[$no])) {
      $str = "Unknown Error";
   }
   if ($into_vars && !XMLRPC_OO) {
      $xmlrpc_error = $str;
      $xmlrpc_errorcode = $no;
      return(NULL);
   }
   else {
      return new xmlrpc_error($no, $str, $type);
   }
}


#-- error object
class xmlrpc_error {

   var $type = 1;   // else an HTTP error
   var $no;
   var $str;
   
   function xmlrpc_error($no, $str, $type=1) {
      $this->type = $type;
      $this->no = $no;
      $this->str = $str;
   }
   
   function send() {
      $error = xmlrpc_compact_value(array(
         "faultCode" => $no,
         "faultString" => $str,
      ));
      $resp = array(
         "methodResponse" => array(
            "fault" => $error
         )
      );
      xmlrpc_send_response($resp);
   }
}


#-- Sends a response.
function xmlrpc_send_response($r) {

   #-- error objects send itself (by calling _send_response() again ;-)
   if (is_object($r)) {
      $r->send();
   }

   #-- answer XML-RPC and XML+RPC requests
   $ct = trim(strtok(strtolower($_SERVER["CONTENT_TYPE"]), ";,("));  // from original request
   $cs = XMLRPC_CHARSET;
   header("Content-Type: $ct; charset=\"$cs\"");
   
   #-- make XML document from it
   if (is_array($r)) {
      $r = array2xml($r, 1, 'encoding="'.$cs.'" ');
   }

   #-- compress answer?
   if (!headers_sent()) {
      $enc = trim(strtolower($_SERVER["HTTP_ACCEPT_ENCODING"]));
      $funcs = array("deflate"=>"gzdeflate", "gzip"=>"gzencode", "compress"=>"gzcompress", "x-gzip"=>"gzencode", "x-bzip2"=>"bzcompress");
      if ($enc && ($pf = $funcs[$enc]) && function_exists($pf)) {
         header("Content-Encoding: $enc");
         $r = $pf($r);
      }
   }

   #-- send
   if (ob_get_level()) {
      #-- this prevents that PHP errors appear as garbage in our response
      $add .= "<!--\n" . ob_get_contents() . "\n-->";
      ob_end_clean();
   }
   header("Content-Length: " . strlen($r));
   print $r . $add;
   die;
}



#-- Provides "system.*" method namespace.
class xmlrpc_system_methods {

   function listMethods() {
      global $xmlrpc_methods;
      $r = array();
      foreach ($xmlrpc_methods as $i=>$i2) {
         $real = is_int($i) ? $i2 : $i;
         if (class_exists($real) && ($i2=$real) || class_exists($i2)) {
            foreach (get_class_methods($i2) as $add) {
               $r[] = $real.".".$add;
            }
         }
         else {
            $r[] = $real;
         }
      }
      return($r);
   }

   function time() {
      return new xmlrpc_datetime(time());
   }
}


############################################################################
#                                                                          #
#  misc functions                                                          #
#                                                                          #
############################################################################


function xmlrpc_log($message) {
}

function xmlrpc_die($error="", $str="") {
}



############################################################################
#                                                                          #
#  data representation mangling                                            #
#                                                                          #
############################################################################


#-- Makes compact-array2xml datavar from a PHP variable.
function xmlrpc_compact_value($var, $n=0) {

   #-- create compact-array2xml tree
   $root = array(
      "value,$n" => array(),
   );
   $r = &$root["value,$n"];

   #-- detect PHP values to be complex types in XML-RPC
   if (XMLRPC_AUTO_TYPES && is_string($var)) {
      if ((strlen($var) >= 64) && preg_match('/^[\w]+=*$/', $var)) {
         $var = new xmlrpc_base64($var);
      }
      elseif ((strlen($var)==17) && ($var[8]=="T") && preg_match('/^\d{8}T\d\d:\d\d:\d\d$/', $var)) {
         $var = new xmlrpc_datetime($var);
      }
   }

   #-- complex types
   if (is_object($var)) {
      $r = $var->out();
   }
   #-- arrays and hashes(structs)
   elseif (is_array($var)) {
      if (isset($var[0]) || empty($var)) {
         $r = array("array,$n" => array("data,0" => array()));
         $r = &$r["array,$n"]["data,0"];
         foreach ($var as $n=>$val) {
            $r = array_merge($r, xmlrpc_compact_value($val, $n));
         }
      }
      else {
         $r = array("struct,$n"=>array());
         $r = &$r["struct,$n"];
         $n = 0;
         foreach ($var as $i=>$val) {
            $r["member,$n"] = array_merge(array(
               "name,0" => array(",0" => "$i"),
            ), xmlrpc_compact_value($val, 1));
            $n++;
         }
      }
   }
   #-- simple types
   elseif (is_bool($var)) {
      $r = array(
         "boolean,$n" => array(",0" => ($var?1:0)),
      );
   }
   elseif (is_int($var)) {
      $r = array(
         "int,$n" => array(",0" => $var),
      );
   }
   elseif (is_float($var)) {
      $r = array(
         "double,$n" => array(",0" => $var),
      );
   }
   elseif (is_string($var)) {
      $r = array(
         "string,$n" => array(",0" => $var),
      );
   }
   return($root);
}


#-- Makes a PHP array from a compact-xml2array representation. $value must
#   always be the xml2array elements _below_ the ["value,0"] or ["data,0"]
#   or ["member,N"] entry.
function xmlrpc_decode_value($value) {
   $val = NULL;
   foreach ($value as $i=>$d) {

      #-- use single (text) content xml2array entry as actual $d var
      if (is_array($d) && isset($d[",0"])) {
         $d = $d[",0"];
      }

      #-- convert into PHP var based on type
      $type = strtok($i, ",");
      switch ($type) {

         case "array":
            $val = array();
            foreach ($d["data,0"] as $i=>$value) {
               $val[] = xmlrpc_decode_value($value);
            }
            break;

         case "struct":
            $val = array();
            foreach ($d as $uu=>$d2) {
               if (($in=$d2["name,0"][",0"]) && ($pos2=1) || ($in=$d2["name,1"][",0"]) && ($pos2=0)) {
                  $val[$in] = xmlrpc_decode_value($d2["value,$pos2"]);
               }
            }
            break;

         case "":    # handles also '<value>s</value>' instead
         case "0":   # of '<value><string>s</string></value>'
         case "string":
            $val =  is_array($d) ? "" : (string)$d;
            break;

         case "base64":
            $val = (XMLRPC_AUTO_TYPES>=2) ? base64_decode($d) : (string)$d;
            if ((XMLRPC_AUTO_UTF8 >= 2) && ($uu = utf8_decode($val))) {
               $val = $uu;
            }
            break;
            
      // case "real":  case "float":   // neither is allowed
         case "double":
            $val = (double)$d;
            break;
         case "i4":
         case "int":
            $val = (int)$d;
            break;

         case "boolean":
            $val = (boolean)$d;
            break;

         case "dateTime.iso8601":
            $val = xmlrpc_strtotime($d);
            break;

         default:
            if (defined("XMLRPC_SERVER")) {
               xmlrpc_send_response(xmlrpc_error(-32600, "Unknown data type '$type'"));
            }
            else {
               echo $xmlrpc_error = "UNKNOWN XML-RPC DATA TYPE '$type'<br>\n";
               $xmlrpc_errorcode = -32207;
            }
#           echo "<!-- UNKNOWN TYPE $type -->\n";
#           xmlrpc_log("bad data type '$type' enountered");
      }
   }
   return($val);
}


#-- More complex XML-RPC data types need object representation to
#   distinguish them from ordinary string and integer vars.
class xmlrpc_xtype {
   var $scalar = "";
   var $xmlrpc_type = "string";
   var $tag = "string";
   function xmlrpc_type($str) {
      $this->data = $str;
   }
   function out() {
      return array($this->tag.",0" => array(",0"=>$this->scalar));
   }
}
class xmlrpc_base64 extends xmlrpc_xtype {
   function xmlrpc_base64($str) {
      $this->tag = "base64";
      $this->xmlrpc_type = "base64";
      if (XMLRPC_AUTO_UTF8 >= 2) {
         $str = utf8_encode($str);
      }
      if (!preg_match("/^[=\w\s]+$/", $str)) {
         $this->encode=1;
      }
      $this->scalar = $str;
   }
   function out() {
      if (isset($this->encode)) {
         $this->scalar = chunk_split(base64_encode($this->scalar), 74, "\n");
      }
      return xmlrpc_xtype::out();
   }
}
class xmlrpc_datetime extends xmlrpc_xtype {
   function xmlrpc_datetime($t) {
      $this->tag = "dateTime.iso8601";
      $this->xmlrpc_type = "datetime";
      if (($t > 0) && ($t[8] != "T")) {
         $this->timestamp = $t;
         $t = xmlrpc_timetostr($t);
      }
      $this->scalar = $t;
   }
}

#-- Further simplify use of the above ones.
function xmlrpc_base64($string) {
   return(new xmlrpc_base64($string));
}
function xmlrpc_datetime($timestr) {
   return(new xmlrpc_datetime($timestr));
}


#-- Deciphers ISO datetime string into UNIX timestamp.
function xmlrpc_strtotime($str) {
   $tm = explode(":", substr($str, 9));
   $t = mktime($tm[0], $tm[1], $tm[2], substr($str, 4, 2), substr($str, 6, 2), substr($str, 0, 4));
   return($t);
}
function xmlrpc_timetostr($time) {
   return(gmstrftime("%Y%m%dT%T", $time));
}


#-- helping hand for the xmlrpc-epi extension of php
function xmlrpc_epi_decode_xtypes(&$r) {
   if (is_object($r) && isset($r->xmlrpc_type)) {
      if (isset($r->timestamp)) {
         $r = $r->timestamp;
      }
      else {
         $r = $r->scalar;
      }
   }
   elseif (is_array($r)) {
      foreach ($r as $i=>$v) {
         xmlrpc_epi_decode_xtypes($r[$i]);
      }
   }
}




############################################################################
#                                                                          #
#  simplified XML parser                                                   #
#                                                                          #
############################################################################


#-- Encode the two chars & and < into htmlentities (there is nothing said
#   about the possible other entities in the XML-RPC spec).
function xml_entities($str) {
   $e = array(
      "&" => "&amp;",
      "<" => "&lt;",
//      ">" => "&gt;",
   );
   return(strtr($str, $e));
}
function xml_decode_entities($str) {
   $e = array(
      "&lt;" => "<",
      "&gt;" => ">",
      "&apos;" => "'",
      "&quot;" => '"',
      "&amp;" => "&",
   );
   if (strpos($e, "&#") !== false) {
      $e = preg_replace('/&#(\d+);/e', 'chr($1)', $e);
      $e = preg_replace('/&#x([\da-fA-F]+);/e', 'chr(hexdec("$1"))', $e);
   }
   return(strtr($str, $e));
}


#-- Can split simplified XML into a PHP array structure. The now used
#   'compact' format will yield tag sub arrays with an "*,0" index and
#   just [",0"] for text nodes.
function xml2array($xml, $compact="ALWAYS") {
   $r = array();
   if (function_exists("xml_parser_create") && (strlen($xml) >= 512)) {
      $r = xml2array_php($xml);
   }
   else {
      xml2array_parse($xml, $r, $compact);
   }
   return($r);
}


#-- Recursively builds an array of the chunks fetched via strtok() from
#   the original XML input string.
function xml2array_parse(&$string, &$r, $compact=1) {
   $n = 0;
   do {
      #-- split chunks
      $l = strpos($string, "<");
      $p = strpos($string, ">", $l);
      $text = $attr=$close = $tag = false;
      if ($l === false) {
         $text = $string;
         $string = false;
      }
      else {
         $tag = strtok(substr($string, $l+1, $p-$l-1), " ");
         if ((strncmp($tag, "![CDATA[", 8)==0) && ($p = strpos($string, "]]>", $l))) {
            $text = substr($string, $l+9, $p-$l-9);
         }
         else {
            if ($l) {
               $text = xml_decode_entities(substr($string, 0, $l));
            }
            $attr = strtok("\000");
            $close = $attr && ($attr[strlen($attr)-1]=="/");
            $string = substr($string, $p+1);
         }
      }
      #-- insert text/body content into array
      if (trim($text)) {
#         if ($compact) {
             $r[",$n"] = $text;
#         }
#         else {
#            $r[] = $text;
#         }
         $n++;
      }
      #-- recurse for tags
      if ($tag && ($tag[0] >= 'A')) {    #-- don't read <? <! </ pseudo-tags
#         if ($compact) {
             $r["$tag,$n"] = array();
             $new = &$r["$tag,$n"];
#         } else {
#            $r[] = array($tag => array());
#            $new = &$r[count($r)-1][$tag];
#         }
         if (!$close) {
            xml2array_parse($string, $new, $compact);
         }
         $n++;
      }
      #-- stop if no more tags or content
      if (empty($tag) && empty($text) || empty($string)) {
         $tag = "/";
      }
   } while ($tag[0] != "/");
}


#-- Uses the XML extension of PHP to convert an XML stream into the
#   compact array representation.
function xml2array_php(&$xml, $compact=1) {

   $p = xml_parser_create(xml_which_charset($xml));
   xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, false);
   xml_parser_set_option($p, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");

   xml_parse_into_struct($p, $xml, $struct);

   $a = array();  // will hold all tag nodes
   $tree = array(&$a);  // stack of pointers to last node of any tree level
   $in = &$a;           // pointer to last created node

   foreach ($struct as $t) {
      unset($value);
      extract($t);

      $depth = count($tree) - 1;
      $in = &$tree[$depth];
      $tag .= "," . count($in);
//echo "#$depth, TAG=\"$tag\", TYP=$type, LEV=$level, VAL=$value\n";

      switch ($type[1]) {

         #--  OpEN
         case "p":
            $in[$tag] = array();
            if ($type=="open") {
               $tree[] = &$in[$tag];
            }
            if (isset($value) && trim($value)) {
               $in[$tag][",0"] = $value;
            }
            break;

         #--  CoMPLETE
         case "o":
            $in[$tag] = array();
            if (isset($value) && trim($value)) {
               $in[$tag][",0"] = $value;
            }
            break;

         #--  ClOSE
         case "l":
            array_pop($tree);
            break;

         #--  CdATA - usually just whitespace
         case "d":
            if (isset($value) && trim($value)) {
               $in[",".count($in)] = $value;
            }
            break;
         
         default:
            // case "attribute":
            // and anything else we do not want
      }
      
   }
   
   return($a);
}



function xml_which_charset(&$xml) {
   return( strpos(strtok($xml, "\n"), '-8859-1"') ? "iso-8859-1" : "utf-8" );
}



############################################################################
#                                                                          #
#  simplified XML creator                                                  #
#                                                                          #
############################################################################


#-- This is the opposite of the above xml2array, and can also work with the
#   so called $compact format.
function array2xml($r, $compact=1, $ins="") {
   $string = "<?xml version=\"1.0\" $ins?>";
   array2xml_push($string, $r, $compact);
   return($string);
}


#-- Recursively throws out the XMLified tree generated by the xml2array()
#   'parser' function.
function array2xml_push(&$string, &$r, $compact, $ind=-1) {
   $old_ind = ++$ind - 1;
   if ($old_ind < 0) { $old_ind = 0; }
   foreach ($r as $i=>$d) {
      $d = &$r[$i];
      if (is_scalar($d)) {
         $string .= xml_entities($d);
      }
      elseif (is_array($d)) {
         if ($compact) {
            $i = strtok($i, ","); 
         }
         $ls = str_repeat(" ", $ind);
         $string .= "\n$ls<$i>";
         $string .=  array2xml_push($string, $d, $compact, $ind);
         $ls = str_repeat(" ", $old_ind);
         $string .= "</$i>\n$ls";
      }
   }
}




?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted contrib/xmlrpc.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

XML-RPC is a "standard" (well, not yet exactly) for accessing remotely
provided 'Web services'. More exactly it is just a complicated encoding
standard for calling functions and procedures on a remote Web server
(and getting its calculation or data request results of course).

It is still in wide use for many interesting features like accessing
database content, searching, data conversion, and so on. It started as
a lightweight alternative to SOAP, which currently is more on the rise.
While SOAP is much more bloated, also XML-RPC is not the quickest RPC
format available, is not really standards-compliant (bogus specs over
the time), and so has probably only a limited lifetime now.
Therefore you should try to provide your services and access others`
via vanilla HTTP requests (form or url encoding), when possible; use
the "http.php" class for this.

(There is also a faster PHP-RPC standard on the rise, which provides
type-safe data transport over compressed and fast connections, without
the encoding overhead and charset issues when using XML-RPC.)



xmlrpc.php
――――――――――
The 'xmlrpc.php' script implements the XML-RPC spec., but adds a few
extensions, namely use of the (yet unregistered) "application/rpc+xml"
MIME type and compressed HTTP transportation. It uses a builtin stupid
XML parser (for the highly simplified XML-RPC message content) and thus
is totally independent of any PHP extensions. It of course takes
advantage of the XML extension where present (a lot faster), and it even
can make use of Epinions XML-RPC extension for PHP (really fast than).

It is mostly not object-oriented, but extremely easy to use for building
XML-RPC servers or calling remote procedures.


configuration
―――――――――――――
There are a few constants and variables that the 'xmlrpc.php' script
respects.

XMLRPC_PLUS
   If set to 1 enables use of the "application/rpc+xml" MIME type and
   request compression per default (for server and client). In 2004
   still not the recommended setting.

XMLRPC_AUTO_TYPES
   Allows the request encoder to automatically determine the <base64>
   and <dateTime.iso8061> types, even if you just used them as scalar PHP
   values. Otherwise you had to use 'new xmlrpc_base64("STrinG==")' and
   'new xmlrpc_datetime("20001020T00:00:00")' to prepare such values.

XMLRPC_AUTO_UTF8
   Takes care of transforming the complete RPC messages into/from UTF-8,
   what is useful if your scripts deal only with Latin1 and always expect
   this. <base64> are also de/encoded if you set this constant to 2.

XMLRPC_CHARSET
   The whole script is currently optimized to produce UTF-8 and decode
   requests from/into Latin-1 for your scripts.

XMLRPC_FAST
   Enables use of Epinions XML-RPC extension module for PHP automatically
   where available. You only want to disable this for debugging purposes.

XMLRPC_OO
   Engages error result objects, else you had to use the two global vars
   "$xmlrpc_error" and "$xmlrpc_errorstr" to detect such cases. If you
   enable it you must however compare all xmlrpc_request() result values
   against being an object (what does not happen for succeeded XML-RPC
   requests).

XMLRPC_AUTODISCOVERY
   If you create a "xmlrpc" or "xmlrpc_connection" object and this is
   enabled, you would get the object with function names of the
   automatically instantiated methods of the remotely provided service
   wrapped into one object (not yet), much like in the Python library
   for xmlrpc.

XMLRPC_LOG
   Creates a log file for incoming requests to the _server() part of xmlrpc
   (whenerver you activate it with the _server() call).


There are also a few automatically defined values, which you shouldn't
care about:

XMLRPC_MIME
   Contains the currently selected default MIME type for transport.
XMLRPC_MIME_NEW
   Contains the newer MIME type value. Do not change.
XMLRPC_MIME_OLD
   For compatibility with older XML-RPC clients and servers. Do not change.
XMLRPC_ACCEPT
   Again the MIME Types wrapped into a HTTP Accept: header for requests
   and responses.
XMLRPC_EPI
   Tells if the Epinions extension is available.


server configuration
――――――――――――――――――――
$xmlrpc_methods[]
   Every accessible method (for remote calls) must be defined here, for
   use with the xmlrpc_server(). There is a separate section on this one.


making xmlrpc() requests
――――――――――――――――――――――――
You can call a remote procedure by just using the short xmlrpc() call
syntax:

  $result = xmlrpc("http://example.com/rpc.php", "the.function", 1, 2, 3);

Where 1, 2 and 3 would be parameters to "the.function" on the remote server.
The number of parameters is not limited, and you do not need to give one at
all (if the remote procedure does not require them. The parameter values
are automatically encoded into XML-RPC representations except for <base64>
and <dateTime.iso8061> ones, for which you needed to create objects first.
The $result of course recieved in ordinary PHP representation of the remote
functions result value.


       xmlrpc_request()
       ――――――――――――――――
       Is basically the same as calling the xmlrpc() function, but that
       all parameters given to the remote function are now to be passed
       as array in the third parameter:

         $params = array(  "param1", "param2", "param3"  );
         $r = xmlrpc_request("server.com:80", "remoteMethod", $params);

       Also a fourth parameter to xmlrpc_request (boolean) says if to
       use the old XML-RPC or the faster XML+RPC interface. But beware,
       that this could fail if you connect to an older server.


       xmlrpc_connection
       ―――――――――――――――――
       You can also establish a 'connection' (this is purely virtual) to
       a remote XML-RPC server, using a xmlrpc_connection object as follows:

         $xc = new xmlrpc_connection("http://example.com/rpc.php");

       Then you could regularily call remote functions on that server:

         $result1 = $xc->call("function1");
         $result2 = $xc->call("function2", 2, $result1, 0x5F02);

       The xmlrpc_connection automatically chooses XML+RPC if available
       with the remote server.


       data types
       ――――――――――
       Unless XMLRPC_AUTO_TYPES was enabled (discouraged, because this is
       considered 'unreliable type guessing') you need to explicetely mark
       parameters passed to the xmlrpc() or xmlrpc_request() calls for
       their later XML-RPC type.

       To do so, you have the two class types 'xmlrpc_datetime' and
       'xmlrpc_base64' availabe. Use them as follows:

          $param1 = new xmlrpc_base64(  base64_encode($string1)  );
          $p2 = new xmlrpc_datetime(  time() + 60*60*24*7  );
          $r = xmlrpc("www.server.com/rpc/", "function1", $param1, $p2);

       Please note, that you needed to call base64_encode() yourself, and
       that the _datetime() can also use standard Unix timestamps as input.

       The XML-RPC <dateTime.iso8601> entites are, btw, automatically
       converted into Unix timestamps, if returned as result from xmlrpc()
       and xmlrpc_request() calls. This happens regardless of
       XMLRPC_AUTO_TYPES.

       If XMLRPC_AUTO_TYPES is set to 2, then even <base64> result values
       would be automatically converted into their plain (binary) string
       representation.


       "Bugs"
       ――――――
       pass-by-reference is not possible ;)



xmlrpc_server() use
―――――――――――――――――――
To make a set of functions available for remote calls, you would create
an interface script and make its URL public. Assuming that you had a
subdirectory "./myrpc" on your server, you would likely want to create 
the file "./myrpc/index.php" with following content:

   <?php

      $xmlrpc_methods = array(
         "myFunction",
         "mySecondOne",
      );
 
      include("xmlrpc.php");
      xmlrpc_server();
   ?>

So, by calling the xmlrpc_server() you make all registered functions
($xmlrpc_methods) available with the URL "xml+rpc://example.com/myrpc/" for
remote calls.


       $xmlrpc_methods[]
       ―――――――――――――――――
       All function names you list in this array (before calling the
       xmlrpc_server() function) will be available for remote calls. The
       function names are mapped to remote method names by having the
       _ underscore as alias the the . dot, which is commonly used. So a
       function whose name was "tools_register" was available as remotely
       callable method "tools_register" or "tools.register".

       Also with xmlrpc_server() it is possible to register member methods
       of object classes as remotely callable methods. All you needed to
       do is list your class in $xmlrpc_methods[].

       You can also give aliases, both for function names and for object
       classes:

          $xmlrpc_methods["callable.methodname"] = "here_function_name";
          $xmlrpc_methods["section"] = "here_class_name";

       The member methods of a class cannot be aliased however.


       xmlrpc_server()
       ―――――――――――――――
       Just fetches the current request, decodes it and executes the
       destination method (PHP function) if listed in the global
       $xmlrpc_methods[] variable.

       It automatically exits after sending the response or an error. So
       this is the last command in your xmlrpc wrapper script.


       xmlrpc_fetch_post_chunk()
       ―――――――――――――――――――――――――
       Begs PHP for the complete POST data stream. It only has two options
       to do so and may fail with some Webservers and earlier PHP versions.
       In either case try to set the "always_populate_raw_post_data" option
       in php.ini or from within a .htaccess file.

       To allow the server part to receive the XML-RPC message, you either
       need PHP 4.3 or later, or configure your PHP interpreter specifically
       to pass in the POSTed data stream. In you php.ini ([PHP] section) add:

         always_populate_raw_post_data = 1

       Or following in a .htaccess per-dir configuration
       file for Apache:

         php_option always_populate_raw_post_data=1


       xmlrpc_send_response()
       ――――――――――――――――――――――
       Is called from within xmlrpc_server() to send the response for the
       processed request (also sends error responses).


       xmlrpc_error()
       ――――――――――――――
       Creates a XML-RPC error result array.



---------------------------------------------------------------------------
internals
---------------------------------------------------------------------------
Unless you are interrested in an in-deep discussion of the "xmlrpc.php"
you should effectively stop reading here.


xmlrpc data representation encoders
―――――――――――――――――――――――――――――――――――
This lib uses the simple xml2array() compact format to do the initial work
of converting a XML file into an array representation. Various design
restrictions of the XML-RPC message format then impose certain structures
inside of the xml2array-compact representation, what is taken adavantage of.

For example <struct> entries have in the compact representation sub-elements
like ["member,0"], ["member,1"], ["member,2"] and so on. Each of which then
has two sub elements: ["name,0"] and ["value,1"].

The XML-RPC <array> instead had one ["data,0"] with sub-arrays of
["value,0"], ["value,1"], ["value,2"] and so on, which would be recursively
feed through:


      xmlrpc_decode_value()
      ―――――――――――――――――――――
      Makes a PHP representation of a part (one must start it with the
      content of a ["value,0"]) from a xml2array()-compact representation
      made out of a XML-RPC message.


      xmlrpc_compact_value()
      ――――――――――――――――――――――
      Converts a PHP array or scalar variable into an array suitable for
      transformation into a XML-RPC message string using the array2xml()
      function then.



generic functions
―――――――――――――――――
The xml2array() and array2xml() functions are stupid XML parsers and
probably only suitable for XML-RPC messages.


       xml2array()
       ―――――――――――
       Can decode a SimplifiedXML document into an array structure - and this
       in two formats. Internall xml+rpc uses only the so called "$compact
       format". If we had a XML document like the following:

       <xml>
         <more> <string> String </string>
         </more>
         <more> <string> String2 </string>
                <int>5</int>
         </more>
       </xml>

       It would return for the $compact=1 format, something like:

       array(
          "xml,0" => array(
             "more,0" => array(
                "string,0" = array(
                   ",0" => " String "
                )
             )
             "more,1" => array(
                "string,0" = array(
                   ",0" => " String2 "
                ),
                "int,1" = array(
                   ",0" => 5
                )
             )
          )
       );

       Where every tagname had a ","+NUMBER suffix, and text nodes would
       start with the comma. The numbers are always counted up in each
       nesting level from 0, regardless if it counted text or tag nodes.

       The not-compact format would hold another subarray to denote a deeper
       level tag node, but leave the text nodes as entries into the ordering
       array level. This was more suitable for XML like files, where you had
       mixed text and tag nodes in a level. For example:

       <html>
          string1
          <b>string2</b>
       </html>

       Would become in the not-compact format:

       array(
          0 => array(
             "html" => array(
                0 => "\n   string1\n   "
                1 => array(
                   "b" => array(
                       0 => "string2",
                   )
             )
          )
       )


       array2xml()
       ―――――――――――
       Regenerates a XML stream from an array structure like the one emitted
       by xml2array().


other functions
―――――――――――――――
If you want a different behaviour, you might want to alter one of
the following functions.


      xmlrpc_method_call()
      ――――――――――――――――――――
      Is responsible in the _server() part for invoking the requested
      function. It does so by using the $xmlrpc_methods[] array as mapping
      to the PHP functions to activate.

      If you would like to have a better mapping support, or even to add
      parameter type and number checking, then this is where you would
      want to start editing the code.


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































Added doc/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
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

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. Stop omitting certain more useful
PHP functions or retyping workarounds. Your applications remain
"PHP 4.1+ COMPATIBLE" while you in fact use PHP5.2 features.


this is useful:

- for open source distributions
- if your own providers PHP version is immemorial
- you want to test new functions, but not install a new PHP ver
- 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 ;-)


when it 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 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/defined if they are missing
- some functions are just simple stubs
- emulated functions are mostly slower than the native would be,
  of course
- not all PHP errors are exactly mimicked,
  -> upgradephp leaves this often to parent functions (e.g. fopen)
  -> and you probably test for errors on the native PHP anyhow
     (no practical need to have that in emulation mode)
- 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 LGPL license
      and contains more PHP4.0 emulation (what's not targetted anymore
      in upgrade.php).
      You could even use it in conjunction with upgrade.php

      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.4.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
· fprintf
· vfprintf
· str_split
· http_build_query
· convert_uuencode
· convert_uudecode
· scandir
· idate
· time_nanosleep
· strpbrk
· php_real_logo_guid
· php_egg_logo_guid
· 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_recursive
· file_get_contents
· fnmatch
· glob
· 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
· str_rot13
· array_change_key_case
· array_fill
· array_chunk
· md5_file
· is_a
· fmod
· floatval
· is_infinite
· is_nan
· is_finite
· var_export
· strcoll
· diskfreespace
· disktotalspace
· vprintf
· vsprintf
· import_request_variables
· hypot
· log1p
· expm1
· sinh
· cosh
· tanh
· asinh
· acosh
· atanh
· mhash
· mhash_count
· mhash_get_hash_name
· mhash_get_block_size
· array_udiff_uassoc
· array_udiff_assoc
· array_diff_uassoc
· array_udiff
· array_uintersect_uassoc
· array_uintersect_assoc
· array_uintersect
· array_intersect_uassoc
· dc___exec
· bcscale
· bcadd
· bcsub
· bcmul
· bcdiv
· bcmod
· bcpow
· bcpowmod
· bcsqrt
· bccomp
· bc___scaledown
· gettext
· gettext___plural_guess
· ngettext
· dngettext
· dcngettext
· dcgettext
· dgettext
· textdomain
· bindtextdomain
· gettext___load_mo
· gettext___load_po
· bind_textdomain_codeset
· _
· mime_content_type
· image_type_to_mime_type
· image_type_to_extension
· exif_imagetype
· array_filter
· array_map
· is_callable
· array_search
· array_reduce
· is_scalar
· localeconv
· call_user_func_array
· call_user_method_array
· array_sum
· constant
· is_null
· pathinfo
· escapeshellarg
· is_uploaded_file
· move_uploaded_file
· strncasecmp
· wordwrap
· php_uname
· php_sapi_name
· posix_mkfifo
· posix_getcwd
· posix_kill
· posix_uname
· ctype_alnum
· ctype_alpha
· ctype_digit
· ctype_xdigit
· ctype_cntrl
· ctype_space
· ctype_upper
· ctype_lower
· ctype_graph
· ctype_punct
· ctype_print
· odbc_connect
· odbc_pconnect
· odbc_close
· odbc_exec
· odbc_do
· odbc_prepare
· odbc_execute
· odbc_fetch_array
· odbc_fetch_row
· 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, if you seriously need
just one or two functions.


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

· predefined STDIN, STDOUT and STDERR constants
· UPLOAD_ERR_* constants (introduced with 4.2, officially 4.3)
· ob_* (eventually possible)
· ini_get_all (ingenious trick in PHP_Compat)

Some of these functions and other esoteric code is implemented
in the ext/ scripts:


ext/
----
The ext/ subdirectory in here provides a few more or less useful
emulations for various PHP extensions or function groups.

· "ext/array" provides a few exotic array diff functions (for
  associative arrays and for using multiple callback functions)

· "ext/exotic" contains some rarely needed functions, which have
  been removed from the main file for that and other reasons

· "ext/bcmath" provides the mathematical functions with arbitrary
  precision on Unix systems, but emulation also works on top of
  GMP or big_int

· "ext/dba" allows you to use scripts written for the dba module,
  if your interpreter only has dbm_*() functions; but only provides
  the minimum functionality

· "ext/ftp" emulates the ftp extension using only the bare socket
  and networking functions (should work anywhere), even has some
  features not found in the original

· "ext/gettext" simulates most of what gettext/libintl provides, and
  seems to read .mo data files correctly - plural support is however
  weak. There is also support for .po files, but since the libintl
  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.


doc/devtools/
-------------
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"
utility:

· The "dtools/updoc" commandline script updates your local PHP
  documentation to carry hints about emulated functions. It'll simply
  add a small "EMU" on top of the supported functions` description
  pages (in the line typically listing the PHP versions).

· "ckavail.php" was used to check for added functions between
   different PHP interpreter versions, purely a development script.

· "dtools/doctests" greps your local PHP manual for function use
  examples, and executes them with the given PHP interpreter and
  the "upgrade.php" script loaded of course. This way you get live
  tests, but also see:

· "dtools/compact" creates a collapsed version of the upgrade.php
  script (saved into contrib/)



doc/tests*
----------
Contains stupidly short scripts, that have been used to compare
behaviour of the original functions to that of the emulated ones.

The tests now can be run using PEARs RunTest class. (But not all
have been updated or proof-checked.)



ext/contrib/
------------
Holds a few library scripts, that will later be reworked to mimick
other new PHP extensions.

· "contrib/http" can be used to contact Web form scripts, or PHP
  code utilizing "ext/phprequest" more efficiently. It especially
  supports content-coding as per RFC2616 (HTTP standard) for saving
  a lot of bandwidth and getting answers faster.

· "contrib/xmlrpc" likewise can compress output and is used to
  access XML-RPC and IETF XML+RPC Web services. It takes advantage
  of supported XML and EPI-XML-RPC extensions, but runs gracefully
  (not 100% exact XML parser) without. It was also made to provide
  downwards compatibility. Currently you shouldn't run it against
  old and not-HTTP standards-compliant servers and clients (=avoid
  compression unless you use it also as server or client at the
  other side).

· "contrib/hiddenerrors" shows a nice way to hide all disturbing
  error messages from users, but keeping them available for
  development. It is especially useful, when premature _NOTICEs or
  _WARNINGs could garbage (XML or binary) output or if this could
  prevent sending any further/required HTTP headers().

· "contrib/fix.php" fights magic_quotes and register_globals
  (though here it's often better to let users of outdated PHP setups
  run into the open knife, or die() with an error message)

· "contrib/phprequest" enables your PHP interpreter to receive HTTP
  requests with "application/vnd.php.serialized" encoding (even
  compressed) instead of the older "multipart/form-data" and the
  more simple "application/x-www-form-urlencoded" var post formats;
  this is faster and type-safe if you control both ends of the wire;
  see "contrib/README.http" for hints about the upcoming "PHP-RPC"

· "contrib/exceptions" provide a scheme for PHP4-compatible
  exception management using simple wrapper calls and agreements

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
-------
Almost all in here is Public Domain. There are no restrictions on how
or where you could use it. You may redistribute it under any license
as you wish, and you don't need to tell anyone where you got it from.
It has absolutely no impact on the rest of YOUR project; you are free
to include it as if you had written it yourself.

You could prepend the license preamble (GNU GPL, LGPL, BSD, MPL, MSFT
EULA, PHP, CDDL, Artistic, ...) of your choice if you want to.

Exceptions are the doc/tests* and doc/runtest scripts. Those are under
the PHP license, taken from PEAR, PECL or PHP.

The "ext/pdo.php" class is from Andrea Giammarchi and under the PHP
License as well. Also check out http://xpdo.org/ - slightly related.


Author
------
The current maintainer can be contacted under <milky*users·sf·net>

Please drop me a line, regarding omissions, bugs, contributing a few
bytes...



ChangeLog
---------

v15
  - moved to phpDoc comment style,
    but not all emulated functions carry @param lists
  - tarball directories restructured
  - ext/filter ...
  - json_decode now decodes \uXXXX unicode references
  - include the PDO emulation classes of Andrea Giammarchi (under PHP License)

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
  + incomplete ext/odbc
  + ext/exceptions for PHP4
  + extremely fast but incomplete plural form handling in gettext module
  - core script rewritten with more exhaustive comments

v11
  - shortened (whitespace- and comment-free) script was added
  - first gettext emulation version

v10
  (unreleased)

...
  (visit the BerliOS download page and diff it yourself)

v1
  - initial release (non-public)

Added doc/devtools/_dt.

















>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
#!/bin/sh
# runs the `doctests` utility for a given (param) function,
# simply has some custom pathnames built-in
MAN=/usr/local/doc/php5-doc/
PHP=php412

DIR=$(dirname $(dirname $(realpath $0)))
$DIR/dtools/doctests $PHP $MAN $@

Added doc/devtools/_notdefined.







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

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

Added doc/devtools/ckavail.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
<?php
/*
   Run this first with an older PHP interpreter, and then with a newer
   version. This way you get a list (once) of added functions (the func
   list is stored in a temporary file).
*/
$DATA_FILE = "/tmp/ckavail.lst";

#-- load previous list
if ($f = @fopen($DATA_FILE, "rb")) {
   $oldl = unserialize(fread($f, 1<<20));
   fclose($f);
}
//echo "OLD=";print_r($oldl);

#-- current func list
$newl = get_defined_stuff();
//echo "NEW=";print_r($newl);

#-- save this one
if ($f = fopen($DATA_FILE, "wb")) {
   fwrite($f, serialize($newl));
   fclose($f);
}
else {
   echo "ERROR(could not save current list)\n";
}

#-- comparison of  current / last run
echo "old(".count($oldl["functions"])."), new(".count($newl["functions"]).")\n";
if ($oldl) {

   #-- funcs
   $new = array_diff($newl["functions"], $oldl["functions"]);
   echo "New functions added between PHP $oldl[version] and current $newl[version] interpreter:\n";
   print_r($new);

   #-- constants
   $new = array_diff(array_keys($newl["constants"]), array_keys($oldl["constants"]));
   echo "\nNewly added constants:\n";
   print_r($new);

   #-- classes
   $new = array_diff($newl["classes"], $oldl["classes"]);
   echo "\nAnd classes:\n";
   print_r($new);

}
else {
   echo "Now start this script a 2nd time with the newer interpreter version.\n";
}


function get_defined_stuff() {
   $rl = array();
   $f = get_defined_functions();
   while ($f["internal"]) {
      $f = $f["internal"];
   }
   $rl["functions"] = $f;
   $c = get_defined_constants();
   $rl["constants"] = $c;
   $c = get_declared_classes();
   $rl["classes"] = $c;
   $rl["version"] = PHP_VERSION;
   return($rl);
}


?>

Added doc/devtools/compact.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh

#
#  creates comment+whitespace free version of upgrade.php script
#

cd `dirname $0`
cd ../..

php -q -w upgrade.php | perl -pe 's/\s*([{}()\[\]=\-\/\$<>+*",;!&|])\s*|\n/$1/gmis;' > upgrade.php.shortened

ls -l upgrade.php*

Added doc/devtools/convertoldtest.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/php
<?php


$fn = $_SERVER["argv"][1];

$src = file_get_contents($fn);
$src = preg_replace("/\s+include\(.+?\);/ims", "", $src);
$src = trim($src);
file_put_contents($fn, $src);

$expect = `php -qC $fn`;
$src = "--TEST--\n$fn\n--FILE--\n$src\n--EXPECT--\n$expect";
file_put_contents("$fn.phpt", $src);


?>

Added doc/devtools/crw.













































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/php -qC
<?php
/**
 *
 * converts hash-style function comments into phpDoc-style blocks,
 * adds guessed @param list on the way
 * 
 *
 */

 

  $txt = file_get_contents("/dev/stdin");
//  $txt = addslashes($txt);
  $txt = preg_replace(
     "_^#--\s*(.+?\n(^#.+?\n)*)(.+?function\s+\w+\((.*?)\))?_imse",
     "'/**\n' . stripslashes(newcmt('$1')) . paramdesc('$4') . ' */\n' . stripslashes('$3')",
     $txt
  );
//  $txt = stripslashes($txt);
  print $txt;


function newcmt($c) {
   return preg_replace("_^[*/# ]*_ims", " * ", $c);
}

function paramdesc($f) {
   if (!$f || !$_SERVER["argv"][1]) {
     return " * \n";
   }
   $c = "";
   $retype = "mixed";
   preg_match_all("/([$]\w+)(=[^),]+)?/ims", $f, $uu);
   foreach ($uu[1] as $i=>$var) {
      $opt = stripslashes(substr($uu[2][$i],1));
      $type = vartype($var, $opt);
      $c .= " * @param  $type $var  "
          . ($opt ? "(optional) $opt" : "")
          . "\n";
      if ($i==0) { $retype = $type; }
   }
   return $c ? " *\n$c" . " * @return $retype\n" : "";
}

function vartype($name, $defval="") {
   $deftype = array(
      "/^[\"\']/" => "string",
      "/array\(/" => "array",
      "/^\d+$/" => "integer",
   );
   foreach ($deftype as $rx=>$t) if (preg_match($rx, $defval)) {
      return $t;
   }
   $typenames = array(
      "/int|num|size|count|index|time|offs|len|flags/i" => "integer",
      "/bool|option/i" => "boolean",
      "/str|needle|name|char|form|call|func/i" => "string",
      "/obj|class/i" => "object",
      "/hash|list|keys|values|search|arr/i" => "array",
      "/data|var/i" => "mixed",
      "/asc|desc/i" => "boolean",
   );
   foreach ($typenames as $rx=>$t) if (preg_match($rx, $name)) {
      return $t;
   }
   return "mixed";
}

?>

Added doc/devtools/doctests.

































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/local/bin/php -qC
<?php
/*
   Makes small test scripts, which get extracted from the PHP manual
   on the fly (but not every function has one there, suddenly).
*/

#-- config
$PAUSE = 1;   // (use 3) break between tests; you should use `|less` instead
$CLEAN = 0;   // remove test scripts after use
$MANY = 1;    // create one testing script per function


#-- help
if (count($_SERVER["argv"]) < 3) {
   echo<<<END

Usage: doctest  [php-interpreter]  [/path/to/your/php/manual/]

   Runs the examples from your locally installed PHP manual (any language
   will work, but get the latest!) with the given PHP interpreter version
   (use an older version to really test the emulated functions). You need
   lynx or w3m installed also. Use only under U*ix/Linux.

   Pipe the output through |less, |more or |most, there are built-in
   delays. Rarely example scripts may not run (they are examples only).

END;
}

#-- proceed
else {

   #-- args
   $php = $_SERVER["argv"][1];
   $php = trim(`which $php`);
   if (!$php) {
      die(__FILE__.": Given PHP interpreter not in your %PATH!\n");
   }
   $dir = $_SERVER["argv"][2];
   if (!is_dir($dir) || !file_exists("$dir/function.print.html")) {
      die(__FILE__.": PHP manual does not live under '$dir'.\n");
   }
   ($html = `which w3m`) or ($html = `which lynx`);
   if (!($html = trim($html))) {
      die(__FILE__.": lynx or w3m required.\n");
   }
   $tmp = "/tmp/upgrade.php.doctest.tmp";
   $tmpdir = $tmp;
   if ($MANY) { @unlink($tmpdir); @mkdir($tmpdir); }

   #-- load emulation script
   $emu = realpath(dirname(__FILE__) . "/../upgrade.php");
   $emu2 = dirname($emu)."/ext/array.php";
   $emu3 = dirname($emu)."/ext/mime.php";
   require($emu);

   #-- get function names
   $text = file_get_contents($emu);
   preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu);
   $funcs = $uu[1];
   #-- or use user-specified list
   if (count($_SERVER["argv"]) >= 4) {
      $funcs = array_slice($_SERVER["argv"], 3);
   }

   #-- generate list of really emulated functions
   $simulated = `echo '<?php echo serialize(get_defined_functions()); ?>' | $php -q`;
   $simulated = unserialize($simulated);
   $simulated = $simulated["internal"];

   #-- all
   foreach ($funcs as $func) {
      if (file_exists($fn = "$dir/function.".strtr($func, "_", "-").".html")) {
         echo "checking function '\033[31m$func\033[37m'... ";

         #-- only run over emulated stuff
         if (in_array($func, $simulated)) {
            echo "NOT EMULATED (with your PHP version)... ";
            // continue;
         }

         #-- grep example scripts
         $text = `$html -dump $fn`;
         preg_match_all("/<\?php(.+?)\?".">/ms", $text, $uu);

         #-- exec each
         if ($n = count($uu[1])) {

            #-- note
            echo "$n examples:\n\n";

            #-- multiple scripts to run
            foreach ($uu[1] as $i=>$scr) {

               #-- fix output-less scripts: find last assigned-to variable name
               if (!strpos($scr, "echo") && !strpos($scr, "print")) {
                  if (preg_match('/^.+(\$[_\w\d\[\"\'\]]+)\s*=/s', $scr, $uu)) {
                     $scr .= "\n\n#-- auto-added\nprint_r($uu[1]);\n";
                  }
                  else {
                     $scr .= "\n\n#-- this script gives no useful output, or does it?";
                  }
               }

               #-- fix compatibility to older PHP versions
               $scr = preg_replace('/(\s)private(\s\$)/', '$1var$2', $scr);

               #-- output sample script text from doc
               if ($i) {
                  echo "\n++++++++++++++++++++++++++++\n\n";
                  sleep($PAUSE);
               }
               echo "\033[1;30m<?php $scr\n?".">\033[0;37m\n";

               #-- create temp script, run it
               if ($MANY) {
                  $tmp = "$tmpdir/$func#$i.php";
               }
               $scr = ltrim($scr);
               file_put_contents(
                  $tmp,
                  "<?php\n\n".
                  "#-- a test script for emulated function '$func'\n".
                  "if (function_exists('$func')) { echo \"ATTENTION: the native '$func' function will engage for this test\\n\"; }\n".
                  "include('$emu');\n".
                  "include('$emu2');\n".
                  "include('$emu3');\n".
                  "error_reporting(E_ALL);\n\n".
                  "#-- example[$i] as taken from PHP manual page '$fn'\n".
                  "$scr\n".
                  "\n?".">"
               );
               echo "==>\033[32m\n";
               passthru("$php $tmp");
               echo "\033[0;37m\n\n";
            }

            #-- pause before next func/script
            sleep($PAUSE);
            echo "\n-------------------------------------------------------------------\n\n";
         }

         else {
            echo "NO EXAMPLES found in doc, skipping";
         }
         echo "\n";
      }
   }

   #-- clean up
   if ($CLEAN) {
      unlink($tmp);
   }
}

#-- even more clean
if ($MANY && CLEAN) { @rmdir($tmpdir); }

?>

Added doc/devtools/listemu.































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/local/bin/php -qC
<?php
/*
   Prints the list of emulated functions.
*/

#-- basedir
$dir = realpath(dirname(__FILE__) . "/../");

#-- grep for function definitions
$text = "";
$text .= implode("", file("$dir/upgrade.php"));
$text .= implode("", file("$dir/ext/array.php"));
$text .= implode("", file("$dir/ext/bcmath.php"));
$text .= implode("", file("$dir/ext/gettext.php"));
$text .= implode("", file("$dir/ext/mime.php"));
$text .= implode("", file("$dir/ext/old.php"));
$text .= implode("", file("$dir/ext/posix.php"));
$text .= implode("", file("$dir/ext/ctype.php"));
$text .= implode("", file("$dir/ext/odbc.php"));
if (preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu)) {
   $list = array_unique($uu[1]);
}

#-- print
echo "Following functions can be emulated currently:\n";
foreach ($list as $func) {
   echo "· $func\n";
}

?>

Added doc/devtools/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 doc/devtools/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 doc/devtools/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 doc/devtools/php-commandline/phpecho.







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

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

Added doc/gettext.txt.



















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

PHP-only gettext emulation
--------------------------

The "gettext.php" include script tries to reimplement GNU gettext in
pure PHP. It is incomplete and divergent in many ways, but seems to
work well in its goal to be a quick drop-in replacement.

You load the script, like you'd include the "upgrade.php" script, and
then have the family of gettext functions always available - if they
are compiled in into your PHP binary or not. This way you can freely
use standardized i18n features safely on any web server and with all
your applications.

There are however a few minor obstacles and differences in between
the original and the emulation which you have to take care of. Most
of the incompatibilites descend from lousily documented behaviour of
the original and from lack of extensqive testing of the emulated
versions.

 - You should use setlocale() before any bindtextdomain(), because
   this emulation does load the .mo/.po data files only once.

 - The emulation only ever loads one translation file (it never
   retrieves translation strings from different localizations,
   so it is less useful in conjunction with Accept-Language header
   settings - where multiple languages could be given).
   [Original gettext may or may not load from multiple files??]

 - To be compliant with the native implementation, you have to make
   sure, that the .mo files are built from the *.po source files.
   (The emulation tries to work on both, but it really shouldn't do
   that.)

 - Order of environment variable precedence is:
     1. LANGUAGE
     2. LC_ALL
     3. LC_MESSAGE
     4. LANG                    (multiple langs)
     5. setlocale()
     6. HTTP_ACCEPT_LANGUAGE    (incompliant with GNU gettext)

 - There is a second variant of the script, which tries to handle
   plural forms. This has multiple limitations:
     - does not employ a full Plural-Forms parser (a C expression
       which must be interpreted at runtime)
     - matches and works only with a few built-in language plural
       form syntaxes and orderings
     - and it's fully untested as of yet

 - It constructs a global $_GETTEXT[] variable which contains all
   messages and translations at runtime in-memory. That means, it
   is far more memory-hungry and less scalable than the original
   GNU libintl in C.



Added doc/runtest.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
#!/usr/bin/php -qC
<?php
#
# doesn't yet run a choosen PHP interpreter,
# and auto_prepend_file doesn't seem to work either
#


#-- Use the emulation, Luke.
$T = new PEAR_RunTest();
$T->ini_overwrites[] = "auto_prepend_file=".dirname(dirname(__FILE__))."/upgrade.php";
// $T->_php = "php412";


#-- *.phpt file list
$files = $_SERVER["argv"];
unset($files[0]);

#-- exec all
foreach ($files as $i => $fn) {
   $T->run($fn, array(), $i);
}




/**
 * PEAR_RunTest
 *
 * PHP versions 4 and 5
 *
 * LICENSE: This source file is subject to version 3.0 of the PHP license
 * that is available through the world-wide-web at the following URI:
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
 * the PHP License and are unable to obtain it through the web, please
 * send a note to license@php.net so we can mail you a copy immediately.
 *
 * @category   pear
 * @package    PEAR
 * @author     Tomas V.V.Cox <cox@idecnet.com>
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2006 The PHP Group
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
 * @version    CVS: $Id: RunTest.php,v 1.45 2007/06/19 03:10:49 cellog Exp $
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 1.3.3
 */

/**
 * for error handling
 */
require_once 'PEAR.php';
require_once 'PEAR/Config.php';

define('DETAILED', 1);
putenv("PHP_PEAR_RUNTESTS=1");

/**
 * Simplified version of PHP's test suite
 *
 * Try it with:
 *
 * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);'
 *
 *
 * @category   pear
 * @package    PEAR
 * @author     Tomas V.V.Cox <cox@idecnet.com>
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2006 The PHP Group
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
 * @version    Release: 1.6.1
 * @link       http://pear.php.net/package/PEAR
 * @since      Class available since Release 1.3.3
 */
class PEAR_RunTest
{
    var $_headers = array();
    var $_logger;
    var $_options;
    var $_php;
    var $test_count;
    var $xdebug_loaded;
    var $ini_overwrites = array(
        'output_handler=',
        'open_basedir=',
        'safe_mode=0',
        'disable_functions=',
        'output_buffering=Off',
        'display_errors=1',
        'log_errors=0',
        'html_errors=0',
        'track_errors=1',
        'report_memleaks=0',
        'report_zend_debug=0',
        'docref_root=',
        'docref_ext=.html',
        'error_prepend_string=',
        'error_append_string=',
#        'auto_prepend_file=',
        'auto_append_file=',
        'magic_quotes_runtime=0',
        'xdebug.default_enable=0',
        'allow_url_fopen=1',
    );

    /**
     * An object that supports the PEAR_Common->log() signature, or null
     * @param PEAR_Common|null
     */
    function PEAR_RunTest($logger = null, $options = array())
    {
        $this->ini_overwrites[] = 'error_reporting=' . E_ALL;
        if (is_null($logger)) {
            require_once 'PEAR/Common.php';
            $logger = new PEAR_Common;
        }
        $this->_logger  = $logger;
        $this->_options = $options;
        
        $conf = &PEAR_Config::singleton();
        $this->_php = $conf->get('php_bin');
    }

    /**
     * Taken from php-src/run-tests.php
     *
     * @param string $commandline command name
     * @param array $env
     * @param string $stdin standard input to pass to the command
     * @return unknown
     */
    function system_with_timeout($commandline, $env = null, $stdin = null)
    {
        $data = '';
        if (version_compare(phpversion(), '5.0.0', '<')) {
            $proc = proc_open($commandline, array(
                0 => array('pipe', 'r'),
                1 => array('pipe', 'w'),
                2 => array('pipe', 'w')
                ), $pipes);
        } else {
            $proc = proc_open($commandline, array(
                0 => array('pipe', 'r'),
                1 => array('pipe', 'w'),
                2 => array('pipe', 'w')
                ), $pipes, null, $env, array('suppress_errors' => true));
        }
    
        if (!$proc) {
            return false;
        }
    
        if (is_string($stdin)) {
            fwrite($pipes[0], $stdin);
        }
        fclose($pipes[0]);
    
        while (true) {
            /* hide errors from interrupted syscalls */
            $r = $pipes;
            $e = $w = null;
            $n = @stream_select($r, $w, $e, 60);
    
            if ($n === 0) {
                /* timed out */
                $data .= "\n ** ERROR: process timed out **\n";
                proc_terminate($proc);
                return array(1234567890, $data);
            } else if ($n > 0) {
                $line = fread($pipes[1], 8192);
                if (strlen($line) == 0) {
                    /* EOF */
                    break;
                }
                $data .= $line;
            }
        }
        if (function_exists('proc_get_status')) {
            $stat = proc_get_status($proc);
            if ($stat['signaled']) {
                $data .= "\nTermsig=".$stat['stopsig'];
            }
        }
        $code = proc_close($proc);
        if (function_exists('proc_get_status')) {
            $code = $stat['exitcode'];
        }
        return array($code, $data);
    }

    function settings2array($settings, $ini_settings)
    {
        foreach ($settings as $setting) {
            if (strpos($setting, '=')!== false) {
                $setting = explode('=', $setting, 2);
                $name  = trim(strtolower($setting[0]));
                $value = trim($setting[1]);
                $ini_settings[$name] = $value;
            }
        }
        return $ini_settings;
    }
    
    function settings2params($ini_settings)
    {
        $settings = '';
        foreach ($ini_settings as $name => $value) {
            $value = addslashes($value);
            $settings .= " -d \"$name=$value\"";
        }
        return $settings;
    }

    function runPHPUnit($file, $ini_settings = '')
    {
        $cmd = "$this->_php$ini_settings -f $file";
        if (isset($this->_logger)) {
            $this->_logger->log(2, 'Running command "' . $cmd . '"');
        }
    
        $savedir = getcwd(); // in case the test moves us around
        chdir(dirname($file));
        echo `$cmd`;
        chdir($savedir);
        return 'PASSED'; // we have no way of knowing this information so assume passing
    }

    //
    //  Run an individual test case.
    //

    function run($file, $ini_settings = '', $test_number)
    {
        if (empty($this->_options['cgi'])) {
            // try to see if php-cgi is in the path
            if (false !== $this->system_with_timeout('php-cgi -v')) {
                $this->_options['cgi'] = 'php-cgi';
            }
        }
        if (1 < $len = strlen($this->tests_count)) {
            $test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT);
            $test_nr = "[$test_number/$this->tests_count] ";
        } else {
            $test_nr = '';
        }

        $file = realpath($file);
        $section_text = $this->_readFile($file);
        if (PEAR::isError($section_text)) {
            return $section_text;
        }

        if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) {
            return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file");
        }

        $cwd = getcwd();
        
        $pass_options = '';
        if (!empty($this->_options['ini'])) {
            $pass_options = $this->_options['ini'];
        }

        $ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings);
        if ($section_text['INI']) {
            if (strpos($section_text['INI'], '{PWD}') !== false) {
                $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
            }
            $ini = preg_split( "/[\n\r]+/", $section_text['INI']);
            $ini_settings = $this->settings2array($ini, $ini_settings);
        }
        $ini_settings = $this->settings2params($ini_settings);
        $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file);

        $tested = trim($section_text['TEST']);
        $tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' ';

        if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) ||
              !empty($section_text['UPLOAD']) || !empty($section_text['GET']) ||
              !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
            if (empty($this->_options['cgi'])) {
                if (!isset($this->_options['quiet'])) {
                    $this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')");
                }
                if (isset($this->_options['tapoutput'])) {
                    return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info');
                }
                return 'SKIPPED';
            }
            $this->_php = $this->_options['cgi'];
        }

        $temp_dir = realpath(dirname($file));
    	$main_file_name = basename($file, 'phpt');
    	$diff_filename     = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff';
    	$log_filename      = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log';
    	$exp_filename      = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp';
    	$output_filename   = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out';
    	$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem';
    	$temp_file         = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
    	$temp_skipif       = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
    	$temp_clean        = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
    	$tmp_post          = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');

    	// unlink old test results
        $this->_cleanupOldFiles($file);

        // Check if test should be skipped.
        $res  = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings);
        if (count($res) != 2) {
            return $res;
        }
        $info = $res['info'];
        $warn = $res['warn'];

        // We've satisfied the preconditions - run the test!
        if (isset($this->_options['coverage']) && $this->xdebug_loaded) {
            $len_f = 5;
            if (substr($section_text['FILE'], 0, 5) != '<?php'
                && substr($section_text['FILE'], 0, 2) == '<?') {
                $len_f = 2;
            }

            $text = '<?php' . "\n" . 'xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);' . "\n";
            $new = substr($section_text['FILE'], $len_f, strlen($section_text['FILE']));
            $text.= substr($new, 0, strrpos($new, '?>'));
            $xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug';
            $text.= "\n" . 
                   "\n" . '$xdebug = var_export(xdebug_get_code_coverage(), true);' . 
                   "\n" . 'file_put_contents(\'' . $xdebug_file . '\', $xdebug);' . 
                   "\n" . 'xdebug_stop_code_coverage();' . "\n" . '?>';

            $this->save_text($temp_file, $text);
        } else {
            $this->save_text($temp_file, $section_text['FILE']);
        }

        $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
        $cmd = "$this->_php$ini_settings \"$temp_file\" $args 2>&1";
        if (isset($this->_logger)) {
            $this->_logger->log(2, 'Running command "' . $cmd . '"');
        }

        // Reset environment from any previous test.
        $env = $this->_resetEnv($section_text, $temp_file);

        $section_text = $this->_processUpload($section_text, $file);
        if (PEAR::isError($section_text)) {
            return $section_text;
        }

        if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
            $post = trim($section_text['POST_RAW']);
            $raw_lines = explode("\n", $post);
    
            $request = '';
            $started = false;
            foreach ($raw_lines as $i => $line) {
                if (empty($env['CONTENT_TYPE']) &&
                    preg_match('/^Content-Type:(.*)/i', $line, $res)) {
                    $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
                    continue;
                }
                if ($started) {
                    $request .= "\n";
                }
                $started = true;
                $request .= $line;
            }
    
            $env['CONTENT_LENGTH'] = strlen($request);
            $env['REQUEST_METHOD'] = 'POST';

            $this->save_text($tmp_post, $request);
            $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
        } elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
            $post = trim($section_text['POST']);
            $this->save_text($tmp_post, $post);
            $content_length = strlen($post);
    
            $env['REQUEST_METHOD'] = 'POST';
            $env['CONTENT_TYPE']   = 'application/x-www-form-urlencoded';
            $env['CONTENT_LENGTH'] = $content_length;
    
            $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
        } else {
            $env['REQUEST_METHOD'] = 'GET';
            $env['CONTENT_TYPE']   = '';
            $env['CONTENT_LENGTH'] = '';
        }

        if (OS_WINDOWS && isset($section_text['RETURNS'])) {
            ob_start();
            system($cmd, $return_value);
            $out = ob_get_contents();
            ob_end_clean();
            $section_text['RETURNS'] = (int) trim($section_text['RETURNS']);
            $returnfail = ($return_value != $section_text['RETURNS']);
        } else {
            $returnfail = false;
            $stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null;
            $out = $this->system_with_timeout($cmd, $env, $stdin);
            $return_value = $out[0];
            $out = $out[1];
        }

        $output = preg_replace('/\r\n/', "\n", trim($out));

        if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) {
            @unlink(realpath($tmp_post));
        }
        chdir($cwd); // in case the test moves us around

        $this->_testCleanup($section_text, $temp_clean);

        /* when using CGI, strip the headers from the output */
        $output = $this->_stripHeadersCGI($output);

        if (isset($section_text['EXPECTHEADERS'])) {
            $testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']);
            $missing = array_diff_assoc($testheaders, $this->_headers);
            $changed = '';
            foreach ($missing as $header => $value) {
                if (isset($this->_headers[$header])) {
                    $changed .= "-$header: $value\n+$header: ";
                    $changed .= $this->_headers[$header];
                } else {
                    $changed .= "-$header: $value\n";
                }
            }
            if ($missing) {
                // tack on failed headers to output:
                $output .= "\n====EXPECTHEADERS FAILURE====:\n$changed";
            }
        }
        // Does the output match what is expected?
        do {
            if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
                if (isset($section_text['EXPECTF'])) {
                    $wanted = trim($section_text['EXPECTF']);
                } else {
                    $wanted = trim($section_text['EXPECTREGEX']);
                }
                $wanted_re = preg_replace('/\r\n/', "\n", $wanted);
                if (isset($section_text['EXPECTF'])) {
                    $wanted_re = preg_quote($wanted_re, '/');
                    // Stick to basics
                    $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy
                    $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re);
                    $wanted_re = str_replace("%d", "[0-9]+", $wanted_re);
                    $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re);
                    $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re);
                    $wanted_re = str_replace("%c", ".", $wanted_re);
                    // %f allows two points "-.0.0" but that is the best *simple* expression
                }
    /* DEBUG YOUR REGEX HERE
            var_dump($wanted_re);
            print(str_repeat('=', 80) . "\n");
            var_dump($output);
    */
                if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) {
                    if (file_exists($temp_file)) {
                        unlink($temp_file);
                    }
                    if (array_key_exists('FAIL', $section_text)) {
                        break;
                    }
                    if (!isset($this->_options['quiet'])) {
                        $this->_logger->log(0, "PASS $test_nr$tested$info");
                    }
                    if (isset($this->_options['tapoutput'])) {
                        return array('ok', ' - ' . $tested);
                    }
                    return 'PASSED';
                }
            } else {
                if (isset($section_text['EXPECTFILE'])) {
                    $f = $temp_dir . '/' . trim($section_text['EXPECTFILE']);
                    if (!($fp = @fopen($f, 'rb'))) {
                        return PEAR::raiseError('--EXPECTFILE-- section file ' .
                            $f . ' not found');
                    }
                    fclose($fp);
                    $section_text['EXPECT'] = file_get_contents($f);
                }
                $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT']));
                // compare and leave on success
                if (!$returnfail && 0 == strcmp($output, $wanted)) {
                    if (file_exists($temp_file)) {
                        unlink($temp_file);
                    }
                    if (array_key_exists('FAIL', $section_text)) {
                        break;
                    }
                    if (!isset($this->_options['quiet'])) {
                        $this->_logger->log(0, "PASS $test_nr$tested$info");
                    }
                    if (isset($this->_options['tapoutput'])) {
                        return array('ok', ' - ' . $tested);
                    }
                    return 'PASSED';
                }
            }
        } while (false);

        if (array_key_exists('FAIL', $section_text)) {
            // we expect a particular failure
            // this is only used for testing PEAR_RunTest
            $expectf  = isset($section_text['EXPECTF']) ? $wanted_re : null;
            $faildiff = $this->generate_diff($wanted, $output, null, $expectf);
            $faildiff = preg_replace('/\r/', '', $faildiff);
            $wanted   = preg_replace('/\r/', '', trim($section_text['FAIL']));
            if ($faildiff == $wanted) {
                if (!isset($this->_options['quiet'])) {
                    $this->_logger->log(0, "PASS $test_nr$tested$info");
                }
                if (isset($this->_options['tapoutput'])) {
                    return array('ok', ' - ' . $tested);
                }
                return 'PASSED';
            }
            unset($section_text['EXPECTF']);
            $output = $faildiff;
            if (isset($section_text['RETURNS'])) {
                return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' .
                    $file);
            }
        }

        // Test failed so we need to report details.
        $txt = $warn ? 'WARN ' : 'FAIL ';
        $this->_logger->log(0, $txt . $test_nr . $tested . $info);

        // write .exp
        $res = $this->_writeLog($exp_filename, $wanted);
        if (PEAR::isError($res)) {
            return $res;
        }

        // write .out
        $res = $this->_writeLog($output_filename, $output);
        if (PEAR::isError($res)) {
            return $res;
        }

        // write .diff
        $returns = isset($section_text['RETURNS']) ?
                        array(trim($section_text['RETURNS']), $return_value) : null;
        $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null;
        $data = $this->generate_diff($wanted, $output, $returns, $expectf);
        $res  = $this->_writeLog($diff_filename, $data);
        if (PEAR::isError($res)) {
            return $res;
        }

        // write .log
        $data = "
---- EXPECTED OUTPUT
$wanted
---- ACTUAL OUTPUT
$output
---- FAILED
";

        if ($returnfail) {
            $data .= "
---- EXPECTED RETURN
$section_text[RETURNS]
---- ACTUAL RETURN
$return_value
";
        }

        $res = $this->_writeLog($log_filename, $data);
        if (PEAR::isError($res)) {
            return $res;
        }

        if (isset($this->_options['tapoutput'])) {
            $wanted = explode("\n", $wanted);
            $wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted);
            $output = explode("\n", $output);
            $output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output);
            return array($wanted . $output . 'not ok', ' - ' . $tested);
        }
        return $warn ? 'WARNED' : 'FAILED';
    }

    function generate_diff($wanted, $output, $rvalue, $wanted_re)
    {
        $w  = explode("\n", $wanted);
        $o  = explode("\n", $output);
        $wr = explode("\n", $wanted_re);
        $w1 = array_diff_assoc($w, $o);
        $o1 = array_diff_assoc($o, $w);
        $o2 = $w2 = array();
        foreach ($w1 as $idx => $val) {
            if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) ||
                  !preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) {
                $w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val;
            }
        }
        foreach ($o1 as $idx => $val) {
            if (!$wanted_re || !isset($wr[$idx]) ||
                  !preg_match('/^' . $wr[$idx] . '\\z/', $val)) {
                $o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val;
            }
        }
        $diff = array_merge($w2, $o2);
        ksort($diff);
        $extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : '';
        return implode("\r\n", $diff) . $extra;
    }

    //  Write the given text to a temporary file, and return the filename.
    function save_text($filename, $text)
    {
        if (!$fp = fopen($filename, 'w')) {
            return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)");
        }
        fwrite($fp, $text);
        fclose($fp);
    if (1 < DETAILED) echo "
FILE $filename {{{
$text
}}}
";
    }
    
    function _cleanupOldFiles($file)
    {
        $temp_dir = realpath(dirname($file));
        $mainFileName = basename($file, 'phpt');
    	$diff_filename     = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff';
    	$log_filename      = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log';
    	$exp_filename      = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp';
    	$output_filename   = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out';
    	$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem';
    	$temp_file         = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php';
    	$temp_skipif       = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php';
    	$temp_clean        = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php';
    	$tmp_post          = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');

    	// unlink old test results
    	@unlink($diff_filename);
    	@unlink($log_filename);
    	@unlink($exp_filename);
    	@unlink($output_filename);
    	@unlink($memcheck_filename);
    	@unlink($temp_file);
    	@unlink($temp_skipif);
    	@unlink($tmp_post);
    	@unlink($temp_clean);
    }
    
    function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings)
    {
        $info = '';
        $warn = false;
        if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) {
            $this->save_text($temp_skipif, $section_text['SKIPIF']);
            $output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\"");
            $output = $output[1];
            $loutput = ltrim($output);
            unlink($temp_skipif);
            if (!strncasecmp('skip', $loutput, 4)) {
                $skipreason = "SKIP $tested";
                if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
                    $skipreason .= '(reason: ' . $m[1] . ')';
                }
                if (!isset($this->_options['quiet'])) {
                    $this->_logger->log(0, $skipreason);
                }
                if (isset($this->_options['tapoutput'])) {
                    return array('ok', ' # skip ' . $reason);
                }
                return 'SKIPPED';
            }

            if (!strncasecmp('info', $loutput, 4)
                && preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
                $info = " (info: $m[1])";
            }

            if (!strncasecmp('warn', $loutput, 4)
                && preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
                $warn = true; /* only if there is a reason */
                $info = " (warn: $m[1])";
            }
        }
        
        return array('warn' => $warn, 'info' => $info);
    }
    
    function _stripHeadersCGI($output)
    {
        $this->headers = array();
        if (!empty($this->_options['cgi']) &&
              $this->_php == $this->_options['cgi'] && 
              preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) {
            $output = isset($match[2]) ? trim($match[2]) : '';
            $this->_headers = $this->_processHeaders($match[1]);
        }
        
        return $output;
    }

    /**
     * Return an array that can be used with array_diff() to compare headers
     *
     * @param string $text
     */
    function _processHeaders($text)
    {
        $headers = array();
        $rh = preg_split("/[\n\r]+/", $text);
        foreach ($rh as $line) {
            if (strpos($line, ':')!== false) {
                $line = explode(':', $line, 2);
                $headers[trim($line[0])] = trim($line[1]);
            }
        }
        return $headers;
    }

    function _readFile($file)
    {
        // Load the sections of the test file.
        $section_text = array(
            'TEST'   => '(unnamed test)',
            'SKIPIF' => '',
            'GET'    => '',
            'COOKIE' => '',
            'POST'   => '',
            'ARGS'   => '',
            'INI'    => '',
            'CLEAN'  => '',
        );

        if (!is_file($file) || !$fp = fopen($file, "r")) {
            return PEAR::raiseError("Cannot open test file: $file");
        }

        $section = '';
        while (!feof($fp)) {
            $line = fgets($fp);

            // Match the beginning of a section.
            if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
                $section = $r[1];
                $section_text[$section] = '';
                continue;
            } elseif (empty($section)) {
                fclose($fp);
                return PEAR::raiseError("Invalid sections formats in test file: $file");
            }

            // Add to the section text.
            $section_text[$section] .= $line;
        }
        fclose($fp);
        
        return $section_text;
    }
    
    function _writeLog($logname, $data)
    {
        if (!$log = fopen($logname, 'w')) {
            return PEAR::raiseError("Cannot create test log - $logname");
        }
        fwrite($log, $data);
        fclose($log);
    }

    function _resetEnv($section_text, $temp_file)
    {
        $env = $_ENV;
        $env['REDIRECT_STATUS'] = '';
        $env['QUERY_STRING']    = '';
        $env['PATH_TRANSLATED'] = '';
        $env['SCRIPT_FILENAME'] = '';
        $env['REQUEST_METHOD']  = '';
        $env['CONTENT_TYPE']    = '';
        $env['CONTENT_LENGTH']  = '';
        if (!empty($section_text['ENV'])) {
            foreach (explode("\n", trim($section_text['ENV'])) as $e) {
                $e = explode('=', trim($e), 2);
                if (!empty($e[0]) && isset($e[1])) {
                    $env[$e[0]] = $e[1];
                }
            }
        }
        if (array_key_exists('GET', $section_text)) {
            $env['QUERY_STRING'] = trim($section_text['GET']);
        } else {
            $env['QUERY_STRING'] = '';
        }
        if (array_key_exists('COOKIE', $section_text)) {
            $env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
        } else {
            $env['HTTP_COOKIE'] = '';
        }
        $env['REDIRECT_STATUS'] = '1';
        $env['PATH_TRANSLATED'] = $temp_file;
        $env['SCRIPT_FILENAME'] = $temp_file;
        
        return $env;
    }
    
    function _processUpload($section_text, $file)
    {
        if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) {
            $upload_files = trim($section_text['UPLOAD']);
            $upload_files = explode("\n", $upload_files);

            $request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" .
                       "-----------------------------20896060251896012921717172737\n";
            foreach ($upload_files as $fileinfo) {
                $fileinfo = explode('=', $fileinfo);
                if (count($fileinfo) != 2) {
                    return PEAR::raiseError("Invalid UPLOAD section in test file: $file");
                }
                if (!realpath(dirname($file) . '/' . $fileinfo[1])) {
                    return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " .
                        "in test file: $file");
                }
                $file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]);
                $fileinfo[1] = basename($fileinfo[1]);
                $request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n";
                $request .= "Content-Type: text/plain\n\n";
                $request .= $file_contents . "\n" .
                    "-----------------------------20896060251896012921717172737\n";
            }

            if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
                // encode POST raw
                $post = trim($section_text['POST']);
                $post = explode('&', $post);
                foreach ($post as $i => $post_info) {
                    $post_info = explode('=', $post_info);
                    if (count($post_info) != 2) {
                        return PEAR::raiseError("Invalid POST data in test file: $file");
                    }
                    $post_info[0] = rawurldecode($post_info[0]);
                    $post_info[1] = rawurldecode($post_info[1]);
                    $post[$i] = $post_info;
                }
                foreach ($post as $post_info) {
                    $request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n";
                    $request .= $post_info[1] . "\n" .
                        "-----------------------------20896060251896012921717172737\n";
                }
                unset($section_text['POST']);
            }
            $section_text['POST_RAW'] = $request;
        }
        
        return $section_text;
    }
    
    function _testCleanup($section_text, $temp_clean)
    {
        if ($section_text['CLEAN']) {
            // perform test cleanup
            $this->save_text($temp_clean, $section_text['CLEAN']);
            $this->system_with_timeout("$this->_php $temp_clean");
            if (file_exists($temp_clean)) {
                unlink($temp_clean);
            }
        }
    }
}

Added doc/tests1all/array_change_key_case.phpt.

















































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

$a = array("low"=>32, "CamelCase"=>"Wiki");
print_r($a);
echo "\n";
$a = array_change_key_case($a, CASE_UPPER);
print_r($a);

?>
--EXPECT--
Array
(
    [low] => 32
    [CamelCase] => Wiki
)

Array
(
    [LOW] => 32
    [CAMELCASE] => Wiki
)

Added doc/tests1all/array_chunk.phpt.

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_chunk
--FILE--
<?php

$a = array("a", "b", "c", "d", "e");
$r = array_chunk($a, 2, 1);
echo 'array_chunk($a, 2, 1) = ';
print_r($r);

?>
--EXPECT--
array_chunk($a, 2, 1) = Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [2] => c
            [3] => d
        )

    [2] => Array
        (
            [4] => e
        )

)

Added doc/tests1all/array_combine.phpt.































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_combine
--FILE--
<?php


?>
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c);
<?php
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c);
?>
--EXPECT--
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c);
Array
(
    [green] => avocado
    [red] => apple
    [yellow] => banana
)

Added doc/tests1all/array_diff_assoc.phpt.



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_diff_assoc
--FILE--
<?php


?>
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000,         15=>555);
$res = array_diff_assoc($a, $b);

print_r($res);
<?php
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000,         15=>555);
$res = array_diff_assoc($a, $b);
print_r($res);
?>
--EXPECT--
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000,         15=>555);
$res = array_diff_assoc($a, $b);

print_r($res);
Array
(
    [14] => 10000
    [ccc] => 555
)

Added doc/tests1all/array_fill.phpt.































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_fill
--FILE--
<?php

$a = 17;
$a = array_fill(1, 17, $a);
print_r($a);

?>
--EXPECT--
Array
(
    [1] => 17
    [2] => 17
    [3] => 17
    [4] => 17
    [5] => 17
    [6] => 17
    [7] => 17
    [8] => 17
    [9] => 17
    [10] => 17
    [11] => 17
    [12] => 17
    [13] => 17
    [14] => 17
    [15] => 17
    [16] => 17
    [17] => 17
)

Added doc/tests1all/array_intersect_assoc.phpt.























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_intersect_assoc
--FILE--
<?php

?>
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000, 555);
$res = array_intersect_assoc($a, $b);

print_r($res);
<?php
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000, 555);
$res = array_intersect_assoc($a, $b);
print_r($res);
?>
--EXPECT--
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000, 555);
$res = array_intersect_assoc($a, $b);

print_r($res);
Array
(
    [5] => 5
)

Added doc/tests1all/array_udiff_uassoc.phpt.

























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_udiff_uassoc
--FILE--
<?php

#-- from manual --

class cr {
    var $priv_member;
    function cr($val)
    {
        $this->priv_member = $val;
    }
}
    function comp_func_cr($a, $b)
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }
    
    function comp_func_key($a, $b)
    {
        if ($a === $b) return 0;
        return ($a > $b)? 1:-1;
    }


$a = array(
   "0.1" => new cr(9),
   "0.5" => new cr(12),
   0 => new cr(23),
   1=> new cr(4),
   2 => new cr(-15),
);
$b = array(
   "0.2" => new cr(9),
   "0.5" => new cr(22),
   0 => new cr(3),
   1=> new cr(4),
   2 => new cr(-15),
);

$result = array_udiff_uassoc($a, $b, "comp_func_cr", "comp_func_key");
$expected = array (
  '0.1' => new cr(9),
  '0.5' => new cr(12),
  0 => new cr(23),
);
print_r($result);

if ($result == $expected) {
   echo "\n--> works correctly\n";
}

?>
--EXPECT--
Array
(
    [0.1] => cr Object
        (
            [priv_member] => 9
        )

    [0.5] => cr Object
        (
            [priv_member] => 12
        )

    [0] => cr Object
        (
            [priv_member] => 23
        )

)

--> works correctly

Added doc/tests1all/array_walk_recursive.phpt.







































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
array_walk_recursive
--FILE--
<?php

$a = array(
  "x1",
  "x2\\",
  array(
     "x3aaa1",
     "x3a\\a2",
  ),
  "x4\+end",
);

echo "__start:\n";
array_walk_recursive($a, "outp");

function outp(&$a) {
   var_dump($a);
   $a = stripslashes($a);
}

echo "\n__result:\n";
var_dump($a);

?>
--EXPECT--
__start:
string(2) "x1"
string(3) "x2\"
string(6) "x3aaa1"
string(6) "x3a\a2"
string(7) "x4\+end"

__result:
array(4) {
  [0]=>
  string(2) "x1"
  [1]=>
  string(2) "x2"
  [2]=>
  &array(2) {
    [0]=>
    string(6) "x3aaa1"
    [1]=>
    string(5) "x3aa2"
  }
  [3]=>
  string(6) "x4+end"
}

Added doc/tests1all/base16.phpt.































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--TEST--
base16
--FILE--
<?php
include "../../ext/nonstandard/base64.php";

echo base16_encode("123");
echo "\n";
echo base16_decode("313233");

?>
--EXPECT--
313233

123

Added doc/tests1all/bcmath.phpt.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--TEST--
bcmath
--FILE--
<?php

bcscale(50);
echo "1/17=";
echo bcdiv("1", "17");
echo "\n";

echo "2^55%77777=";
echo bcpowmod(2, 55, 77777);
echo "\n";

?>
--EXPECT--
1/17=0.05882352941176470588235294117647058823529411764705
2^55%77777=0.00000000000000000000000000000000000000000000000000

Added doc/tests1all/class_parents.phpt.













































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

class a {}
class x extends a {}
class y extends x {}
class z extends a {}
class eve extends y {}

$y = new y;
$r = class_parents($y);
print_r($r);

?>
--EXPECT--
Array
(
    [x] => x
    [a] => a
)

Added doc/tests1all/file_put_contents.phpt.









































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

$FN = "/tmp/test_fpc";

echo 'file_put_contents("/tmp/test_fpc", "abc-test-text");'."\n";
file_put_contents($FN, "abc-test-text");

echo 'echo file_get_contents("/tmp/test_fpc");'."\n => ";
echo file_get_contents($FN);

unlink($FN);

?>
--EXPECT--
file_put_contents("/tmp/test_fpc", "abc-test-text");
echo file_get_contents("/tmp/test_fpc");
 => abc-test-text

Added doc/tests1all/floatval.phpt.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
--TEST--
floatval
--FILE--
floatval("1234.567abc") = <?php

$str = "1234.567abc";
echo floatval($str);

?>
--EXPECT--
floatval("1234.567abc") = 1234.567

Added doc/tests1all/fmod.phpt.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
--TEST--
fmod
--FILE--
<?php

$r = fmod(5.7, 1.3);
echo "fmod(5.7, 1.3) = $r\n";

?>
--EXPECT--
fmod(5.7, 1.3) = 0.5

Added doc/tests1all/fnmatch.phpt.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
fnmatch
--FILE--
<?php

$text = "Some text goes here...";
echo '$text = "Some text goes here...";';
echo "\nfnmatch('go*', $text) = ". (fnmatch('go*', $text) ?1:0);
echo "\nfnmatch('*go', $text) = ". (fnmatch('*go', $text) ?1:0);
echo "\nfnmatch('*go*', $text) = ". (fnmatch('*go*', $text) ?1:0);
echo "\nfnmatch('*te?x*', $text) = ". (fnmatch('*te?x*', $text) ?1:0);
echo "\nfnmatch('*te?t*', $text) = ". (fnmatch('*te?t*', $text) ?1:0);
echo "\nfnmatch('So?m*', $text) = ". (fnmatch('So?m*', $text) ?1:0);
echo "\nfnmatch('So*m*', $text) = ". (fnmatch('*So*m*', $text) ?1:0);

?>
--EXPECT--
$text = "Some text goes here...";
fnmatch('go*', Some text goes here...) = 0
fnmatch('*go', Some text goes here...) = 0
fnmatch('*go*', Some text goes here...) = 1
fnmatch('*te?x*', Some text goes here...) = 0
fnmatch('*te?t*', Some text goes here...) = 1
fnmatch('So?m*', Some text goes here...) = 0
fnmatch('So*m*', Some text goes here...) = 1

Added doc/tests1all/get_headers.phpt.













































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

$r = get_headers("http://localhost/");
print_r($r);

?>
--EXPECT--
Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Date: Mon, 30 Jul 2007 04:38:37 GMT
    [2] => Server: aEGiS_nanoweb/2.2.8 (Linux; PHP/5.2.1)
    [3] => Content-Type: text/html
    [4] => Last-Modified: Fri, 01 Sep 2006 16:22:06 GMT
    [5] => ETag: "19e700:6r0x:44f85e2e:99d"
    [6] => Accept-Ranges: bytes
    [7] => Connection: close
    [8] => Content-Length: 2461
)

Added doc/tests1all/gettext.phpt.











































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

#-- load
echo "bindtextdomain(\"tar\");\n";
bindtextdomain("tar");
textdomain("tar");

#-- query
echo "_(\"stdin\") == \"";
echo _("stdin");
echo "\"\n";

?>
--EXPECT--
bindtextdomain("tar");

Warning: Wrong parameter count for bindtextdomain() in /home/mario/www/berli/upgradephp/doc/tests1all/gettext on line 5
_("stdin") == "stdin"

Added doc/tests1all/glob.phpt.































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

echo 'glob("../tests/*m*") = ';
$r = glob("../tests/*m*");
print_r($r);


?>
--EXPECT--
glob("../tests/*m*") = Array
(
)

Added doc/tests1all/gzdecode.phpt.













































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

$orig =
"ORIGINAL_TEXT.................................................................................................................................................................................................................................End";
$gz = gzencode($orig);
echo "strlen(\$orig) == ".strlen($orig)."\n";
echo "strlen(\$gz) == ".strlen($gz)."\n...\n";

$text = gzdecode($gz);
echo "gzdecode(\$gz) = \"$text\"\n\n";


?>
--EXPECT--
strlen($orig) == 241
strlen($gz) == 39
...
gzdecode($gz) = "ORIGINAL_TEXT.................................................................................................................................................................................................................................End"

Added doc/tests1all/headers_list.phpt.















































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

header("Content-Type: text/x-display-on-console");
header("X-Server: upgradephp-test/2.75.01d");
echo "header(\"...\");\n\n";

echo "\$r = headers_list();\n\n";
error_reporting(E_ALL);
$r = headers_list();
print_r($r);

?>
--EXPECT--
header("...");

$r = headers_list();

Array
(
)

Added doc/tests1all/html_entity_decode.phpt.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
--TEST--
html_entity_decode
--FILE--
<?php

echo 'html_entity_decode("&lt;&amp;&gt;&auml;&szlig;") = ';
echo html_entity_decode("&lt;&amp;&gt;&auml;&szlig;");

?>
--EXPECT--
html_entity_decode("&lt;&amp;&gt;&auml;&szlig;") = <&>δί

Added doc/tests1all/http_build_query.phpt.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--TEST--
http_build_query
--FILE--
<?php


?>
$data = array('foo', 'bar', "sub"=>array('b', 'c'), 'cow' => 'milk', 'php' =>'hypertext processor');
echo http_build_query($data, "num_");

<?php
$data = array('foo', 'bar', "sub"=>array('b', 'c'), 'cow' => 'milk', 'php' =>'hypertext processor');
echo http_build_query($data, "num_");
?>
--EXPECT--
$data = array('foo', 'bar', "sub"=>array('b', 'c'), 'cow' => 'milk', 'php' =>'hypertext processor');
echo http_build_query($data, "num_");

num_0=foo&num_1=bar&sub%5B0%5D=b&sub%5B1%5D=c&cow=milk&php=hypertext+processor

Added doc/tests1all/is_a.phpt.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
--TEST--
is_a
--FILE--
<?php

class y {}
class x extends y {}
$x = new x;

echo is_a($x, "x") ? "works" : "failed";
echo "\n";
echo is_a($x, "y") ? "works" : "failed";

?>
--EXPECT--
works
works

Added doc/tests1all/json.phpt.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
json
--FILE--
<?php

$a = array(
  "x" => "y",
  "text" => "Hallφchen
",
  "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";

?>
--EXPECT--
{"x":"y","text":"Hall","abc":true,"int":512,"float":3.14159,"null":null,"sub":[1,2,3],"sub2":{"0":1,"1":2,"a":3}}

Added doc/tests1all/json2.phpt.





































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
json2
--FILE--
<?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);

?>
--EXPECT--
stdClass Object
(
    [menu] => stdClass Object
        (
            [header] => SVG Viewer
            [items] => Array
                (
                    [0] => stdClass Object
                        (
                            [id] => Open
                        )

                    [1] => stdClass Object
                        (
                            [id] => OpenNew
                            [label] => Open New
                        )

                    [2] => 
                    [3] => stdClass Object
                        (
                            [id] => ZoomIn
                            [label] => Zoom In
                        )

                    [4] => stdClass Object
                        (
                            [id] => ZoomOut
                            [label] => Zoom Out
                        )

                    [5] => stdClass Object
                        (
                            [id] => OriginalView
                            [label] => Original View
                        )

                    [6] => 
                    [7] => stdClass Object
                        (
                            [id] => Quality
                        )

                    [8] => stdClass Object
                        (
                            [id] => Pause
                        )

                    [9] => stdClass Object
                        (
                            [id] => Mute
                        )

                    [10] => 
                    [11] => stdClass Object
                        (
                            [id] => Find
                            [label] => Find...
                        )

                    [12] => stdClass Object
                        (
                            [id] => FindAgain
                            [label] => Find Again
                        )

                    [13] => stdClass Object
                        (
                            [id] => Copy
                        )

                    [14] => stdClass Object
                        (
                            [id] => CopyAgain
                            [label] => Copy Again
                        )

                    [15] => stdClass Object
                        (
                            [id] => CopySVG
                            [label] => Copy SVG
                        )

                    [16] => stdClass Object
                        (
                            [id] => ViewSVG
                            [label] => View SVG
                        )

                    [17] => stdClass Object
                        (
                            [id] => ViewSource
                            [label] => View Source
                        )

                    [18] => stdClass Object
                        (
                            [id] => SaveAs
                            [label] => Save As
                        )

                    [19] => 
                    [20] => stdClass Object
                        (
                            [id] => Help
                        )

                    [21] => stdClass Object
                        (
                            [id] => About
                            [label] => About Adobe CVG Viewer...
                        )

                )

        )

)

Added doc/tests1all/md5_file.phpt.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
--TEST--
md5_file
--FILE--
md5_file(__FILE__) = <?php

echo md5_file(__FILE__);

?>
--EXPECT--
md5_file(__FILE__) = 187c2e06df4fb02560064398685e5113

Added doc/tests1all/mhash.phpt.



































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
mhash
--FILE--
<?php

echo "HMAC-MD5 test cases (RFC2104/page 9):\n\n";

# 1
$k = str_pad("", 16, chr(0x0b));
$text = "Hi There";
$end = unpack("H32", mhash(MHASH_MD5, $text, $k));
echo "key =     0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b\n";
echo "data =    \"$text\"\n";
echo "digest =  0x$end[1]\n";
echo "should =  0x9294727a3638bb1c13f48ef8158bfc9d\n\n";

# 2
$k = "Jefe";
$text = "what do ya want for nothing?";
$end = unpack("H32", mhash(MHASH_MD5, $text, $k));
echo "key =     \"$k\"\n";
echo "data =    \"$text\"\n";
echo "digest =  0x$end[1]\n";
echo "should =  0x750c783e6ab0b503eaa86e310a5db738\n\n";



?>
--EXPECT--
HMAC-MD5 test cases (RFC2104/page 9):


Fatal error: Call to undefined function mhash() in /home/mario/www/berli/upgradephp/doc/tests1all/mhash on line 8

Added doc/tests1all/mime_content_type.phpt.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
--TEST--
mime_content_type
--FILE--
<?php

$t = mime_content_type(__FILE__);
echo "mime_content_type(__FILE__) = $t\n\n";

?>
--EXPECT--
mime_content_type(__FILE__) = text/plain

Added doc/tests1all/scandir.phpt.























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
scandir
--FILE--
<?php

$r = scandir("..");
echo "..\n\n";
print_r($r);

?>
--EXPECT--
..

Array
(
    [0] => .
    [1] => ..
    [2] => README
    [3] => ctest
    [4] => devtools
    [5] => gettext.txt
    [6] => index.xhtml
    [7] => runtest
    [8] => tests0old
    [9] => tests1all
    [10] => tests2filter
)

Added doc/tests1all/spl_classes.phpt.























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
spl_classes
--FILE--
<?php

echo "print_r(spl_classes());\n\n";
$r=spl_classes();
print_r($r);

?>
--EXPECT--
print_r(spl_classes());

Array
(
    [AppendIterator] => AppendIterator
    [ArrayIterator] => ArrayIterator
    [ArrayObject] => ArrayObject
    [BadFunctionCallException] => BadFunctionCallException
    [BadMethodCallException] => BadMethodCallException
    [CachingIterator] => CachingIterator
    [Countable] => Countable
    [DirectoryIterator] => DirectoryIterator
    [DomainException] => DomainException
    [EmptyIterator] => EmptyIterator
    [FilterIterator] => FilterIterator
    [InfiniteIterator] => InfiniteIterator
    [InvalidArgumentException] => InvalidArgumentException
    [IteratorIterator] => IteratorIterator
    [LengthException] => LengthException
    [LimitIterator] => LimitIterator
    [LogicException] => LogicException
    [NoRewindIterator] => NoRewindIterator
    [OuterIterator] => OuterIterator
    [OutOfBoundsException] => OutOfBoundsException
    [OutOfRangeException] => OutOfRangeException
    [OverflowException] => OverflowException
    [ParentIterator] => ParentIterator
    [RangeException] => RangeException
    [RecursiveArrayIterator] => RecursiveArrayIterator
    [RecursiveCachingIterator] => RecursiveCachingIterator
    [RecursiveDirectoryIterator] => RecursiveDirectoryIterator
    [RecursiveFilterIterator] => RecursiveFilterIterator
    [RecursiveIterator] => RecursiveIterator
    [RecursiveIteratorIterator] => RecursiveIteratorIterator
    [RecursiveRegexIterator] => RecursiveRegexIterator
    [RegexIterator] => RegexIterator
    [RuntimeException] => RuntimeException
    [SeekableIterator] => SeekableIterator
    [SimpleXMLIterator] => SimpleXMLIterator
    [SplFileInfo] => SplFileInfo
    [SplFileObject] => SplFileObject
    [SplObjectStorage] => SplObjectStorage
    [SplObserver] => SplObserver
    [SplSubject] => SplSubject
    [SplTempFileObject] => SplTempFileObject
    [UnderflowException] => UnderflowException
    [UnexpectedValueException] => UnexpectedValueException
)

Added doc/tests1all/str_ireplace.phpt.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--TEST--
str_ireplace
--FILE--
<?php

$text = "ABC_abc_DEF_def_AAaaAAaa_DDddEEee";
echo "\$text = \"$text\";\n";
echo 'str_ireplace("abc", "xxx", $text);'."\n\n";

$text = str_ireplace("abc", "xxx", $text);
echo "\$text = \"$text\";\n";

?>
--EXPECT--
$text = "ABC_abc_DEF_def_AAaaAAaa_DDddEEee";
str_ireplace("abc", "xxx", $text);

$text = "xxx_xxx_DEF_def_AAaaAAaa_DDddEEee";

Added doc/tests1all/str_rot13.phpt.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
--TEST--
str_rot13
--FILE--
str_rot13('upgrade.php v4') = "<?php

echo str_rot13('upgrade.php v4');

?>"
--EXPECT--
str_rot13('upgrade.php v4') = "hctenqr.cuc i4"

Added doc/tests1all/str_shuffle.phpt.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
--TEST--
str_shuffle
--FILE--
str_shuffle("ABCDEF") == "<?php

srand(17);
echo str_shuffle("ABCDEF");

?>"
--EXPECT--
str_shuffle("ABCDEF") == "FBCEAD"

Added doc/tests1all/str_split.phpt.

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
str_split
--FILE--
<?php


?>
$str = "Hello Friend";
$r = str_split($str, 3);
print_r($r);

<?php
$str = "Hello_Friend";
$r = str_split($str, 3);
print_r($r);
?>
--EXPECT--
$str = "Hello Friend";
$r = str_split($str, 3);
print_r($r);

Array
(
    [0] => Hel
    [1] => lo_
    [2] => Fri
    [3] => end
)

Added doc/tests1all/str_word_count.phpt.









































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


$r = str_word_count("This is-a sample string.", 2);
echo 'str_word_count("This is-a sample string.", 2) = ';
print_r($r);


?>
--EXPECT--
str_word_count("This is-a sample string.", 2) = Array
(
    [0] => This
    [5] => is-a
    [10] => sample
    [17] => string
)

Added doc/tests1all/strftime.phpt.





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
strftime
--FILE--
<?php


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

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

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


?>
--EXPECT--
time=06:38:38 date=07/30/07
Array
(
    [tm_sec] => 38
    [tm_min] => 38
    [tm_hour] => 6
    [tm_mday] => 30
    [tm_mon] => 6
    [tm_year] => 107
    [tm_wday] => 1
    [tm_yday] => 210
    [unparsed] => 
)

Added doc/tests1all/stripos.phpt.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
--TEST--
stripos
--FILE--
<?php

$l = stripos("ABCDEFef", "e");
echo "stripos(\"ABCDEFef\", \"e\") == $l\n\n";

$r = strripos("ABCDefEF", "e");
echo "strripos(\"ABCDefEF\", \"e\") == $r\n\n";

?>
--EXPECT--
stripos("ABCDEFef", "e") == 4

strripos("ABCDefEF", "e") == 6

Added doc/tests1all/strpbrk.phpt.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
strpbrk
--FILE--
<?php

?>
$text = 'This is a Simple text.';

echo strpbrk($text, 'mi');
<?php
$text = 'This is a Simple text.';
echo strpbrk($text, 'mi')."\n\n";

echo 'echo strpbrk($text, "S");'."\n";
echo strpbrk($text, "S")."\n\n";
?>
--EXPECT--
$text = 'This is a Simple text.';

echo strpbrk($text, 'mi');
is is a Simple text.

echo strpbrk($text, "S");
Simple text.

Added doc/tests1all/strripos.phpt.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
--TEST--
strripos
--FILE--
<?php

echo 'strripos("aaaabc_DEFff_ABCccc", "a") == ';
echo strripos("aaaabc_DEFff_ABCccc", "a");

?>
--EXPECT--
strripos("aaaabc_DEFff_ABCccc", "a") == 13

Added doc/tests1all/substr_compare.phpt.













































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


echo 'substr_compare("abcde", "bc", 1, 2) == '. substr_compare("abcde", "bc", 1, 2) . "   // 0\n";
echo 'substr_compare("abcde", "bcg", 1, 2) == '. substr_compare("abcde", "bcg", 1, 2). "   // 0\n"; 
echo 'substr_compare("abcde", "BC", 1, 2, true) == '. substr_compare("abcde", "BC", 1, 2, true) . "   // 0\n";
echo 'substr_compare("abcde", "bc", 1, 3) == '. substr_compare("abcde", "bc", 1, 3) ."   // 1\n";
echo 'substr_compare("abcde", "cd", 1, 2) == '. substr_compare("abcde", "cd", 1, 2) ."  // -1\n";
echo 'substr_compare("abcde", "abc", 5, 1) == '. substr_compare("abcde", "abc", 5, 1) . "   // warning\n";
?>
--EXPECT--
substr_compare("abcde", "bc", 1, 2) == 0   // 0
substr_compare("abcde", "bcg", 1, 2) == 0   // 0
substr_compare("abcde", "BC", 1, 2, true) == 0   // 0
substr_compare("abcde", "bc", 1, 3) == 1   // 1
substr_compare("abcde", "cd", 1, 2) == -1  // -1

Warning: substr_compare(): The length cannot exceed initial string length in /home/mario/www/berli/upgradephp/doc/tests1all/substr_compare.php on line 9
substr_compare("abcde", "abc", 5, 1) ==    // warning

Added doc/tests1all/uuencode.phpt.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--TEST--
uuencode
--FILE--
<?php

$uu = convert_uuencode("ABCDEFGHIJ");
echo "\$uu = \"$uu\"\n\n";

$text = convert_uudecode($uu);
echo "\$text = \"$text\"\n\n";

?>
--EXPECT--
$uu = "*04)#1$5&1TA)2@``
`
"

$text = "ABCDEFGHIJ"

Added doc/tests1all/vprintf.phpt.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
--TEST--
vprintf
--FILE--
<?php

vprintf("%d, %d\n", array(17, 5));

?>
--EXPECT--
17, 5

Added doc/tests2filter/001.phpt.

















>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
--TEST--
Simple GET test
--GET--
a=1
--FILE--
<?php echo $_GET['a']; ?>
--EXPECT--
1

Added doc/tests2filter/002.phpt.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
--TEST--
GET test with 2 values and an empty one
--GET--
a=1&b=&c=3
--FILE--
<?php echo $_GET['a'];
echo $_GET['b']; 
echo $_GET['c'];
?>
--EXPECT--
13

Added doc/tests2filter/003.phpt.













































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--TEST--
GET/POST/REQUEST Test
--POST--
d=4&e=5
--GET--
a=1&b=&c=3
--FILE--
<?php echo $_GET['a'];
echo $_GET['b']; 
echo $_GET['c'];
echo $_POST['d'];
echo $_POST['e'];
echo "\n";
echo $_REQUEST['a'];
echo $_REQUEST['b'];
echo $_REQUEST['c'];
echo $_REQUEST['d'];
echo $_REQUEST['e'];
?>
--EXPECT--
1345
1345

Added doc/tests2filter/004.phpt.





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
GET/POST/REQUEST Test with filtered data
--SKIPIF--
<?php
/* CGI doesn't read commandline options when it sees REQUES_METHOD */
die("skip");
die("not possible to set ini setting using -d and CGI");
?>
--INI--
filter.default=special_chars
--POST--
d="quotes"&e=\slash
--GET--
a=O'Henry&b=&c=<b>Bold</b>
--FILE--
<?php echo $_GET['a'];
echo $_GET['b']; 
echo $_GET['c'];
echo $_POST['d'];
echo $_POST['e'];
echo "\n";
echo $_REQUEST['a'];
echo $_REQUEST['b'];
echo $_REQUEST['c'];
echo $_REQUEST['d'];
echo $_REQUEST['e'];
?>
--EXPECT--
O&#39;HenryBold&quot;quotes&quot;\slash
O&#39;HenryBold&quot;quotes&quot;\slash

Added doc/tests2filter/005.phpt.











































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
--TEST--
GET/REQUEST Test with fifa example data
--INI--
filter.default=stripped
--GET--
id=f03_photos&pgurl=http%3A//fifaworldcup.yahoo.com/03/en/photozone/index.html
--FILE--
<?php 
echo $_GET['id'];
echo "\n";
echo $_GET['pgurl']; 
echo "\n";
echo $_REQUEST['id'];
echo "\n";
echo $_REQUEST['pgurl']; 
?>
--EXPECT--
f03_photos
http://fifaworldcup.yahoo.com/03/en/photozone/index.html
f03_photos
http://fifaworldcup.yahoo.com/03/en/photozone/index.html

Added doc/tests2filter/006.phpt.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
--TEST--
filter() test
--POST--
foo=<b>abc</b>
--FILE--
<?php 
echo filter_input(INPUT_POST, 'foo', FILTER_SANITIZE_STRIPPED);
?>
--EXPECT--
abc

Added doc/tests2filter/007.phpt.









































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
input_has_variable()
--SKIPIF--
<?php
/* TODO: Check why we get warnings 2x */
die("skip");
die("error mode cannot be changed via -d");
?>
--GET--
a=qwe&abc=<a>href</a>
--POST--
b=qwe&bbc=<a>href</a>
--FILE--
<?php

var_dump(input_has_variable(INPUT_GET, "a"));
var_dump(input_has_variable(INPUT_GET, "abc"));
var_dump(input_has_variable(INPUT_GET, "nonex"));
var_dump(input_has_variable(INPUT_GET, " "));
var_dump(input_has_variable(INPUT_GET, ""));
var_dump(input_has_variable(INPUT_GET, array()));

var_dump(input_has_variable(INPUT_POST, "b"));
var_dump(input_has_variable(INPUT_POST, "bbc"));
var_dump(input_has_variable(INPUT_POST, "nonex"));
var_dump(input_has_variable(INPUT_POST, " "));
var_dump(input_has_variable(INPUT_POST, ""));
var_dump(input_has_variable(INPUT_POST, array()));

var_dump(input_has_variable(-1, ""));
var_dump(input_has_variable("", ""));
var_dump(input_has_variable(array(), array()));
var_dump(input_has_variable(array(), ""));
var_dump(input_has_variable("", array()));

echo "Done\n";
?>
--EXPECTF--	
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)

Warning: input_has_variable() expects parameter 2 to be string, array given in %s on line %d
NULL
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)

Warning: input_has_variable() expects parameter 2 to be string, array given in %s on line %d
NULL
bool(false)

Warning: input_has_variable() expects parameter 1 to be long, string given in %s on line %d
NULL

Warning: input_has_variable() expects parameter 1 to be long, array given in %s on line %d
NULL

Warning: input_has_variable() expects parameter 1 to be long, array given in %s on line %d
NULL

Warning: input_has_variable() expects parameter 1 to be long, string given in %s on line %d
NULL
Done

Added doc/tests2filter/008.phpt.











































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_list()
--FILE--
<?php

var_dump(filter_list());
var_dump(filter_list(array()));

echo "Done\n";
?>
--EXPECTF--	
array(18) {
  [0]=>
  string(3) "int"
  [1]=>
  string(7) "boolean"
  [2]=>
  string(5) "float"
  [3]=>
  string(15) "validate_regexp"
  [4]=>
  string(12) "validate_url"
  [5]=>
  string(14) "validate_email"
  [6]=>
  string(11) "validate_ip"
  [7]=>
  string(6) "string"
  [8]=>
  string(8) "stripped"
  [9]=>
  string(7) "encoded"
  [10]=>
  string(13) "special_chars"
  [11]=>
  string(10) "unsafe_raw"
  [12]=>
  string(5) "email"
  [13]=>
  string(3) "url"
  [14]=>
  string(10) "number_int"
  [15]=>
  string(12) "number_float"
  [16]=>
  string(12) "magic_quotes"
  [17]=>
  string(8) "callback"
}

Warning: Wrong parameter count for filter_list() in %s008.php on line 4
NULL
Done

Added doc/tests2filter/009.phpt.

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_id()
--FILE--
<?php

var_dump(filter_id("stripped"));
var_dump(filter_id("string"));
var_dump(filter_id("url"));
var_dump(filter_id("int"));
var_dump(filter_id("none"));
var_dump(filter_id(array()));
var_dump(filter_id(-1));
var_dump(filter_id(0,0,0));

echo "Done\n";
?>
--EXPECTF--	
int(513)
int(513)
int(518)
int(257)
bool(false)

Warning: filter_id() expects parameter 1 to be string, array given in %s009.php on line %d
NULL
bool(false)

Warning: filter_id() expects exactly 1 parameter, 3 given in %s009.php on line %d
NULL
Done
--UEXPECTF--
int(513)
int(513)
int(518)
int(257)
bool(false)

Warning: filter_id() expects parameter 1 to be binary string, array given in %s009.php on line %d
NULL
bool(false)

Warning: filter_id() expects exactly 1 parameter, 3 given in %s009.php on line %d
NULL
Done

Added doc/tests2filter/010.phpt.

























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var()
--FILE--
<?php

var_dump(filter_var(array(1,"1","", "-23234", "text", "asdf234asdfgs", array()), FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY));
var_dump(filter_var(array(1.2,"1.7","", "-23234.123", "text", "asdf234.2asdfgs", array()), FILTER_VALIDATE_FLOAT, FILTER_REQUIRE_ARRAY));
var_dump(filter_var(1, array()));
var_dump(filter_var(1, FILTER_SANITIZE_STRING, 1));
var_dump(filter_var(1, FILTER_SANITIZE_STRING, 0));
var_dump(filter_var(1, FILTER_SANITIZE_STRING, array()));
var_dump(filter_var(1, -1, array(123)));
var_dump(filter_var(1, 0, array()));

echo "Done\n";
?>
--EXPECTF--	
array(7) {
  [0]=>
  int(1)
  [1]=>
  int(1)
  [2]=>
  bool(false)
  [3]=>
  int(-23234)
  [4]=>
  bool(false)
  [5]=>
  bool(false)
  [6]=>
  array(0) {
  }
}
array(7) {
  [0]=>
  float(1.2)
  [1]=>
  float(1.7)
  [2]=>
  bool(false)
  [3]=>
  float(-23234.123)
  [4]=>
  bool(false)
  [5]=>
  bool(false)
  [6]=>
  array(0) {
  }
}

Warning: filter_var() expects parameter 2 to be long, array given in %s on line %d
NULL
string(1) "1"
string(1) "1"
string(1) "1"
string(1) "1"
string(1) "1"
Done

Added doc/tests2filter/011.phpt.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
input_get()
--SKIPIF--
<?php
/* TODO: Check why we get warnings 2x */
die("skip");
die("error mode cannot be changed via -d");
?>
--GET--
a=<b>test</b>&b=http://example.com
--POST--
c=<p>string</p>&d=12345.7
--FILE--
<?php
ini_set('html_errors', false);
var_dump(input_get(INPUT_GET, "a", FILTER_SANITIZE_STRIPPED));
var_dump(input_get(INPUT_GET, "b", FILTER_SANITIZE_URL));
var_dump(input_get(INPUT_GET, "a", FILTER_SANITIZE_SPECIAL_CHARS, array(1,2,3,4,5)));
var_dump(input_get(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass));
var_dump(input_get(INPUT_POST, "c", FILTER_SANITIZE_STRIPPED, array(5,6,7,8)));
var_dump(input_get(INPUT_POST, "d", FILTER_VALIDATE_FLOAT));
var_dump(input_get(INPUT_POST, "c", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(input_get(INPUT_POST, "d", FILTER_VALIDATE_INT));

var_dump(input_get(new stdClass, "d"));

var_dump(input_get(INPUT_POST, "c", "", ""));
var_dump(input_get("", "", "", "", ""));
var_dump(input_get(0, 0, 0, 0, 0));

echo "Done\n";
?>
--EXPECTF--	
string(4) "test"
string(18) "http://example.com"
string(27) "&#60;b&#62;test&#60;/b&#62;"
bool(false)
string(6) "string"
float(12345.7)
string(29) "&#60;p&#62;string&#60;/p&#62;"
bool(false)

Warning: input_get() expects parameter 1 to be long, object given in %s on line %d
NULL

Warning: input_get() expects parameter 3 to be long, string given in %s on line %d
NULL

Warning: input_get() expects parameter 1 to be long, string given in %s on line %d
NULL
NULL
Done

Added doc/tests2filter/012.phpt.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--TEST--
filter_input()
--FILE--
<?php

var_dump(filter_input(INPUT_GET, "test"));
var_dump(filter_input(INPUT_POST, "test"));
var_dump(filter_input(INPUT_COOKIE, ""));

echo "Done\n";
?>
--EXPECT--	
NULL
NULL
NULL
Done

Added doc/tests2filter/013.phpt.

















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and flags
--FILE--
<?php
var_dump(filter_var("  234", FILTER_VALIDATE_INT));
var_dump(filter_var("234    ", FILTER_VALIDATE_INT));
var_dump(filter_var("  234  ", FILTER_VALIDATE_INT));
var_dump(filter_var("0xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("0Xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("0xFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("0XFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("07", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));
var_dump(filter_var("0xff0000", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("0666", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));
var_dump(filter_var("08", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));
var_dump(filter_var("00", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));
var_dump(filter_var("000", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));

var_dump(filter_var("-0xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("-0Xff", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("-0xFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("-0XFF", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("-07", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));
var_dump(filter_var("-0xff0000", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)));
var_dump(filter_var("-0666", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)));

var_dump(filter_var("6", FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>7))));
var_dump(filter_var("6", FILTER_VALIDATE_INT, array("options" => array("min_range"=>0, "max_range"=>5))));
var_dump(filter_var(-1, FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>7))));
var_dump(filter_var(-1, FILTER_VALIDATE_INT, array("options" => array("min_range"=>-4, "max_range"=>7))));

var_dump(filter_var("", FILTER_VALIDATE_INT, array("options" => array("min_range"=>-4, "max_range"=>7))));
var_dump(filter_var("", FILTER_VALIDATE_INT, array("options" => array("min_range"=>2, "max_range"=>7))));
var_dump(filter_var("", FILTER_VALIDATE_INT, array("options" => array("min_range"=>-5, "max_range"=>-3))));
var_dump(filter_var(345, FILTER_VALIDATE_INT, array("options" => array("min_range"=>500, "max_range"=>100))));
var_dump(filter_var("0ff", FILTER_VALIDATE_INT));
var_dump(filter_var("010", FILTER_VALIDATE_INT));

echo "Done\n";
?>
--EXPECT--	
int(234)
int(234)
int(234)
int(255)
int(255)
int(255)
int(255)
int(7)
int(16711680)
int(438)
bool(false)
int(0)
int(0)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
int(6)
bool(false)
bool(false)
int(-1)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
Done

Added doc/tests2filter/014.phpt.









































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_VALIDATE_BOOLEAN
--FILE--
<?php

class test {

	function __toString() {
		return "blah";
	}
}

$t = new test;

var_dump(filter_var("no", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var(NULL, FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var($t, FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var(array(1,2,3,0,array("", "123")), FILTER_VALIDATE_BOOLEAN, FILTER_REQUIRE_ARRAY));
var_dump(filter_var("yes", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("true", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("false", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("off", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("on", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("0", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("1", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("NONE", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var(-1, FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("000000", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_var("111111", FILTER_VALIDATE_BOOLEAN));
	

echo "Done\n";
?>
--EXPECT--	
bool(false)
bool(false)
bool(false)
array(5) {
  [0]=>
  bool(true)
  [1]=>
  bool(false)
  [2]=>
  bool(false)
  [3]=>
  bool(false)
  [4]=>
  array(2) {
    [0]=>
    bool(false)
    [1]=>
    bool(false)
  }
}
bool(true)
bool(true)
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
Done

Added doc/tests2filter/015.phpt.















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_VALIDATE_URL
--FILE--
<?php

$values = Array(
'http://example.com/index.html',	
'http://www.example.com/index.php',	
'http://www.example/img/test.png',	
'http://www.example/img/dir/',	
'http://www.example/img/dir',	
'http//www.example/wrong/url/',	
'http:/www.example',	
'file:///tmp/test.c',	
'ftp://ftp.example.com/tmp/',	
'/tmp/test.c',	
'/',	
'http://',	
'http:/',	
'http:',	
'http',	
'',	
-1,	
array(),	
);
foreach ($values as $value) {
	var_dump(filter_var($value, FILTER_VALIDATE_URL));
}


var_dump(filter_var("qwe", FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var("http://qwe", FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var("http://", FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var("/tmp/test", FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var("http://www.example.com", FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var("http://www.example.com", FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var("http://www.example.com/path/at/the/server/", FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var("http://www.example.com/index.html", FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));
var_dump(filter_var("http://www.example.com/index.php?a=b&c=d", FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));

echo "Done\n";
?>
--EXPECT--	
string(29) "http://example.com/index.html"
string(32) "http://www.example.com/index.php"
string(31) "http://www.example/img/test.png"
string(27) "http://www.example/img/dir/"
string(26) "http://www.example/img/dir"
string(28) "http//www.example/wrong/url/"
string(17) "http:/www.example"
string(18) "file:///tmp/test.c"
string(26) "ftp://ftp.example.com/tmp/"
string(11) "/tmp/test.c"
string(1) "/"
bool(false)
string(6) "http:/"
string(5) "http:"
string(4) "http"
string(0) ""
string(2) "-1"
bool(false)
bool(false)
string(10) "http://qwe"
bool(false)
bool(false)
string(22) "http://www.example.com"
bool(false)
string(42) "http://www.example.com/path/at/the/server/"
bool(false)
string(40) "http://www.example.com/index.php?a=b&c=d"
Done

Added doc/tests2filter/016.phpt.

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_VALIDATE_EMAIL
--FILE--
<?php
$values = Array(
'a@b.c',	
'abuse@example.com',	
'test!.!@#$%^&*@example.com',	
'test@@#$%^&*())).com',	
'test@.com',	
'test@com',	
'@',	
'[]()/@example.com',	
'QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET',	
);
foreach ($values as $value) {
	var_dump(filter_var($value, FILTER_VALIDATE_EMAIL));
}

echo "Done\n";
?>
--EXPECT--	
string(5) "a@b.c"
string(17) "abuse@example.com"
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
string(57) "QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET"
Done

Added doc/tests2filter/017.phpt.

















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--TEST--
filter_var() and FILTER_VALIDATE_REGEXP
--FILE--
<?php

var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/.*/'))));
var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^b(.*)/'))));
var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^d(.*)/'))));
var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/blah/'))));
var_dump(filter_var("data", FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/\[/'))));
var_dump(filter_var("data", FILTER_VALIDATE_REGEXP));

echo "Done\n";
?>
--EXPECTF--	
string(4) "data"
bool(false)
string(4) "data"
bool(false)
bool(false)

Warning: filter_var(): 'regexp' option missing in %s on line %d
bool(false)
Done

Added doc/tests2filter/018.phpt.





































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_VALIDATE_IP
--FILE--
<?php
var_dump(filter_var("192.168.0.1", FILTER_VALIDATE_IP));
var_dump(filter_var("192.168.0.1.1", FILTER_VALIDATE_IP));
var_dump(filter_var("::1", FILTER_VALIDATE_IP));
var_dump(filter_var("fe00::0", FILTER_VALIDATE_IP));
var_dump(filter_var("::123456", FILTER_VALIDATE_IP));
var_dump(filter_var("::1::b", FILTER_VALIDATE_IP));
var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP));
var_dump(filter_var("192.168.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE));
var_dump(filter_var("192.0.34.166", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE));
var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
var_dump(filter_var("192.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
var_dump(filter_var("192.0.34.166", FILTER_VALIDATE_IP));
var_dump(filter_var("256.1237.123.1", FILTER_VALIDATE_IP));
var_dump(filter_var("255.255.255.255", FILTER_VALIDATE_IP));
var_dump(filter_var("255.255.255.255", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
var_dump(filter_var("", FILTER_VALIDATE_IP));
var_dump(filter_var(-1, FILTER_VALIDATE_IP));
var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
echo "Done\n";
?>
--EXPECT--	
string(11) "192.168.0.1"
bool(false)
string(3) "::1"
string(7) "fe00::0"
bool(false)
bool(false)
string(9) "127.0.0.1"
bool(false)
string(12) "192.0.34.166"
string(9) "127.0.0.1"
string(9) "192.0.0.1"
string(12) "192.0.34.166"
bool(false)
string(15) "255.255.255.255"
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
string(3) "::1"
string(9) "127.0.0.1"
Done

Added doc/tests2filter/019.phpt.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--TEST--
filter_var() & FILTER_VALIDATE_IP and weird data
--FILE--
<?php

var_dump(filter_var("....", FILTER_VALIDATE_IP));
var_dump(filter_var("...", FILTER_VALIDATE_IP));
var_dump(filter_var("..", FILTER_VALIDATE_IP));
var_dump(filter_var(".", FILTER_VALIDATE_IP));
var_dump(filter_var("1.1.1.1", FILTER_VALIDATE_IP));

echo "Done\n";
?>
--EXPECT--	
bool(false)
bool(false)
bool(false)
bool(false)
string(7) "1.1.1.1"
Done

Added doc/tests2filter/020.phpt.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--TEST--
filter_var() and FILTER_SANITIZE_MAGIC_QUOTES
--FILE--
<?php

var_dump(filter_var("test'asd'asd'' asd\'\"asdfasdf", FILTER_SANITIZE_MAGIC_QUOTES));
var_dump(filter_var("'", FILTER_SANITIZE_MAGIC_QUOTES));
var_dump(filter_var("", FILTER_SANITIZE_MAGIC_QUOTES));
var_dump(filter_var(-1, FILTER_SANITIZE_MAGIC_QUOTES));

echo "Done\n";
?>
--EXPECT--	
string(36) "test\'asd\'asd\'\' asd\\\'\"asdfasdf"
string(2) "\'"
string(0) ""
string(2) "-1"
Done

Added doc/tests2filter/021.phpt.

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_SANITIZE_NUMBER_*
--FILE--
<?php

var_dump(filter_var("qwertyu123456dfghj", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("asd123123.asd123.23", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("123,23", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("0", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("asd123.2asd", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("qwertyuiop", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("123.4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_var("123,4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_var("123.4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
var_dump(filter_var("123,4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
var_dump(filter_var("123.4e", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC));
var_dump(filter_var("123,4E", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC));
var_dump(filter_var("qwe123,4qwe", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_var("werty65456.34", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_var("234.56fsfd", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_var("", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));

echo "Done\n";
?>
--EXPECT--	
string(6) "123456"
string(11) "12312312323"
string(5) "12323"
string(0) ""
string(1) "0"
string(4) "1232"
string(0) ""
string(5) "123.4"
string(4) "1234"
string(4) "1234"
string(5) "123,4"
string(5) "1234e"
string(5) "1234E"
string(4) "1234"
string(8) "65456.34"
string(6) "234.56"
string(0) ""
Done

Added doc/tests2filter/022.phpt.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--TEST--
filter_var() and FILTER_SANITIZE_EMAIL
--FILE--
<?php

var_dump(filter_var("a@b.c", FILTER_SANITIZE_EMAIL));
var_dump(filter_var("a[!@#$%^&*()@a@#$%^&*(.com@#$%^&*(", FILTER_SANITIZE_EMAIL));
var_dump(filter_var("white space here \ \ \" som more", FILTER_SANITIZE_EMAIL));
var_dump(filter_var("", FILTER_SANITIZE_EMAIL));
var_dump(filter_var("123456789000000", FILTER_SANITIZE_EMAIL));
	
echo "Done\n";
?>
--EXPECTF--	
string(5) "a@b.c"
string(30) "a[!@#$%^&*@a@#$%^&*.com@#$%^&*"
string(21) "whitespaceheresommore"
string(0) ""
string(15) "123456789000000"
Done

Added doc/tests2filter/023.phpt.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--TEST--
filter_var() and FILTER_UNSAFE_RAW
--FILE--
<?php

var_dump(filter_var("}\"<p>test para</p>", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_var("a[!@#<b>$%^&*()@a@#$%^&*(.<br>com@#$%^&*(", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_var("white space here \ \ \" some more", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_var("", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_var("             123456789000000       <qwertyuiop> ", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
	
echo "Done\n";
?>
--EXPECT--	
string(18) "}"<p>test para</p>"
string(53) "a[!@#<b>$%^&#38;*()@a@#$%^&#38;*(.<br>com@#$%^&#38;*("
string(32) "white space here \ \ " some more"
string(0) ""
string(48) "             123456789000000       <qwertyuiop> "
Done

Added doc/tests2filter/024.phpt.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--TEST--
filter_var() and FILTER_SANITIZE_ENCODED
--FILE--
<?php

var_dump(filter_var("\"<br>blah</ph>", FILTER_SANITIZE_ENCODED));
var_dump(filter_var("", FILTER_SANITIZE_ENCODED));
var_dump(filter_var("  text here  ", FILTER_SANITIZE_ENCODED));
var_dump(filter_var("!@#$%^&*()QWERTYUIOP{ASDFGHJKL:\"ZXCVBNM<>?", FILTER_SANITIZE_ENCODED));

echo "Done\n";
?>
--EXPECT--	
string(26) "%22%3Cbr%3Eblah%3C%2Fph%3E"
string(0) ""
string(23) "%20%20text%20here%20%20"
string(74) "%21%40%23%24%25%5E%26%2A%28%29QWERTYUIOP%7BASDFGHJKL%3A%22ZXCVBNM%3C%3E%3F"
Done

Added doc/tests2filter/025.phpt.

















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--TEST--
filter_var() and FILTER_SANITIZE_STRING
--FILE--
<?php

var_dump(filter_var("", FILTER_SANITIZE_STRING));
var_dump(filter_var("<>", FILTER_SANITIZE_STRING));
var_dump(filter_var("<>!@#$%^&*()'\"", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES));
var_dump(filter_var("<>!@#$%^&*()'\"", FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_var("<>`1234567890", FILTER_SANITIZE_STRING));
var_dump(filter_var("`123`", FILTER_SANITIZE_STRING));
var_dump(filter_var(".", FILTER_SANITIZE_STRING));

echo "Done\n";
?>
--EXPECT--	
string(0) ""
string(0) ""
string(12) "!@#$%^&*()'""
string(32) "!@#$%^&#38;*()&#38;#39;&#38;#34;"
string(11) "`1234567890"
string(5) "`123`"
string(1) "."
Done

Added doc/tests2filter/026.phpt.





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_SANITIZE_STRIPPED
--FILE--
<?php

var_dump(filter_var("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED));
var_dump(filter_var("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED));
var_dump(filter_var("", FILTER_SANITIZE_STRIPPED));

var_dump(filter_var("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW));
var_dump(filter_var("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW));
var_dump(filter_var("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW));

var_dump(filter_var("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH));
var_dump(filter_var("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH));
var_dump(filter_var("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH));

echo "Done\n";
?>
--EXPECTF--	
string(40) "Let me see you Stripped down to the bone"
string(11) "!@#$%^&*()>"
string(0) ""
string(40) "Let me see you Stripped down to the bone"
string(11) "!@#$%^&*()>"
string(0) ""
string(40) "Let me see you Stripped down to the bone"
string(11) "!@#$%^&*()>"
string(0) ""
Done

Added doc/tests2filter/027.phpt.





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_SANITIZE_ENCODED
--FILE--
<?php

var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED));
var_dump(filter_var("<data&sons>", FILTER_SANITIZE_ENCODED));
var_dump(filter_var("", FILTER_SANITIZE_ENCODED));

var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_var("<data&sons>", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_var("", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW));

var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_var("<data&sons>", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_var("", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH));

echo "Done\n";
?>
--EXPECT--	
string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn"
string(17) "%3Cdata%26sons%3E"
string(0) ""
string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn"
string(17) "%3Cdata%26sons%3E"
string(0) ""
string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn"
string(17) "%3Cdata%26sons%3E"
string(0) ""
Done

Added doc/tests2filter/028.phpt.







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_SANITIZE_SPECIAL_CHARS
--FILE--
<?php

var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(filter_var("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(filter_var("", FILTER_SANITIZE_SPECIAL_CHARS));

var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_var("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_var("", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));

var_dump(filter_var("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_var("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_var("", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));

var_dump(filter_var("ΠΊΠΈΡ€ΠΈΠ»Π»ΠΈΡ†Π°", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_var("ΠΊΠΈΡ€ΠΈΠ»Π»ΠΈΡ†Π°", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));

echo "Done\n";
?>
--EXPECT--	
string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
string(23) "&#60;data&#38;sons&#62;"
string(0) ""
string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
string(23) "&#60;data&#38;sons&#62;"
string(0) ""
string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
string(23) "&#60;data&#38;sons&#62;"
string(0) ""
string(108) "&#208;&#186;&#208;&#184;&#209;&#128;&#208;&#184;&#208;&#187;&#208;&#187;&#208;&#184;&#209;&#134;&#208;&#176;"
string(18) "ΠΊΠΈΡ€ΠΈΠ»Π»ΠΈΡ†Π°"
Done

Added doc/tests2filter/029.phpt.















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FILTER_CALLBACK
--FILE--
<?php

/* Simple callback function */
function test($var) {
	return strtoupper($var);
}
	
var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test")));
var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test")));
var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test")));
var_dump(filter_var("qwe", FILTER_CALLBACK, array("options"=>"no such func")));
var_dump(filter_var("qwe", FILTER_CALLBACK, array("options"=>"")));
var_dump(filter_var("qwe", FILTER_CALLBACK));

/* Simple class method callback */
class test_class {
	static function test ($var) {
		return strtolower($var);
	}
}

var_dump(filter_var("dAtA", FILTER_CALLBACK, array("options"=>array("test_class", "test"))));
var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>array("test_class","test"))));
var_dump(filter_var("", FILTER_CALLBACK, array("options"=>array("test_class","test"))));

/* empty function without return value */
function test1($var) {
}
	
var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test1")));
var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test1")));
var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test1")));

/* attempting to change data by reference */
function test2(&$var) {
	$var = 1;
}
	
var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test2")));
var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test2")));
var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test2")));

/* unsetting data */
function test3(&$var) {
	unset($var);
}
	
var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test3")));
var_dump(filter_var("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("options"=>"test3")));
var_dump(filter_var("", FILTER_CALLBACK, array("options"=>"test3")));

/* unset data and return value */
function test4(&$var) {
	unset($var);
	return 1;
}
	
var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test4")));

/* thrown exception in the callback */
function test5(&$var) {
	throw new Exception("test");
}

try {
	var_dump(filter_var("data", FILTER_CALLBACK, array("options"=>"test5")));
} catch (Exception $e) {
	var_dump($e->getMessage());
}

echo "Done\n";
?>
--EXPECTF--	
string(4) "DATA"
string(46) "~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?"}{:"
string(0) ""

Warning: filter_var(): First argument is expected to be a valid callback in %s on line %d
NULL

Warning: filter_var(): First argument is expected to be a valid callback in %s on line %d
NULL

Warning: filter_var(): First argument is expected to be a valid callback in %s on line %d
NULL
string(4) "data"
string(46) "~!@#$%^&*()_qwertyuiopasdfghjklzxcvbnm<>>?"}{:"
string(0) ""
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
int(1)
string(4) "test"
Done

Added doc/tests2filter/030.phpt.







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and IPv6 
--FILE--
<?php
$ipv6_test = array(
	"::127.0.0.1"				=> true,
	"FF01::101:127.0.1" 		=> false,
	"FF01:0:0:0:101:127.0.1.1"  => false,
	"FF01:0:0:0:237:101:127.0.1.1"  => true,
	"FF01::101"					=> true,
	"A1080::8:800:200C:417A"	=> false,
	"1080::8:Z00:200C:417A"		=> false,
	"FF01::101::1"				=> false,
	"1080::8:800:200C:417A"		=> true,
	"1080:0:0:0:8:800:200C:417A" => true,
	"2001:ec8:1:1:1:1:1:1"			=> true,
	"ffff::FFFF:129.144.52.38"		=> true,
	"::ffff:1.2.3.4"				=> true,
	"0:0:0:0:0:FFFF:129.144.52.38" => true,
	"0:0:0:0:0:0:13.1.68.3"		=> true,
	"::13.1.68.3"				=> true,
    "::FFFF:129.144.52.38"		=> true
);
foreach ($ipv6_test as $ip => $exp) {
	$out = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
	$out = (int) ($out === false ? 0 : 1);
	if ($exp != $out) {
		echo "$ip failed\n";
	}
}

echo "Ok\n";
?>
--EXPECT--	
Ok

Added doc/tests2filter/031.phpt.













































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
filter_var() and FLOAT
--FILE--
<?php

$floats = array(
'1.234   ',
'   1.234',
'1.234'	,
'1.2e3',
'7E3',
'7E3     ',
'  7E3     ',
'  7E-3     '
);

foreach ($floats as $float) {
	$out = filter_var($float, FILTER_VALIDATE_FLOAT);
	var_dump($out);
}

$floats = array(
'1.234   '	=> ',',
'1,234'		=> ',',
'   1.234'	=> '.',
'1.234'		=> '..',
'1.2e3'		=> ','
);

echo "\ncustom decimal:\n";
foreach ($floats as $float => $dec) {
	$out = filter_var($float, FILTER_VALIDATE_FLOAT, array("options"=>array('decimal' => $dec)));
	var_dump($out);
}

?>
--EXPECTF--
float(1.234)
float(1.234)
float(1.234)
float(1200)
float(7000)
float(7000)
float(7000)
float(0.007)

custom decimal:
bool(false)
float(1.234)
float(1.234)

Warning: filter_var(): decimal separator must be one char in %s on line %d
bool(false)
bool(false)

Added doc/tests2filter/032.phpt.















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
input_get_args()
--FILE--
<?php
$data = array(
    'product_id'    => 'libgd<script>',
    'component'     => '10dhsajkkdhk <do>',
    'versions'      => '2.0.33',
    'testscalar'    => array('2','23','10','12'),
    'testarray'     => '2',
);

$args = array(
    'product_id'    => FILTER_SANITIZE_ENCODED,
    'component'     => array(//'filter' => FILTER_VALIDATE_INT,
                             'flags'    => FILTER_FORCE_ARRAY,
                             'options'  => array("min_range"=>1, "max_range"=>10)
                        ),
    'versions'      => array(
                            'filter' => FILTER_SANITIZE_ENCODED,
                            'flags'  => FILTER_REQUIRE_SCALAR,
                            ),
    'doesnotexist'  => FILTER_VALIDATE_INT,
    'testscalar'    => FILTER_VALIDATE_INT,
    'testarray' => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_FORCE_ARRAY,
                        )

);

$myinputs = filter_var_array($data, $args);
var_dump($myinputs);
?>
--EXPECT--
array(6) {
  ["product_id"]=>
  string(17) "libgd%3Cscript%3E"
  ["component"]=>
  array(1) {
    [0]=>
    string(17) "10dhsajkkdhk <do>"
  }
  ["versions"]=>
  string(6) "2.0.33"
  ["doesnotexist"]=>
  NULL
  ["testscalar"]=>
  bool(false)
  ["testarray"]=>
  array(1) {
    [0]=>
    int(2)
  }
}

Added doc/tests2filter/033.phpt.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
Test all filters returned by filter_list()
--FILE--
<?php
include dirname(__FILE__) . '/033_run.inc';
?>
--EXPECT--     
int                      1                                               123                                               
boolean                  1                                                                                                 
float                    1                                               123                                               
validate_regexp                                                                                   O'Henry                  
validate_url        PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc<>()          O'Henry        ν•˜νΌ    
validate_email              foo@bar.com                                                                                    
validate_ip                                                    1.2.3.4                                                     
string              PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc()            O&#39;Henry    ν•˜νΌ    
stripped            PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc()            O&#39;Henry    ν•˜νΌ    
encoded             PHP  1  foo%40bar.com  http%3A%2F%2Fa.b.c  1.2.3.4   123  123abc%3C%3E%28%29  O%27Henry      %ED%95%98%ED%8D%BC
special_chars       PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc&#60;&#62;()  O&#39;Henry    ν•˜νΌ    
unsafe_raw          PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc<>()          O'Henry        ν•˜νΌ    
email               PHP  1  foo@bar.com    http//a.b.c         1.2.3.4   123  123abc              O'Henry                  
url                 PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc<>()          O'Henry                  
number_int               1                                     1234      123  123                                          
number_float             1                                     1234      123  123                                          
magic_quotes        PHP  1  foo@bar.com    http://a.b.c        1.2.3.4   123  123abc<>()          O\'Henry       ν•˜νΌ    
callback            PHP  1  FOO@BAR.COM    HTTP://A.B.C        1.2.3.4   123  123ABC<>()          O'HENRY        ν•˜νΌ  

Added doc/tests2filter/034.phpt.































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
Logical filter: boolean
--FILE--
<?php
$booleans = array(
'1' => true,
'On' => true,
'Off' => true,
'True' => true,
'TrUe' => true,
'oN' => true,

'0' => false,
'Off' => false,
'False' => false,
'faLsE' => false,
'oFf' => false,

'' => false
);

foreach($booleans as $val=>$exp) {
    $res =filter_var($val, FILTER_VALIDATE_BOOLEAN);
	    if ($res !== $exp) {
        echo "$val failed,'$exp' expect, '$res' received.\n";
    }
}
echo "Ok.";
?>
--EXPECTF--	
Ok.

Added doc/tests2filter/035.phpt.









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
GET/POST/REQUEST Test with input_filter 
--POST--
d=379
--GET--
ar[elm1]=1234&ar[elm2]=0660&a=0234
--FILE--
<?php
$ret = filter_input(INPUT_GET, 'a', FILTER_VALIDATE_INT);
var_dump($ret);

$ret = filter_input(INPUT_GET, 'a', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL));
var_dump($ret);

$ret = filter_input(INPUT_GET, 'ar', FILTER_VALIDATE_INT, array('flags'=>FILTER_REQUIRE_ARRAY));
var_dump($ret);

$ret = filter_input(INPUT_GET, 'ar', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY));
var_dump($ret);

?>
--EXPECT--
bool(false)
int(156)
array(2) {
  ["elm1"]=>
  int(1234)
  ["elm2"]=>
  bool(false)
}
array(2) {
  ["elm1"]=>
  int(1234)
  ["elm2"]=>
  int(432)
}

Added doc/tests2filter/036.phpt.















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
input_get_args() and references
--SKIPIF--
<?php if (!extension_loaded("filter")) print "skip"; ?>
--FILE--
<?php

$var = "1";

$data = array();
$data["test1"] = 1;
$data["test2"] = &$var;

$args = array();
$args["test1"] = FILTER_VALIDATE_INT;
$args["test2"] = FILTER_VALIDATE_INT;

$ret = filter_var_array($data, $args);
var_dump($ret);
var_dump($data); //should be separated, i.e. not reference anymore. looks like we can't change this, or it'd change the original zval instead..
var_dump($var); //should be still string(1) "1"

echo "Done\n";
?>
--EXPECTF--	
array(2) {
  ["test1"]=>
  int(1)
  ["test2"]=>
  int(1)
}
array(2) {
  ["test1"]=>
  int(1)
  ["test2"]=>
  &string(1) "1"
}
string(1) "1"
Done

Added doc/tests2filter/037.phpt.















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
GET and data callback tests
--GET--
a=1&b=2
--FILE--
<?php
function myfunc($val) {
	return $val . '_callback';
}
echo filter_input(INPUT_GET, 'a', FILTER_CALLBACK, array("options"=>'myfunc'));
echo "\n";
echo filter_input(INPUT_GET, 'b', FILTER_VALIDATE_INT);
echo "\n";
$data = "data";

echo filter_var($data, FILTER_CALLBACK, array("options"=>'myfunc'));
echo "\n";

$res = filter_input_array(INPUT_GET, array(
				'a' => array(
					'filter' => FILTER_CALLBACK,
					'options' => 'myfunc'
					),
				'b' => FILTER_VALIDATE_INT 
		)
	);

var_dump($res);
?>
--EXPECT--
1_callback
2
data_callback
array(2) {
  ["a"]=>
  string(10) "1_callback"
  ["b"]=>
  int(2)
}

Added doc/tests2filter/038.phpt.

















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
Test scalar, array
--FILE--
<?php

$var = 12;
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL));
var_dump($res);

$var = array(12);
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL));
var_dump($res);

$var = 12;
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_FORCE_ARRAY));
var_dump($res);



$var = 12;
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY));
var_dump($res);

$var = array(12);
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY));
var_dump($res);

$var = array(12);
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_FORCE_ARRAY|FILTER_REQUIRE_ARRAY));
var_dump($res);

$var = array(12);
$res = filter_var($var, FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_FORCE_ARRAY));
var_dump($res);

?>
--EXPECT--
int(12)
bool(false)
array(1) {
  [0]=>
  int(12)
}
bool(false)
array(1) {
  [0]=>
  int(12)
}
array(1) {
  [0]=>
  int(12)
}
array(1) {
  [0]=>
  int(12)
}

Added doc/tests2filter/LICENSE.









>
>
>
>
1
2
3
4
Copyright (c) 1997-2006 The PHP Group
Rasmus Lerdorf, Derick Rethans, Pierre-Alain Joye, Ilia Alshanetsky
PHP license v3.01
http://www.php.net/license/3_01.txt

Added doc/tests2filter/bug7586.phpt.











































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
input_get_args() filter not reseted between elements
--FILE--
<?php
$data = array(
    'product_id'    => 'libgd<script>',
    'component'     => '10dhsajkkdhk <do>',
    'versions'      => '2.0.33',
    'testscalar'    => array('2','23','10','12'),
    'testarray'     => '2',
);

$args = array(
    'product_id'    => FILTER_SANITIZE_ENCODED,
    'component'     => array('flags'    => FILTER_FORCE_ARRAY,
                             'options'  => array("min_range"=>1, "max_range"=>10)
                        ),
    'versions'      => array(
                            'filter' => FILTER_SANITIZE_ENCODED,
                            'flags'  => FILTER_REQUIRE_SCALAR,
                            ),
    'doesnotexist'  => FILTER_VALIDATE_INT,
    'testscalar'    => FILTER_VALIDATE_INT,
    'testarray' => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_FORCE_ARRAY,
                        )

);
$out = filter_var_array($data, $args);
var_dump($out);
?>
--EXPECTF--	
array(6) {
  ["product_id"]=>
  string(17) "libgd%3Cscript%3E"
  ["component"]=>
  array(1) {
    [0]=>
    string(17) "%s"
  }
  ["versions"]=>
  string(6) "2.0.33"
  ["doesnotexist"]=>
  NULL
  ["testscalar"]=>
  bool(false)
  ["testarray"]=>
  array(1) {
    [0]=>
    int(2)
  }
}

Added doc/tests2filter/bug7715.phpt.



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
--TEST--
bug 7715, floats value with integer or incomplete input
--FILE--
<?php
$data = array(
	'.23',
	'-42',
	'+42',
	'.4',
	'-.4',
	'1000000000000',
	'-1000000000000',
	'02.324'
);
foreach ($data as $val) {
	$res = filter_var($val, FILTER_VALIDATE_FLOAT);
	var_dump($res);
}
echo "\n";
?>
--EXPECTF--	
float(0.23)
float(-42)
float(42)
float(0.4)
float(-0.4)
float(1.0E+12)
float(-1.0E+12)
float(2.324)

Added doc/tests2filter/bug8315.phpt.



























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
--TEST--
bug 8315, NULL values halt the validation 
--FILE--
<?php

$var="3".chr(0)."foo";
var_dump(filter_var($var, FILTER_VALIDATE_INT));
$var="3".chr(0)."foo";
var_dump(filter_var($var, FILTER_VALIDATE_FLOAT));
?>
--EXPECT--	
bool(false)
bool(false)

Added doc/tests2filter/callback_non_modified_var.phpt.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
--TEST--
callback function returns non modified value
--FILE--
<?php
function callback($var) {
	return $var;
}
$var = "test";
var_dump(filter_var($var, FILTER_CALLBACK, array('options'=>'callback')));
?>
--EXPECT--	
string(4) "test"

Added doc/updoc.















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/php -qC
<?php
/*
   Adds hints about emulation functions to your local PHP documentation.
*/

#-- help
if ($_SERVER["argc"] < 2) {

   echo<<<END

Usage: updoc [.../upgrade.php] /path/to/your/php-doc/directory/
 
   This script will update your PHP documentation, if you have the
   (DocBook-converted) multi-html-files version installed. The first
   parameter must be the filepath to the 'upgrade.php' script, so the
   names of the emulated functions are known.

   You will afterwards find the abbreviation "EMU" in the required-
   PHP-version line throughout the documentation, so you know which
   functions you could safely use from now on (= without backwards
   compatibility stomach aches).


END;

}

#-- run
else {
   error_reporting(0);

   #-- params
   $emu = $_SERVER["argv"][1];
   $dir = $_SERVER["argv"][2];
   if (!$dir) {
      $dir = $emu;
      $emu = dirname(__FILE__)."/../upgrade.php";
   }
   if (!is_dir($dir)) {
      die("The given 'PHP doc directory' of \"$dir\" isn't!\n");
   }
   if (!file_exists($emu)) {
      die("Couldn't find 'upgrade.php' script under the given name \"$emu\".\n");
   }
   include($emu);
   
   #-- grep for function definitions
   $text = file_get_contents($emu);
   if (preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu)) {
      $list = $uu[1];
   }
   
   #-- go thru doc
   if ($list) {
      $chng = 0;
      foreach ($list as $func) {
      
         #-- doc filename
         if (file_exists($fn = "$dir/function.".strtr($func, "_", "-").".html")) {
            $html = file_get_contents($fn);
            
            #-- update if no hint found yet
            if (!preg_match('/\(.*?(EMU|UP).*?\)/i', $html)) {
               $l = strpos($html, ")"); 
               $html = substr($html, 0, $l)
                     . ", EMU"
                     . substr($html, $l);
               file_put_contents($fn, $html);
               
               $chng += 1;
            }
         }
      }
      
      echo "$chng documentation files updated.\n";
   }

   #-- add some special files
   $add_files = array(
      array(
         "func"=>"gzdecode",
         "text"=>"PGh0bWw+PGhlYWQ+PHRpdGxlPmd6ZGVjb2RlPC90aXRsZT48L2hlYWQ+Cjxib2R5Pgo8ZGl2IGFsaWduPSJjZW50ZXIiPnVwZ3JhZGUucGhwIGRvYzwvZGl2Pgo8dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iMTAwJSIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj48dHI+CiAgPHRkIGFsaWduPSJsZWZ0Ij48YSBocmVmPSJmdW5jdGlvbi5nemRlZmxhdGUuaHRtbCI+YmFjazwvYT48L3RkPgogIDx0ZCBhbGlnbj0icmlnaHQiPjxhIGhyZWY9ImZ1bmN0aW9uLmd6ZW5jb2RlLmh0bWwiPm5leHQ8L2E+PC90ZD4KPC90cj48L3RhYmxlPgo8aHIgYWxpZ249IkxFRlQiIHdpZHRoPSIxMDAlIj4KCjxoMT5nemRlY29kZTwvaDE+Cgo8cD4oUEhQIDYsIEVNVSk8L3A+CgpnemRlY29kZSZuYnNwOy0tJm5ic3A7RGVjb2RlcyBhIGd6aXAgY29tcHJlc3NlZCBzdHJpbmc8L2Rpdj4KCjxoMj5EZXNjcmlwdGlvbjwvaDI+CgpzdHJpbmcgPGIgY2xhc3M9Im1ldGhvZG5hbWUiPmd6ZGVjb2RlPC9iPiAoIHN0cmluZyBkYXRhIFssIGludCBtYXhsZW5dKTxicj4KPGJyPgo8cD5UaGlzIGZ1bmN0aW9uIGRlY29kZXMgYSBzdHJpbmcgY29tcHJlc3NlZCBieSB0aGUgCjxhIGhyZWY9ImZpbGU6Ly8vdXNyL3NoYXJlL21hbi9tYW4xL2d6aXAuMS5neiI+Z3ppcCgxKTwvYT4gdXRpbGl0eSBvcgp0aGUgPGEgY2xhc3M9ImZ1bmN0aW9uIiBocmVmPSJmdW5jdGlvbi5nemVuY29kZS5odG1sIj5nemVuY29kZSgpPC9hPgpmdW5jdGlvbi4gVGhlIG9wdGlvbmFsIHBhcmFtZXRlciAnbWF4bGVuJyBsaW1pdHMgdGhlIGxlbmd0aCBvZiB0aGUgcmV0dXJuZWQKc3RyaW5nIC0gaWYgdGhlIGluZmxhdGlvbiBwcm9jZXNzIHJldHVybmVkIGEgYmlnZ2VyIHJlc3VsdCBpdCB3b3VsZCBiZSBkcm9wcGVkLgo8L3A+Cgo8cD5UaGUgZ3ppcCBmb3JtYXQgaW50ZXJuYWxseSB1c2VzIHRoZSBkZWZsYXRlIGFsZ29yaXRobSwgYW5kIGFkZHMgYSBmZXcKY2hlY2tzdW1zIGFuZCBvcHRpb25hbCBtZXRhIGRhdGEgZmllbGRzLiBJdCBpcyByZWd1bGFyaWx5IHVzZWQgYXMKY29udGVudC1jb2RpbmcgaW4gSFRUUCByZXF1ZXN0cyBhbmQgcmVzcG9uc2VzLiBTZWUKPGEgaHJlZj0iaHR0cDovL3d3dy5mYXFzLm9yZy9yZmNzL3JmYzE5NTIiPlJGQzE5NTI8L2E+IGZvciB0aGUgZm9ybWF0CmRlc2NyaXB0aW9uLjwvcD4KCjxwPgpTZWUgYWxzbyA8YSBocmVmPSJmdW5jdGlvbi5nemVuY29kZS5odG1sIj48YiBjbGFzcz0iZnVuY3Rpb24iPmd6ZW5jb2RlKCk8L2I+PC9hPgphbmQgPGEgaHJlZj0iZnVuY3Rpb24uZ3ppbmZsYXRlLmh0bWwiPjxiIGNsYXNzPSJmdW5jdGlvbiI+Z3ppbmZsYXRlKCk8L2I+PC9hPi4KPC9wPgoKPHA+Rm9yIGNvbXBhdGliaWxpdHkgd2l0aCBvbGRlciBQSFAgdmVyc2lvbnMgKGFuZCBmb3IgcGVvcGxlIHRoYXQgYXJlCnVud2lsbGluZyB0byBsb2FkICd1cGdyYWRlLnBocCcpLCB5b3UgY2FuIHVzZSBmb2xsb3dpbmcgKHVuY2xlYW4pCndvcmthcm91bmQgZm9yIGRlY29tcHJlc3NpbmcgZ3ppcGVkIGRhdGE6PGJyPgo8YnI+CjxiPkV4YW1wbGUgMTwvYj46PGJyPgo8YnI+Cjxjb2RlPgombmJzcDsgICRnemRhdGEgPSBnemVuY29kZSgiSSdtIGdldHRpbmcgY29tcHJlc3NlZC4uLiIpOzxicj4KPGJyPgombmJzcDsgICRzdHIgPSBmdW5jdGlvbl9leGlzdHMoImd6ZGVjb2RlIik8YnI+CiZuYnNwOyAmbmJzcDsgJm5ic3A7ICA/IGd6ZGVjb2RlKCRnemRhdGEpPGJyPgombmJzcDsgJm5ic3A7ICZuYnNwOyAgOiBnemluZmxhdGUoc3Vic3RyKCRnemRhdGEsIDEwLCAtOCkpOzxicj4KPGJyPgo8L2NvZGU+CjwvcD4KCjxocj4KPHRhYmxlIGJvcmRlcj0iMCIgd2lkdGg9IjEwMCUiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRyPgogIDx0ZCB3aWR0aD0iMzMlIiBhbGlnbj0ibGVmdCI+PGEgaHJlZj0iZnVuY3Rpb24uZ3pkZWZsYXRlLmh0bWwiPmJhY2s8L2E+PGJyPmd6ZGVmbGF0ZTwvdGQ+CiAgPHRkIHdpZHRoPSIzMyUiIGFsaWduPSJjZW50ZXIiPjxhIGhyZWY9InJlZi56bGliLmh0bWwiPnVwPC9hPjxicj56bGliIG92ZXJ2aWV3PC90ZD4KICA8dGQgd2lkdGg9IjMzJSIgYWxpZ249InJpZ2h0Ij48YSBocmVmPSJmdW5jdGlvbi5nemVuY29kZS5odG1sIj5uZXh0PC9hPjxicj5nemVuY29kZTwvdGQ+CjwvdHI+PC90YWJsZT4KCjwvYm9keT4KPC9odG1sPgo=",
         "sect"=>"zlib", "after"=>"gzencode",
         "desc"=>"Decode a gzip compressed string",
      ),
   );
   foreach ($add_files as $data) {
      extract($data);
      if (!file_exists($fn = "$dir/function.$func.html")
||1) {
         echo "adding \"$fn\"\n";
         file_put_contents($fn, base64_decode($text));

         #-- update function list page
         $fn = array("$dir/ref.$sect.html", "$dir/index.functions.html");
         update_files($fn, "/(<a\s+href=\"function.$after)/ims",
            "<a href=\"function.$func.html\">$func</a> -- $desc.</dt>\n<dt> $1"
         ); 
      }
   }

}


#-- inject something into a file
function update_files($list, $regex, $replace) {
   if (!is_array($list)) {
      $list = array($list);
   }
   foreach ($list as $fn) {
echo "+$fn\n";
      $html = file_get_contents($fn);
      $html = preg_replace($regex, $replace, $html);
      file_put_contents($fn, $html);
   }
}

?>

Deleted dtools/_dt.

1
2
3
4
5
6
7
8
#!/bin/sh
# runs the `doctests` utility for a given (param) function,
# simply has some custom pathnames built-in
MAN=/usr/local/doc/php5-doc/
PHP=php412

DIR=$(dirname $(dirname $(realpath $0)))
$DIR/dtools/doctests $PHP $MAN $@
<
<
<
<
<
<
<
<
















Deleted dtools/_notdefined.

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

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






Deleted dtools/ckavail.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
<?php
/*
   Run this first with an older PHP interpreter, and then with a newer
   version. This way you get a list (once) of added functions (the func
   list is stored in a temporary file).
*/
$DATA_FILE = "/tmp/ckavail.lst";

#-- load previous list
if ($f = @fopen($DATA_FILE, "rb")) {
   $oldl = unserialize(fread($f, 1<<20));
   fclose($f);
}
//echo "OLD=";print_r($oldl);

#-- current func list
$newl = get_defined_stuff();
//echo "NEW=";print_r($newl);

#-- save this one
if ($f = fopen($DATA_FILE, "wb")) {
   fwrite($f, serialize($newl));
   fclose($f);
}
else {
   echo "ERROR(could not save current list)\n";
}

#-- comparison of  current / last run
echo "old(".count($oldl["functions"])."), new(".count($newl["functions"]).")\n";
if ($oldl) {

   #-- funcs
   $new = array_diff($newl["functions"], $oldl["functions"]);
   echo "New functions added between PHP $oldl[version] and current $newl[version] interpreter:\n";
   print_r($new);

   #-- constants
   $new = array_diff(array_keys($newl["constants"]), array_keys($oldl["constants"]));
   echo "\nNewly added constants:\n";
   print_r($new);

   #-- classes
   $new = array_diff($newl["classes"], $oldl["classes"]);
   echo "\nAnd classes:\n";
   print_r($new);

}
else {
   echo "Now start this script a 2nd time with the newer interpreter version.\n";
}


function get_defined_stuff() {
   $rl = array();
   $f = get_defined_functions();
   while ($f["internal"]) {
      $f = $f["internal"];
   }
   $rl["functions"] = $f;
   $c = get_defined_constants();
   $rl["constants"] = $c;
   $c = get_declared_classes();
   $rl["classes"] = $c;
   $rl["version"] = PHP_VERSION;
   return($rl);
}


?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































Deleted dtools/compact.

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh

#
#  creates comment+whitespace free version of upgrade.php script
#

cd `dirname $0`
cd ..

php -q -w upgrade.php | perl -pe 's/\s*([{}()\[\]=\-\/\$<>+*",;!&|])\s*|\n/$1/gmis;' > contrib/upgrade.php.shortened

ls -l upgrade.php contrib/upgrade.php*
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted dtools/doctests.

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
#!/usr/local/bin/php -qC
<?php
/*
   Makes small test scripts, which get extracted from the PHP manual
   on the fly (but not every function has one there, suddenly).
*/

#-- config
$PAUSE = 1;   // (use 3) break between tests; you should use `|less` instead
$CLEAN = 0;   // remove test scripts after use
$MANY = 1;    // create one testing script per function


#-- help
if (count($_SERVER["argv"]) < 3) {
   echo<<<END

Usage: doctest  [php-interpreter]  [/path/to/your/php/manual/]

   Runs the examples from your locally installed PHP manual (any language
   will work, but get the latest!) with the given PHP interpreter version
   (use an older version to really test the emulated functions). You need
   lynx or w3m installed also. Use only under U*ix/Linux.

   Pipe the output through |less, |more or |most, there are built-in
   delays. Rarely example scripts may not run (they are examples only).

END;
}

#-- proceed
else {

   #-- args
   $php = $_SERVER["argv"][1];
   $php = trim(`which $php`);
   if (!$php) {
      die(__FILE__.": Given PHP interpreter not in your %PATH!\n");
   }
   $dir = $_SERVER["argv"][2];
   if (!is_dir($dir) || !file_exists("$dir/function.print.html")) {
      die(__FILE__.": PHP manual does not live under '$dir'.\n");
   }
   ($html = `which w3m`) or ($html = `which lynx`);
   if (!($html = trim($html))) {
      die(__FILE__.": lynx or w3m required.\n");
   }
   $tmp = "/tmp/upgrade.php.doctest.tmp";
   $tmpdir = $tmp;
   if ($MANY) { @unlink($tmpdir); @mkdir($tmpdir); }

   #-- load emulation script
   $emu = realpath(dirname(__FILE__) . "/../upgrade.php");
   $emu2 = dirname($emu)."/ext/array.php";
   $emu3 = dirname($emu)."/ext/mime.php";
   require($emu);

   #-- get function names
   $text = file_get_contents($emu);
   preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu);
   $funcs = $uu[1];
   #-- or use user-specified list
   if (count($_SERVER["argv"]) >= 4) {
      $funcs = array_slice($_SERVER["argv"], 3);
   }

   #-- generate list of really emulated functions
   $simulated = `echo '<?php echo serialize(get_defined_functions()); ?>' | $php -q`;
   $simulated = unserialize($simulated);
   $simulated = $simulated["internal"];

   #-- all
   foreach ($funcs as $func) {
      if (file_exists($fn = "$dir/function.".strtr($func, "_", "-").".html")) {
         echo "checking function '\033[31m$func\033[37m'... ";

         #-- only run over emulated stuff
         if (in_array($func, $simulated)) {
            echo "NOT EMULATED (with your PHP version)... ";
            // continue;
         }

         #-- grep example scripts
         $text = `$html -dump $fn`;
         preg_match_all("/<\?php(.+?)\?".">/ms", $text, $uu);

         #-- exec each
         if ($n = count($uu[1])) {

            #-- note
            echo "$n examples:\n\n";

            #-- multiple scripts to run
            foreach ($uu[1] as $i=>$scr) {

               #-- fix output-less scripts: find last assigned-to variable name
               if (!strpos($scr, "echo") && !strpos($scr, "print")) {
                  if (preg_match('/^.+(\$[_\w\d\[\"\'\]]+)\s*=/s', $scr, $uu)) {
                     $scr .= "\n\n#-- auto-added\nprint_r($uu[1]);\n";
                  }
                  else {
                     $scr .= "\n\n#-- this script gives no useful output, or does it?";
                  }
               }

               #-- fix compatibility to older PHP versions
               $scr = preg_replace('/(\s)private(\s\$)/', '$1var$2', $scr);

               #-- output sample script text from doc
               if ($i) {
                  echo "\n++++++++++++++++++++++++++++\n\n";
                  sleep($PAUSE);
               }
               echo "\033[1;30m<?php $scr\n?".">\033[0;37m\n";

               #-- create temp script, run it
               if ($MANY) {
                  $tmp = "$tmpdir/$func#$i.php";
               }
               $scr = ltrim($scr);
               file_put_contents(
                  $tmp,
                  "<?php\n\n".
                  "#-- a test script for emulated function '$func'\n".
                  "if (function_exists('$func')) { echo \"ATTENTION: the native '$func' function will engage for this test\\n\"; }\n".
                  "include('$emu');\n".
                  "include('$emu2');\n".
                  "include('$emu3');\n".
                  "error_reporting(E_ALL);\n\n".
                  "#-- example[$i] as taken from PHP manual page '$fn'\n".
                  "$scr\n".
                  "\n?".">"
               );
               echo "==>\033[32m\n";
               passthru("$php $tmp");
               echo "\033[0;37m\n\n";
            }

            #-- pause before next func/script
            sleep($PAUSE);
            echo "\n-------------------------------------------------------------------\n\n";
         }

         else {
            echo "NO EXAMPLES found in doc, skipping";
         }
         echo "\n";
      }
   }

   #-- clean up
   if ($CLEAN) {
      unlink($tmp);
   }
}

#-- even more clean
if ($MANY && CLEAN) { @rmdir($tmpdir); }

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































Deleted dtools/listemu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/local/bin/php -qC
<?php
/*
   Prints the list of emulated functions.
*/

#-- basedir
$dir = realpath(dirname(__FILE__) . "/../");

#-- grep for function definitions
$text = "";
$text .= implode("", file("$dir/upgrade.php"));
$text .= implode("", file("$dir/ext/array.php"));
$text .= implode("", file("$dir/ext/bcmath.php"));
$text .= implode("", file("$dir/ext/gettext.php"));
$text .= implode("", file("$dir/ext/mime.php"));
$text .= implode("", file("$dir/ext/old.php"));
$text .= implode("", file("$dir/ext/posix.php"));
$text .= implode("", file("$dir/ext/ctype.php"));
$text .= implode("", file("$dir/ext/odbc.php"));
if (preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu)) {
   $list = array_unique($uu[1]);
}

#-- print
echo "Following functions can be emulated currently:\n";
foreach ($list as $func) {
   echo "· $func\n";
}

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































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

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































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


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































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




























































































































































































































































Deleted dtools/php-commandline/phpecho.

1
2
3
#!/bin/sh

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






Deleted dtools/updoc.

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
#!/usr/local/bin/php -qC
<?php
/*
   Adds hints about emulation functions to your local PHP documentation.
*/

#-- help
if ($_SERVER["argc"] < 2) {

   echo<<<END

Usage: updoc [.../upgrade.php] /path/to/your/php-doc/directory/
 
   This script will update your PHP documentation, if you have the
   (DocBook-converted) multi-html-files version installed. The first
   parameter must be the filepath to the 'upgrade.php' script, so the
   names of the emulated functions are known.

   You will afterwards find the abbreviation "EMU" in the required-
   PHP-version line throughout the documentation, so you know which
   functions you could safely use from now on (= without backwards
   compatibility stomachaches).


END;

}

#-- run
else {
   error_reporting(0);

   #-- params
   $emu = $_SERVER["argv"][1];
   $dir = $_SERVER["argv"][2];
   if (!$dir) {
      $dir = $emu;
      $emu = dirname(__FILE__)."/../upgrade.php";
   }
   if (!is_dir($dir)) {
      die("The given 'PHP doc directory' of \"$dir\" isn't!\n");
   }
   if (!file_exists($emu)) {
      die("Couldn't find 'upgrade.php' script under the given name \"$emu\".\n");
   }
   
   #-- grep for function definitions
   $text = implode("", file($emu));
   if (preg_match_all("/function[ ]+([_\w\d]+)\s*\(/", $text, $uu)) {
      $list = $uu[1];
   }
   
   #-- go thru doc
   if ($list) {
      $chng = 0;
      foreach ($list as $func) {
      
         #-- doc filename
         if (file_exists($fn = "$dir/function.".strtr($func, "_", "-").".html")) {
            $f = fopen($fn, "r");
            $html = fread($f, 1<<20);
            fclose($f);
            
            #-- update if no hint found yet
            if (!preg_match('/\(.*?(EMU|UP).*?\)/i', $html)) {
               $l = strpos($html, ")"); 
               $html = substr($html, 0, $l)
                     . ", EMU"
                     . substr($html, $l);
               $f = fopen($fn, "w");
               fwrite($f, $html);
               fclose($f);
               
               $chng += 1;
            }
         }
      }
      
      echo "$chng documentation files updated.\n";
   }

   #-- add some special files
   $add_files = array(
      array(
         "func"=>"gzdecode",
         "data"=>"PGh0bWw+PGhlYWQ+PHRpdGxlPmd6ZGVjb2RlPC90aXRsZT48L2hlYWQ+Cjxib2R5Pgo8ZGl2IGFsaWduPSJjZW50ZXIiPnVwZ3JhZGUucGhwIGRvYzwvZGl2Pgo8dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iMTAwJSIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj48dHI+CiAgPHRkIGFsaWduPSJsZWZ0Ij48YSBocmVmPSJmdW5jdGlvbi5nemRlZmxhdGUuaHRtbCI+YmFjazwvYT48L3RkPgogIDx0ZCBhbGlnbj0icmlnaHQiPjxhIGhyZWY9ImZ1bmN0aW9uLmd6ZW5jb2RlLmh0bWwiPm5leHQ8L2E+PC90ZD4KPC90cj48L3RhYmxlPgo8aHIgYWxpZ249IkxFRlQiIHdpZHRoPSIxMDAlIj4KCjxoMT5nemRlY29kZTwvaDE+Cgo8cD4oUEhQIDYsIEVNVSk8L3A+CgpnemRlY29kZSZuYnNwOy0tJm5ic3A7RGVjb2RlcyBhIGd6aXAgY29tcHJlc3NlZCBzdHJpbmc8L2Rpdj4KCjxoMj5EZXNjcmlwdGlvbjwvaDI+CgpzdHJpbmcgPGIgY2xhc3M9Im1ldGhvZG5hbWUiPmd6ZGVjb2RlPC9iPiAoIHN0cmluZyBkYXRhIFssIGludCBtYXhsZW5dKTxicj4KPGJyPgo8cD5UaGlzIGZ1bmN0aW9uIGRlY29kZXMgYSBzdHJpbmcgY29tcHJlc3NlZCBieSB0aGUgCjxhIGhyZWY9ImZpbGU6Ly8vdXNyL3NoYXJlL21hbi9tYW4xL2d6aXAuMS5neiI+Z3ppcCgxKTwvYT4gdXRpbGl0eSBvcgp0aGUgPGEgY2xhc3M9ImZ1bmN0aW9uIiBocmVmPSJmdW5jdGlvbi5nemVuY29kZS5odG1sIj5nemVuY29kZSgpPC9hPgpmdW5jdGlvbi4gVGhlIG9wdGlvbmFsIHBhcmFtZXRlciAnbWF4bGVuJyBsaW1pdHMgdGhlIGxlbmd0aCBvZiB0aGUgcmV0dXJuZWQKc3RyaW5nIC0gaWYgdGhlIGluZmxhdGlvbiBwcm9jZXNzIHJldHVybmVkIGEgYmlnZ2VyIHJlc3VsdCBpdCB3b3VsZCBiZSBkcm9wcGVkLgo8L3A+Cgo8cD5UaGUgZ3ppcCBmb3JtYXQgaW50ZXJuYWxseSB1c2VzIHRoZSBkZWZsYXRlIGFsZ29yaXRobSwgYW5kIGFkZHMgYSBmZXcKY2hlY2tzdW1zIGFuZCBvcHRpb25hbCBtZXRhIGRhdGEgZmllbGRzLiBJdCBpcyByZWd1bGFyaWx5IHVzZWQgYXMKY29udGVudC1jb2RpbmcgaW4gSFRUUCByZXF1ZXN0cyBhbmQgcmVzcG9uc2VzLiBTZWUKPGEgaHJlZj0iaHR0cDovL3d3dy5mYXFzLm9yZy9yZmNzL3JmYzE5NTIiPlJGQzE5NTI8L2E+IGZvciB0aGUgZm9ybWF0CmRlc2NyaXB0aW9uLjwvcD4KCjxwPgpTZWUgYWxzbyA8YSBocmVmPSJmdW5jdGlvbi5nemVuY29kZS5odG1sIj48YiBjbGFzcz0iZnVuY3Rpb24iPmd6ZW5jb2RlKCk8L2I+PC9hPgphbmQgPGEgaHJlZj0iZnVuY3Rpb24uZ3ppbmZsYXRlLmh0bWwiPjxiIGNsYXNzPSJmdW5jdGlvbiI+Z3ppbmZsYXRlKCk8L2I+PC9hPi4KPC9wPgoKPHA+Rm9yIGNvbXBhdGliaWxpdHkgd2l0aCBvbGRlciBQSFAgdmVyc2lvbnMgKGFuZCBmb3IgcGVvcGxlIHRoYXQgYXJlCnVud2lsbGluZyB0byBsb2FkICd1cGdyYWRlLnBocCcpLCB5b3UgY2FuIHVzZSBmb2xsb3dpbmcgKHVuY2xlYW4pCndvcmthcm91bmQgZm9yIGRlY29tcHJlc3NpbmcgZ3ppcGVkIGRhdGE6PGJyPgo8YnI+CjxiPkV4YW1wbGUgMTwvYj46PGJyPgo8YnI+Cjxjb2RlPgombmJzcDsgICRnemRhdGEgPSBnemVuY29kZSgiSSdtIGdldHRpbmcgY29tcHJlc3NlZC4uLiIpOzxicj4KPGJyPgombmJzcDsgICRzdHIgPSBmdW5jdGlvbl9leGlzdHMoImd6ZGVjb2RlIik8YnI+CiZuYnNwOyAmbmJzcDsgJm5ic3A7ICA/IGd6ZGVjb2RlKCRnemRhdGEpPGJyPgombmJzcDsgJm5ic3A7ICZuYnNwOyAgOiBnemluZmxhdGUoc3Vic3RyKCRnemRhdGEsIDEwLCAtOCkpOzxicj4KPGJyPgo8L2NvZGU+CjwvcD4KCjxocj4KPHRhYmxlIGJvcmRlcj0iMCIgd2lkdGg9IjEwMCUiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRyPgogIDx0ZCB3aWR0aD0iMzMlIiBhbGlnbj0ibGVmdCI+PGEgaHJlZj0iZnVuY3Rpb24uZ3pkZWZsYXRlLmh0bWwiPmJhY2s8L2E+PGJyPmd6ZGVmbGF0ZTwvdGQ+CiAgPHRkIHdpZHRoPSIzMyUiIGFsaWduPSJjZW50ZXIiPjxhIGhyZWY9InJlZi56bGliLmh0bWwiPnVwPC9hPjxicj56bGliIG92ZXJ2aWV3PC90ZD4KICA8dGQgd2lkdGg9IjMzJSIgYWxpZ249InJpZ2h0Ij48YSBocmVmPSJmdW5jdGlvbi5nemVuY29kZS5odG1sIj5uZXh0PC9hPjxicj5nemVuY29kZTwvdGQ+CjwvdHI+PC90YWJsZT4KCjwvYm9keT4KPC9odG1sPgo=",
         "sect"=>"zlib", "after"=>"gzencode",
         "desc"=>"Decode a gzip compressed string",
      ),
   );
   foreach ($add_files as $data) {
      extract($data);
      if (!file_exists($fn = "$dir/function.$func.html")
||1) {
         echo "adding \"$fn\"\n";
         $f = fopen($fn, "w");
         fwrite($f, base64_decode($data));
         fclose($f);

         #-- update function list page
         $fn = array("$dir/ref.$sect.html", "$dir/index.functions.html");
         update_files($fn, "/(<a\s+href=\"function.$after)/ims",
            "<a href=\"function.$func.html\">$func</a> -- $desc.</dt>\n<dt> $1"
         ); 
      }
   }

}


#-- inject something into a file
function update_files($list, $regex, $replace) {
   if (!is_array($list)) {
      $list = array($list);
   }
   foreach ($list as $fn) {
echo "+$fn\n";
      $f = fopen($fn, "r");
      $html = fread($f, 1<<20);
      fclose($f);
      $html = preg_replace($regex, $replace, $html);
      $f = fopen($fn, "w");
      fwrite($f, $html);
      fclose($f);
   }
}

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































Changes to ext/array.php.

1
2

3
4
5
6
7
8
9






10
11
12
13
14
15
16
17
<?php
/*

   Extended PHP array functions - _diff and _intersect() for associative
   arrays and/or with callback functions (for keys and/or values). These
   are too rarely used and exotic to be part of the core "upgrade.php"
   script.
   
   NOTHING IN HERE WAS SERIOUSLY TESTED. Please grab the definitions from
   "PEAR::PHP_Compat" if you want reliable and tested versions.






*/


#-- diff associative arrays with two user callbacks
#   (if this looks complicated to you, don't even try to look at the manual)
if (!function_exists("array_udiff_uassoc")) {
   function array_udiff_uassoc() {
      $in = func_get_args();

|
>
|
|
|
|
|
|
|
>
>
>
>
>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/**
 *
 *  Extended PHP array functions - _diff and _intersect() for associative
 *  arrays and/or with callback functions (for keys and/or values). These
 *  are too rarely used and exotic to be part of the core "upgrade.php"
 *  script.
 *  
 *  NOTHING IN HERE WAS SERIOUSLY TESTED. Please grab the definitions from
 *  PEAR::PHP_Compat if you want reliable and tested versions.
 *
 *
 *  @group ARRAY_FUNCS_4_0
 *  @since 4.0
 *  @untested
 *
 */


#-- diff associative arrays with two user callbacks
#   (if this looks complicated to you, don't even try to look at the manual)
if (!function_exists("array_udiff_uassoc")) {
   function array_udiff_uassoc() {
      $in = func_get_args();

Deleted ext/base64.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
/*
   This script implements the base64-encoding functions and base32 and
   base16 as described in RFC3548.
*/
if (!function_exists("base16_encode")) {


   #-- URL and filename safe variants of base64-encoding
   function base64_encode_safe($str) {
      return strtr(base64_encode($str), "+/", "-_");
   }
   function base64_decode_safe($b64) {
      return base64_decode(strtr($str, "-_", "+/"));
   }


   #-- base16
   function base16_encode($str) {
      $str = unpack("H".(2*strlen($str)), $str);
      $str = chunk_split($str[1]);
      return($str);
   }
   function base16_decode($b16) {
      $b16 = preg_replace("/\s+/", '', $b16);
      $b16 = pack("H*", $b16);
      return($b16);
   }


   #-- base32
   function base32_encode() {
      
      # strtoupper()
      # "A-Z,0-7,="
   }

}
?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































Changes to ext/bcmath.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
<?php
/*

   Emulates mathematical functions with arbitrary precision (bcmath)
   using POSIX systems 'dc' utility or either GMP or PHPs bigint
   extension module as fallback (were faster, but wouldn't allow to

   set precisions).

*/


#-- BSD/Linux dc(1)
if (!function_exists("bcadd") && is_executable("/usr/bin/dc")) {

   #-- invokes commandline 'dc' utility (faster than with 'bc')
   #   (later version should use proc_open() for safer and faster bi-directional I/O)
   function dc___exec($calc, $scale=NULL) {








      global $bc___scale;


      #-- assemble dc expression
      $calc = str_replace(' -', ' _', $calc);  // convert minus signs for dc
      if (isset($scale) || ($scale = $bc___scale)) {
         $calc = ((int)$scale) . "k" . $calc;  // inject precision directive
      }
      $calc = escapeshellarg($calc);   // could be non-integer from elsewhere
      
      #-- prevent any command execution from within dc
      # (for speed reasons we don't assert parameters to be fully numeric)
      if (strpos($calc, "!")) { return; }

      #-- do
      return str_replace("\\\n", "", `/usr/bin/dc -e $calc`);
   }

   #-- global state variable
   $GLOBALS["bc___scale"] = 0;  //ini_get("bcmath.scale");  // =0
   function bcscale($scale=NULL) {

      $GLOBALS["bc___scale"] = $scale;
   }

   #-- wrapper calls
   function bcadd($a, $b, $scale=NULL) {
      return dc___exec(" $a $b +nq", $scale);
   }
   function bcsub($a, $b, $scale=NULL) {

|
>
|
|
<
>
|
>
|








>
>
>
>
>
>
>
>
|
>



<
|
<
|


|







<
|
>
|







1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31

32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
<?php
/**
 *
 *  Emulates mathematical functions with arbitrary precision (bcmath)
 *  using POSIX systems 'dc' utility. Cannot work in PHP 'safe mode'.

 * 
 *  @requires realmode
 *
 */


#-- BSD/Linux dc(1)
if (!function_exists("bcadd") && is_executable("/usr/bin/dc")) {

   #-- invokes commandline 'dc' utility (faster than with 'bc')
   #   (later version should use proc_open() for safer and faster bi-directional I/O)
   function dc___exec($calc, $scale=NULL) {
      static $saved_scale=0;
      
      #-- bcscale() set
      if ($calc=="SETSCALE") {
         $saved_scale = (int)$scale;
         return;
      }
      elseif (!isset($scale)) {
         $scale = $saved_scale;
      }

      #-- assemble dc expression
      $calc = str_replace(' -', ' _', $calc);  // convert minus signs for dc

      $calc = $scale . "k" . $calc;    // inject precision directive

      $calc = escapeshellarg($calc);   // could contain non-integers from elsewhere
      
      #-- prevent any command execution from within dc
      #   (for speed reasons we don't assert parameters to be fully numeric)
      if (strpos($calc, "!")) { return; }

      #-- do
      return str_replace("\\\n", "", `/usr/bin/dc -e $calc`);
   }

   #-- global state variable

   function bcscale($scale=0) {
      //ini_get("bcmath.scale");  // =0
      dc___exec("SETSCALE", $scale);
   }

   #-- wrapper calls
   function bcadd($a, $b, $scale=NULL) {
      return dc___exec(" $a $b +nq", $scale);
   }
   function bcsub($a, $b, $scale=NULL) {
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
   }
   function bc___scaledown(&$a, $scale) {
      if (isset($scale) && ($dot = strpos($a, $dot))) {
         $a = substr($a, $dot + $scale) . "0";
      }
   }

}//shell version



#-- GMP
if (!function_exists("bcadd") && function_exists("gmp_strval")) {
   function bcadd($a, $b) {
      return gmp_strval(gmp_add($a, $b));
   }
   function bcsub($a, $b) {
      return gmp_strval(gmp_sub($a, $b));
   }
   function bcmul($a, $b) {
      return gmp_strval(gmp_mul($a, $b));
   }
   function bcdiv($a, $b, $precision=NULL) {
      $qr = gmp_div_qr($a, $b);
      $q = gmp_strval($qr[0]);
      $r = gmp_strval($qr[1]);
      if ((!$r) || ($precision===0)) {
         return($q);
      }
      else {
         if (isset($precision)) {
            $r = substr($r, 0, $precision);
         }
         return("$q.$r");
      }
   }
   function bcmod($a, $b) {
      return gmp_strval(gmp_mod($a, $b));
   }
   function bcpow($a, $b) {
      return gmp_strval(gmp_pow($a, $b));
   }
   function bcpowmod($x, $y, $mod) {
      return gmp_strval(gmp_powm($x, $y, $mod));
   }
   function bcsqrt($x) {
      return gmp_strval(gmp_sqrt($x));
   }
   function bccomp($a, $b) {
      return gmp_cmp($a, $b);
   }
   function bcscale($scale="IGNORED") {
      trigger_error("bcscale(): ignored", E_USER_ERROR);
   }
}//gmp emulation



#-- bigint
// @dl("php_big_int".PHP_SHLIB_SUFFIX))
if (!function_exists("bcadd") && function_exists("bi_serialize")) {
   function bcadd($a, $b) {
      return bi_to_str(bi_add($a, $b));
   }
   function bcsub($a, $b) {
      return bi_to_str(bi_sub($a, $b));
   }
   function bcmul($a, $b) {
      return bi_to_str(bi_mul($a, $b));
   }
   function bcdiv($a, $b) {
      return bi_to_str(bi_div($a, $b));
   }
   function bcmod($a, $b) {
      return bi_to_str(bi_mod($a, $b));
   }
   function bcpow($a, $b) {
      return bi_to_str(bi_pow($a, $b));
   }
   function bcpowmod($a, $b, $c) {
      return bi_to_str(bi_powmod($a, $b, $c));
   }
   function bcsqrt($a) {
      return bi_to_str(bi_sqrt($a));
   }
   function bccomp($a, $b) {
      return bi_cmp($a, $b);
   }
   function bcscale($scale="IGNORED") {
      trigger_error("bcscale(): ignored", E_USER_ERROR);
   }
}


?>







<
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

79
80
81
82
83
84
85

86
87
88



















































































89
   }
   function bc___scaledown(&$a, $scale) {
      if (isset($scale) && ($dot = strpos($a, $dot))) {
         $a = substr($a, $dot + $scale) . "0";
      }
   }


}





















































































?>

Added ext/contrib/exceptions.php.























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
/*
   simplistic exception handling for PHP4
   --------------------------------------
   
   As you might know, PHP5 introduced exceptions, similiar to Javas. This
   feature of course cannot be used for PHP4-compatible scripts, and it can
   in no way be emulated by a functional API emulation like "upgrade.php".

   To use an exception-like scheme in PHP4 you'd have to agree on conventions
   - lots of. And exceptions won't look object-oriented anymore and not be
   compliant with the PHP5 scheme - the names are in fact held incompatible
   to avoid conflicts in the language semantics (reserved words).
   

   interfaces
   ----------
  
    - class Exception 
    - global variable $_EXCEPTION (- should better be a list of excptn objs?)
    - _try() function
    - _throw() function
    - _catch() function


   howto
   -----
   
    - prefix a block of commands with _try();
      this will initialize exception handling (evtl. resets internal vars)
    - errors are thrown, by calling _throw() with an Exception-class derived
      object instance as parameter, and returning immediately
    - exceptions are "catched" in if() statements, the _catch() function
      with a classname as parameter returns false or the $_EXCEPTION object
    - you shouldn't use set_exception_handler(), but $_EXCEPTION="funcname";

    #-- main code      
    _try();
    {
       sub_call();
    }
    if ($e = _catch("Special_Case")) {
       echo $e->broken_file();
    }
    if ($e = _catch("Exception")) {
       echo "Something broke, I'd say.";
    }
    
    #-- error-prone
    function sub_call() {
       // ...
       _throw(new Exception("error",255)); return();
    }

    
   note
   ----
   
   Please don't send hatemails only because you feel the syntax is too
   far away from PHP5s native exception handling and counter to that in
   other languages. And the underscores in this agreement are just to
   prevent conflicts with PHP5 constructs - this is not yet another case
   of PHP-underscoritis ;)
   
   -> there has been another PHP framework which implemented exceptions
      long before PHP5 came out; I just don't know anymore which it was
      //@TODO: build a search engine similiar to Google to find that out
*/


#-- base class for exceptions
if (!class_exists("exception")) {
   class Exception
   {
      #-- attributes
      var $message = "";
      var $code = 0;
      var $file = NULL;
      var $line = NULL;
      var $backtrace = NULL;
      
      #-- constructor
      function Exception($message="", $code=0) {
      
         #-- values
         $this->message = $message;
         $this->code = $code;
         
         #-- debugging
         $this->backtrace = debug_backtrace();
         array_shift($this->backtrace);
         $this->file = @$this->backtrace[0]["file"];
         $this->line = @$this->backtrace[0]["line"];
      }
      
      #-- get_ wrappers
      function getMessage() {
         return($this->message);
      }
      function getCode() {
         return($this->code);
      }
      function getFile() {
         return($this->file);
      }
      function getLine() {
         return($this->line);
      }
      function getTrace() {
         return($this->backtrace);
      }
      function getTraceAsString() {
         return(var_export($this->backtrace, TRUE));
      }
      
      #-- output
      function __toString() {
         return($this->message);
      }
   }
}



#-- initialize exception handling for next block
function _try()
{
   global $_EXCEPTION;

   #-- clean up
   if (!is_string($_EXCEPTION) || !function_exists($_EXCEPTION)) {
      $_EXCEPTION = new Object();
   }
}


#-- use for throwing errors
function _throw($obj) {
   global $_EXCEPTION;

   #-- quick
   if (is_string($_EXCEPTION) && function_exists($_EXCEPTION)) {
      $_EXCEPTION($obj);
   }

   #-- what do we do if there's already an exception?
   if ($_EXCEPTION) {
      // ???
      trigger_error("_throw: there is already an unhandled exception on the stack", E_USER_ERROR);
   }

   #-- generate object from error message
   if (!is_object($obj)) {
      $_EXCEPTION = new Exception("$obj");
   }

   #-- pass
   $_EXCEPTION = $obj;

   return(true);
   // break 5;  (after throwing an exception, you should
   //           exit from your current function quickly)
}


#-- check if exception thrown
function &_catch($classname="Exception") {
   global $_EXCEPTION;
   static $e;

   #-- checked for a specific error type / exception class
   if (is_object($_EXCEPTION) && (($classname == "*") || is_a($_EXCEPTION, $classname))) {
      $e = &$_EXCEPTION;   //@FIX: remove reference passing, seems unnecessary
      unset($_EXCEPTION);  // this doesn't clean the global var  [but _try() does]
   }
   else {
      $e = false;
   }

   #-- give out extracted exception   
   return $e;
}


#-- functional additions
if (!function_exists("debug_backtrace")) {
   function debug_backtrace() {
      return array();
   }
}


#-- sets global state
if (!function_exists("set_exception_handler")) {
   // quick hack, should use a different func name
   function set_exception_handler($func) {
      global $_EXCEPTION;
      $_EXCEPTION = $func;
   }
}


?>

Added ext/contrib/fix.php.





















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
/*
  api: PHP
  type: intercept
  title: PHP fixes
  descriptions: removes bogus magic_quotes and left over superglobals
  priority: auto
  category: library
  conflicts: strike_register_globals, strip_wonderful_slashes

   Outdated and bogus PHP settings (register_globals and magic_quotes) are
   defended by this script, so code cannot be negatively impacted. It can
   always be loaded as it doesn't cause problems or speed disadvantages on
   correctly configured servers. THE "PHP.INI" SHOULD BE FIXED PREFERABLY.
*/

 #-- strike register_globals (injected variables)
 if (ini_get("register_globals") == "1") {
    ewiki_recursive_unset($GLOBALS, $_REQUEST);
    ini_set("register_globals", 0);
 }

 #-- strip any \'s if magic_quotes (variable garbaging) is still enabled
 if (ini_get("magic_quotes_gpc") && get_magic_quotes_gpc()) {
    ewiki_recursive_stripslashes($_REQUEST);
    ewiki_recursive_stripslashes($_GET);
    ewiki_recursive_stripslashes($_POST);
    ewiki_recursive_stripslashes($_COOKIE);
    ewiki_recursive_stripslashes($_ENV);
    ewiki_recursive_stripslashes($_SERVER);
    ini_set("magic_quotes_gpc", 0);
 }

 #-- now that one is really dumb
 set_magic_quotes_runtime(0);


 #-- implementation
 function ewiki_recursive_unset(&$TO, $FROM) {
    foreach ($FROM as $var=>$value) {
       if (isset($TO[$var]) && ($TO[$var]==$FROM[$var])) {
          unset($TO[$var]);
          unset($TO[$var]);   // double unset to work around ZE-num/assoc-hashcode bug
       }
    }
 }
 function ewiki_recursive_stripslashes(&$var) {
    if (is_array($var)) {
       foreach ($var as $key=>$item) {
          ewiki_recursive_stripslashes($var[$key]);
       }
    }
    else {
       $var = stripslashes($var);
    }
 }

?>

Added ext/contrib/hiddenerrors.php.



































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
/*
   The error handler provided here will feed all errors and warnings
   into HTTP headers of the form "X-Error-NNNNN: ...", so they can't
   disturb page output or make XML documents invalid. This allows to
   turn on complete error_reporting() without any functionality loss
   due to premature output.
   You of course need a good Web browser that can easily display all
   response headers then for developing.
*/

set_error_handler("ewiki_http_header_errors");
ini_set("html_errors", 0);

function ewiki_http_header_errors($errno, $msg, $file, $line, $lvars) {

   static $error_types = array(
      E_PARSE => "PARSE ERROR",
      E_ERROR => "ERROR",
      E_WARNING => "WARNING",
      E_NOTICE => "NOTICE",
      E_STRICT => "STRICT",
      E_USER_ERROR => "USER ERROR",
      E_USER_WARNING => "USER WARNING",
      E_USER_NOTICE => "USER NOTICE",
   );
   ($errtype = $error_types[$errno]) or ($errtype = "UNDEF ERROR");
   
   #-- check for @ and disabled errors
   $emask = get_cfg_var("error_reporting");
   if (! ($emask & $errno)) {
      return;
   }

   #-- output
   $msg = strtr($msg, "\r\n\t\f", "    ");
   $msg = "$errtype: $msg in $file, line #$line";
   if (headers_sent()) {
      print "\n<!--<div class=\"php-error\">$msg</div>-->\n";
   }
   else {
      $no = crc32($msg);
      $no = ($no & 0xFFFF) ^ ($no >> 16);
      header("X-Error-$no: $msg");
      if ($errno == E_FATAL) { header("Status: 500 Something bad happened"); }
   }
}

?>

Added ext/contrib/http.php.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
<?php
/*
  api: PHP
  type: functions
  category: library
  priority: optional
  provides: http-request
  title: HTTP requests
  description: implements HTTP protocol, various request methods supported
  url: http://freshmeat.net/p/upgradephp
  version: 11.3

   This snippet implements HTTP queries, and allows for most request
   methods, content types and encodings. It is useful for contacting
   scripts made to serve HTML forms.
    - does neither depend upon wget or curl, nor any other extension
    - you can add ->$params (form variables) on the fly, it's a hash
    - if the initial URL contains a query string, the vars will be
      extracted first
    - set the ->$enc very carefully, because many CGI apps and HTTP
      servers can't deal with it (else "gzip" and "deflate" are nice)
    - there are abbreviations for the content ->$type values (namely
      "form" , "url" and "php")
    - user:password@ pairs may be included in the initially given URL
    - headers always get normalized to "Studly-Caps"
    - won't support keep-alive connections
    - for PUT and other methods, the ->$params var may just hold the
      request body
    - files can be added to the ->params array as hash with specially
      named fields: "content"/"data", and "filename"/"name" , "type"
    - you can add authentication information using the standard notation
      "http://user:passw@www.example.com/..." for ->$url and ->$proxy

   A response object will have a ->$content field, ->$headers[] and
   ->len, ->type attributes as well. You could also ->decode() the
   body, if it is app/vnd.php.serialized or app/x-www-form-urlencoded.
   
   Public Domain (use freely, transform into any other license, like
   LGPL, BSD, MPL, ...; but if you change this into GPL please be so
   kind and leave your users a hint where to find the free version).
*/


#-- request objects
class http_request {

   var $method = "GET";
   var $proto = "HTTP/1.1";
   var $url = "";
   var $params = array();   // URL/form post vars, or single request body str
   var $headers = array();
   var $cookies = array();
   var $type = "url";       // content-type, abbrv. for x-www-form-...
   var $enc = false;        // "gzip" or "deflate"
   var $error="", $io_err=0, $io_err_s="";
   var $active_client = 1;  // enables redirect-following
   var $redirects = 3;
   var $proxy = false;      // set to "http://host:NN/"
   var $timeout = 15;


   #-- constructor
   function http_request($method="GET", $url="", $params=NULL) {
      $this->headers["User-Agent"] = "http_query/17.2 {$GLOBALS[ewiki_config][ua]}";
      $this->headers["Accept"] = "text/html, application/xml;q=0.9, text/xml;q=0.7, xml/*;q=0.6, text/plain;q=0.5, text/*;q=0.1, image/png;q=0.8, image/*;q=0.4, */*+xml;q=0.3; application/x-msword;q=0.001, */*;q=0.075";
      $this->headers["Accept-Language"] = "en, eo, es;q=0.2, fr;q=0.1, nl;q=0.1, de;q=0.1";
      $this->headers["Accept-Charset"] = "iso-8859-1, utf-8";
      $this->headers["Accept-Feature"] = "textonly, tables, !tcpa, !javascript, !activex, !graphic";
      $this->headers["Accept-Encoding"] = "deflate, gzip, compress, x-gzip, x-bzip2";
      //$this->headers["Referer"] = '$google';
      $this->headers["TE"] = "identity, chunked, binary, base64";
      $this->headers["Connection"] = "close";
      //$this->headers["Content-Type"] = & $this->type;
      if (isset($params)) {
         $this->params = $params;
      }
      if (strpos($method, "://")) {
         $url = $method;  # glue for incompat PEAR::Http_Request
         $method = "GET";
      }
      $this->method($method);
      $this->setURL($url);
   }


   #-- sets request method
   function method($str = "GET") {
      $this->method = $str;
   }

   #-- special headers
   function setcookie($str="name=value", $add="") {
      $this->cookies[strtok($str,"=")] = strtok("\000").$add;
   }


   #-- deciphers URL into server+path and query string
   function setURL($url) {
      if ($this->method == "GET") {
         $this->url = strtok($url, "?");
         if ($uu = strtok("\000")) {
            $this->setQueryString($uu);
         }
      }
      else {
         $this->url = $url;
      }
   }
   
   
   #-- decodes a query strings vars into the $params hash
   function setQueryString($qs) {
      $qs = ltrim($qs, "?");
      parse_str($qs, $this->params);
   }


   #-- returns params as querystring for GET requests
   function getQueryString() {
      $qs = "";
      if (function_exists("http_build_query")) {
         $qs = http_build_query($this->params);
      }
      else {
         foreach ($this->params as $n=>$v) {
            $qs .= "&" . urlencode($n) . "=" . urlencode($v);
         }
         $qs = substr($qs, 1);
      }
      return($qs);
   }


   #-- transforms $params into request body
   function pack(&$path) {
      $m = strtoupper($this->method);

      #-- GET, HEAD
      if (($m == "GET") || ($m == "HEAD")) {
         $BODY = "";
         $path .= (strpos($path, "?") ? "&" : "?") . $this->getQueryString();
      }

      #-- POST
      elseif (($m == "POST") && is_array($this->params)) {

         #-- known encoding types
         $type = $this->type($this->type, 0);
         if ($type == "url") {
            $BODY = $this->getQueryString($prep="");
         }
         elseif ($type == "php") {
            $BODY = serialize($this->params);
         }
         elseif ($type == "form") {
            // boundary doesn't need checking, unique enough
            $bnd = "snip-".dechex(time())."-".md5(serialize($this->params))
                 . "-".dechex(rand())."-snap";
            $BODY = "";
            foreach ($this->params as $i=>$v) {
               $ct = "text/plain";
               $inj = "";
               if (is_array($v)) {
                  ($ct = $v["ct"].$v["type"].$v["content-type"]) || ($ct = "application/octet-stream");
                  $inj = ' filename="' . urlencode($v["name"].$v["file"].$v["filename"]) . '"';
                  $v = $v["data"].$v["content"].$v["body"];
               }
               $BODY .= "--$bnd\015\012"
                     . "Content-Disposition: form-data; name=\"".urlencode($i)."\"$inj\015\012"
                     . "Content-Type: $ct\015\012"
                     . "Content-Length: " . strlen($v) . "\015\012"
                     . "\015\012$v\015\012";
            }
            $BODY .= "--$bnd--\015\012";
            $ct = $this->type("form") . "; boundary=$bnd";
         }
         #-- ignore
         else {
            $this->error = "unsupported POST encoding";
          // return(false);
            $BODY = & $this->params;
         }

         $this->headers["Content-Type"] = isset($ct) ? $ct : $this->type($type, 1);
      }

      #-- PUT, POST, PUSH, P*
      elseif ($m[0] == "P") {
         $BODY = & $this->$params;
      }

      #-- ERROR (but don't complain)
      else {
         $this->error = "unsupported request method '{$this->method}'";
       //  return(false);
         $BODY = & $this->params;
      }

      return($BODY);
   }


   #-- converts content-type strings from/to shortened nick
   function type($str, $long=1) {
      $trans = array(
         "form" => "multipart/form-data",
         "url" => "application/x-www-form-urlencoded",
         "php" => "application/vnd.php.serialized",
      );
      $trans["multi"] = &$trans["form"];
      if ($long) {
         $new = $trans[$str];
      }
      else {
         $new = array_search($str, $trans);
      }
      return( $new ? $new : $str );
   }


   #-- initiate the configured HTTP request ------------------------------
   function go($force=0, $asis=0) {

      #-- prepare parts
      $url = $this->prepare_url();
      if (!$url && !$force) { return; }
      $BODY = $this->body($url);
      if (($BODY===false) && !$force) { return; }
      $HEAD = $this->head($url);

      #-- open socket
      if (!$this->connect($url)) {
         return;
      }

      #-- send request data
      fwrite($this->socket, $HEAD);
      fwrite($this->socket, $BODY);
      $HEAD = false;
      $BODY = false;

      #-- read response, end connection
      while (!feof($this->socket) && (strlen($DATA) <= 1<<22)) {
         $DATA .= fread($this->socket, 32<<10);
#echo "fread(".strlen($DATA).") ";
      }
      fclose($this->socket);
      unset($this->socket);

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

      #-- decode response
      $r = new http_response();
      $r->from($DATA);        // should auto-unset $DATA

      #-- handle redirects
      if ($this->active_client) {
         $this->auto_actions($r);
      }

      #-- fin      
      return($r);
   }

   #-- alias
   function start($a=0, $b=0) { 
      return $this->go($a, $b);
   }
   
   
   #-- creates socket connection
   function connect(&$url) {
      if ((isset($this->socket) and !feof($this->socket))
      or ($this->socket = fsockopen($url["host"], $url["port"], $this->io_err, $this->io_err_s, $this->timeout))) {
         socket_set_blocking($this->socket, true);
         socket_set_timeout($this->socket, $this->timeout, 555);
         return(true);
      }
      else {
         $this->error = "no socket/connection";
         return(false);
      }
   }


   #-- separate URL into pieces, prepare special headers
   function prepare_url() {
      $this->setURL($this->url);
      if (!$this->proxy) {
         $url = parse_url($this->url);
         if (strtolower($url["scheme"]) != "http") {
            $this->error = "unsupported protocol/scheme";
            return(false);
         }
         if (!$url["host"]) { return; }
         if (!$url["port"]) { $url["port"] = 80; }
         if (!$url["path"]) { $url["path"] = "/"; }
         if ($url["query"]) { $url["path"] .= "?" . $url["query"]; }
         $proxy = "";
      }
      else {
         $url = parse_url($this->proxy);
         $url["path"] = $this->url;
         $proxy = "Proxy-";
         $this->headers["Proxy-Connection"] = $this->headers["Connection"];
      }

      #-- inj auth headers
      if ($url["user"] || $url["pass"]) {
         $this->headers[$proxy."Authorization"] = "Basic " . base64_encode("$url[user]:$url[pass]");
      }
      
      return($url);
   }


   #-- generates request body (if any), must be called before ->head()
   function body(&$url) {

      #-- encoding of variable $params as request body (according to reqmethod)
      $BODY = $this->pack($url["path"]);
      if ($BODY === false) {
         return false;
      }
      elseif ($len = strlen($BODY)) {
         $this->headers["Content-Length"] = $len;
      }
      $enc_funcs = array("gzip"=>"gzencode", "deflate"=>"gzinflate", "bzip2"=>"bzcompress", "x-bzip2"=>"bzcompress", "compress"=>"gzcompress");
      if ((strlen($BODY) >= 1024) && ($f = $enc_funcs[$this->enc]) && function_exists($f)) {
         $BODY = $f($BODY);
         $this->headers["Content-Encoding"] = $this->enc;
         $this->headers["Content-Length"] = strlen($BODY);
      }
      return($BODY);
   }


   #-- generates request head part
   function head(&$url) {
   
      #-- inject cookie header (if any)
      if ($this->cookies) {
         $c = "";
         foreach ($this->cookies as $i=>$v) {
            $c .= "; " . urlencode($i) . "=" . urlencode($v);
         }
         $this->headers["Cookie"] = substr($c, 2);
         $this->headers["Cookie2"] = '$Version="1"';
      }
      
      #-- request head
      $CRLF = "\015\012";
      $HEAD  = "{$this->method} {$url[path]} {$this->proto}$CRLF";
      $HEAD .= "Host: {$url[host]}$CRLF";
      foreach ($this->headers as $h=>$v) {
         $HEAD .= trim($h) . ": " . strtr(trim($v), "\n", " ") . $CRLF;
      }
      $HEAD .= $CRLF;
      return($HEAD);
   }

   #-- perform some things automatically (redirects)
   function auto_actions(&$r) {

      #-- behaviour table
      static $bhv = array(
         "failure" => "204,300,304,305,306",
         "clean_::POST" => "300,301,302,303,307",
         "clean_::PUT" => "300,301,302,303,307",
         "clean_::GET" => "300",  // $params:=undef
         "GET_::POST" => "303",
         "GET_::PUT" => "303",    // downgrade $method:=GET
      );
   
      #-- failure
      if (strstr($this->behaviour_table["failure"], $r->status)) {
         return;
      }

      #-- HTTP redirects
      if (($pri_url=$r->headers["Location"]) || ($pri_url=$r->headers["Uri"])) {

         if ((($this->redirects--) >= 0) && ($r->status >= 300) && ($r->status < 400)) {
            $m = strtoupper($this->method);
            if (strstr($this->behaviour_table["clean_::$m"], $r->status)) {
               unset($this->params);
            }
            if (strstr($this->behaviour_table["GET_::$m"], $r->status)) {
               $this->method("GET");
            }
            $this->setURL($pri_url);
            $this->go();
         }
      }
   }
   
   #-- aliases for compatiblity to PEAR::HTTP_Request
   function sendRequest() {
      return $this->go();
   }
   function setBasicAuth($user, $pw) {
      $this->url = preg_replace("#//(.+?@)?#", "//$user@$pw", $this->url);
   }
   function setMethod($m) {
      $this->method($m);
   }
   function setProxy($host, $port=8080, $user="", $pw="") {
      $auth = ($pw ? "$user:$pw@" : ($user ? "$user@" : ""));
      $this->proxy = "http://$auth$server:$port";
   }
   function addHeader($h, $v) {
      $this->headers[$h] = $v;
   }
   function getResponseStatus() {
      $this->headers[$h] = $v;
   }
}
class http_query extends http_request {
   /* this is just an alias */
}




#-- every query result will be encoded in such an object --------------------
class http_response {

   var $status = 520;
   var $status_str = "";
   var $headers_str = "";
   var $headers = array();
   var $len = 0;
   var $type = "message/x-raw";
   var $content = "";
   
   
   function http_response() {
   }
   

   #-- fill object from given HTTP response BLOB   
   function from(&$SRC) {
      $this->breakHeaders($SRC);  // split data into body + headers
      $SRC = false;
      $this->decodeHeaders();     // normalize header names
      $this->headerMeta();
      $this->decodeTransferEncodings();    // chunked
      $this->decodeContentEncodings();     // gzip, deflate
      $this->len = strlen($this->content);
   }


   #-- separates headers block from response body part
   function breakHeaders(&$DATA) {
      $l = strpos($DATA, "\012\015\012"); $skip = 3;
      $r = strpos($DATA, "\012\012");
      if ($r && ($r<$l)) { $l = $r; $skip = 2; }
      if (!$l) { $l = strlen($DATA); }
      $this->headers_str = rtrim(substr($DATA, 0, $l), "\015");
      $this->content = substr($DATA, $l + $skip);
      $this->body = & $this->content;
      $this->data = & $this->content;  // aliases
      $this->ct = & $this->type;
   }


   #-- splits up the $headers_str into an array and normalizes header names
   function decodeHeaders() {

      #-- normalize linebreaks
      $str = & $this->headers_str;
//      $str = str_replace("\n ", " ", $str);
      $str = str_replace("\r", "", $str);
      
      #-- strip headline
      $nl = strpos($str, "\n") + 1;
      $this->proto = strtok(substr($str, 0, $nl), " ");
      $this->status = (int) strtok(" ");
      $this->status_str = strtok("\000\r\n");
      if ($this->status == 100) {
         $this->full_duplex = 1;
      }

      #-- go through lines, split name:value pairs
      foreach (explode("\n", substr($str, $nl)) as $line) {

         $i = trim(strtok($line, ":"));
         $v = trim(strtok("\000"));

         #-- normalize name look&feel
         $i = strtr(ucwords(strtolower(strtr($i, "-", " "))), " ", "-");

         #-- add to, if key exists
         if (!empty($this->headers[$i])) {
            $this->headers[$i] .= ", ".$v;
         }
         else {
            $this->headers[$i] = $v;
         }

      }
   }


   #-- extract interesting values
   function headerMeta() {
      $this->len = strlen($this->content);
      $this->type = trim(strtok(strtolower($this->headers["Content-Type"]), ";"));
   }
   

   #-- strip any content transformation
   function decodeTransferEncodings() {
      $enc = trim(strtok(strtolower($this->headers["Transfer-Encoding"]), ",;"));
      if ($enc) {
         switch ($enc) {
#echo "ENC($enc) ";
            case "chunked":
               $this->decodeChunkedEncoding();
               break;
            case "base64":
               $this->content = base64_decode($this->content);
               $this->len = strlen($this->content);
               break;
            case "identity": case "binary":
            case "7bit": case "8bit":
               break;
            default:
               trigger_error("http_response::decodeTransferEncodings: unkown TE of '$enc'\n", E_WARNING);
         }
      }
   }


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

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


   #-- uncompress response body
   function decodeContentEncodings() {
      $enc = trim(strtok(strtolower($this->headers["Content-Encoding"]), ";,"));
      $dat = &$this->content;
      if ($enc == "deflate") {
         $dat = gzinflate($dat);
      }
      elseif (($enc == "gzip") || ($enc == "x-gzip")) {
         if (function_exists("gzdecode")) {
            $dat = gzdecode($dat);
         }
         else {
            $dat = gzinflate(substr($dat, 10, strlen($dat)-18));
         }
      }
      elseif ($enc == "compress") {
         $dat = gzuncompress($dat);
      }
      elseif (($enc == "x-bzip2") || ($enc == "bzip2")) {
         if (function_exists("bzdecompress")) {
            $dat = bzdecompress($dat);
         }
         else trigger_error("http_response::decodeContentEncoding: bzip2 decoding isn't supported with this PHP interpreter version", E_WARNING);
      }
      $this->len = strlen($this->content);
   }


   #-- can handle special content-types (multipart, serialized, form-data)
   function decode() {
      $t = http_request::type($this->type, 0);
      if ($t == "php") {
         return(unserialize($this->content));
      }
      elseif ($t == "url") {
         parse_str($this->content, $r);
         return($r);
      }
      elseif ($t == "form") {
         // oh, not yet exactly
      }
   }

   #-- aliases for compatiblity to PEAR::HTTP_Request
   function getResponseBody() {
      return $this->content;
   }
   function getResponseStatus() {
      return $this->status;
   }
   function getResponseCode() {
      return $this->status;
   }
   function getResponseHeader($i=NULL) {
      if (!isset($i)) {
         return $this->headers;
      }
      $i = strtolower($i);
      foreach ($this->headers as $h=>$v) {
         if (strtolower($h)==$i) {
            return $v;
         }
      }
   }
}



?>

Added ext/contrib/http.txt.





























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

Note: This class and file will be renamed into "xhttp..." in the near
feature, to prevent clashes with the old PEAR class.

http.php
――――――――
This script provides the easy to use "http_request" class ("http_query"
is an alias). You can contact forms or simply retrieve files with it.
Unlike fopen_wrappers, you get the response headers alongside and the
received file will be decompressed on-the-fly (it should also be faster
due to more supported compression methods).

There are some options, you can set before starting the request. Most
important aspect is, that you can add form ->params[] one after the
other for GET and POST requests. You can also use a proxy or include
authentication passwords in the initially given url, and of course
inject or override a few ->headers[] when it makes sense.



usage
―――――
It is really easy, you only must take care to always give the method
parameter before the URL ("GET" or "POST" in most cases), look at
the following:

  <?example

      #-- prepare
      $query = new http_request("GET", "http://example.com/form.php");
      $query->params["q"] = "search-this-...";

      #-- do request
      $result = $query->go();

      #-- use result
      if ($result && ($result->status == 200)) {
         echo $result->content;
      }
  ?>

Note, that we could have included the "q" parameter simply appended to
the URL in such simple cases ("http://example.com/form.php?q=search-...").

You can also do "POST" requests (normal for forms), but that you than
must decide about the encoding format. There are two for POST requests,
the default is always urlencoding (like with GET requests) with
  <?example 
      $query->type = "url";    // corresponds to "app/x-www-form-urlencoded"
  ?>
but many bigger forms however require the MIME type for form-data:
  <?example 
      $query->type = "form";    // translates to "multipart/form-data"
  ?>
You see, there are easy to remember abbreviations for this.

The form variables you want to transport are simply appended to the URL
for GETs or "url"-coded requests, but you could use the $query->params[]
array also here.

If you do a "POST" request, you do likewise; or you could also just assign
the $query->params a string blob to transfer as content (if the remote app
can deal with it or expects that, or you already have encoded eveything
into a valid form request).
If you just want to add upload-files to a "POST" request, then do this as
follows:
  <?example
      $query->params["fileformname"] = array(
         "filename" => "original-name.zip",
         "type" => "application/octet-stream",
         "content" => "$READ_FROM_FILE_DATA...",
      );
  // or
      $query->params["2nd_file"] = array(
         "ct" => "x.ml/my-format",
         "name" => "../../where/is/it/from.txt",
         "data" => file_get_contents(".../from.txt"),
      );
  ?>
"body" is a third alias for the "content" field here. If you don't set
the "type" or "ct" flag it will get "application/octet-stream" per default
(this is a good default). You could simply load the "ext/mime" script to
have the best possible MIME type here.



     start an request
     ――――――――――――――――
     Use the ->go() method to start a prepared HTTP request. The only
     alias existing today is ->start(); simply derive or edit this class
     to add your preferred name for this likewise (->do() cannot be used
     as it is a PHP reserved word, sorry ;)

     There are two options to ->go(), the first $force will override a few
     problems, and with the second ($asis) set to 1 or true, you won't get
     a result object, but the plain HTTP response blob (headers and response
     body as one large string variable).



     authentication
     ――――――――――――――
     If the remote site requires authentification, you would simply give
     this within the URL:
      <?example
         $query = new http_request("GET", "http://user:passw@example.com/...");
           // or later:
         $query->setURL("http://username:pw2@server.../")
           // or even:
         $query->url = "http://name:password@localhost/form.php";
      ?>



     proxy
     ―――――
     You can also acccess a form or remote file using a proxy server easily,
     just follow this:
      <?example
         $query = new http_request("PUT", "...");
         $query->proxy = "http://servername.proxy.org:3219/";
           // ...
         $result = $query->go();
      ?>
     You could also give a password or username for your proxy server, if
     you need it (works the same as for above).




reponses
――――――――
The $result value from the above examples should normally be an object,
it will be a scalar (false) only if something went really wrong.

It will have at least a ->status field, which is typically 200 for
succeeded requests. Everything above 500 means an server error, values
above 400 a transport and request error (= we did something wrong) and
a 300 response status means a redirection was issued.

For fulfilled requests you can access the returned file/data simply as
"$result->content" or "$result->body" or even "$result->data" (two aliases
again).

You will also have a "$result->headers[]" array, which will hold all
response HTTP headers in normalized form. Typically this means:
  <?example
      echo $result->headers["Content-Type"] . "\n";
      echo $result->headers["Date"] . "\n";
      echo $result->headers["Last-Modified"] . "\n";
      echo $result->headers["Content-Length"] . "\n";
      echo $result->headers["Etag"] . "\n";    // (beware of the lcased "t" !)
      echo $result->headers["Content-Encoding"] . "\n";
      ...
      print_r($result->headers);  // much better here ;)
  ?>
[[ Elsewhere the field names would be completely lowercased or fully
uppercase, we have CamelCase here, with the hyphens still in of course. ]]

Please note, that a known "Content-Encoding" was already removed from the
received ->content. And there is also a more correct "$result->len" and a
"$result->type" shorthand.

A few response types are understand as application data, and in this case
you can call the $result->decode() function and get a PHP variable/array
from the body.



     redirects
     ―――――――――
     If you expect HTTP redirects (->status codes from 300 till 375), then
     the default settings are ok for you, many will automatically be catched
     and the form data or file request will succeed at the replied URL.

     To tack/catch these cases yourself, simply disable that behaviour with:
      <?example
         $query->active_client = 0;
      ?>



PHP-RPC
―――――――
Not yet!  But this is probably what it will look like:

  If you control both ends of the Wire, you shouldn't use the slow and
  buggy (not everything works with everything else) XML-RPC protocol for
  calling remote functions, but instead use the high speed PHP serialize
  encoding to transfer data.

  The "http_request" class can natively encode values as such. The MIME
  type "application/vnd.php.serialized" has been registered explicitely
  for this purpose (as alternative to "multipart/form-data" encoding,
  and it is type-safe as opposed to the "/x-www-form-urlencoded" format).
  Perl and JS implementations exist (probably also one for Python), so
  plattform-independence should be given.

  PHP-RPC shall inherit (not yet negotiated) some structure from the old
  XML-RPC protocol. That is, a few names are identical. If you start an
  request you would therefore do following:

<?php

    function phprpc($server, $function, $args=array()) {

       #-- init
       $query = new http_request("POST", $server);

       #-- set content
       $query->type = "php";  // here corresponds to "app/vnd.php.serialized"
       $query->params
         = array(
              "method" => $function,
              "params" => $args,
           );

       #-- start
       $result = $query->go();
       if ($result && ($result->status == 200)) {

          $r = $result->decode();
          if ($good = $r["result"]) {
             return($good);
          }
          return($r);
       }
    }
?>

  You of course need a server part to make use of this. Simply try the
  "ext/phprequest", in which case you would do the following:

<?php

   include("ext/phprequest.php")
   if (count($_POST) && ($method = $_POST["method"])
   and ($params = $_POST["params"]))
   {
      #-- call known/registered functions
      $method = strtolower($method);
      if ($method == "my.func") {
         $r = call_user_func_array("my_func", $params);
      }
      elseif ($method == "system.time") {
         $r = time();
      }
      elseif ($method == "sytem.listmethods") {
         $r = get_defined_functions();
         $r = $r["user"];
      }

      #-- if succeeded
      if ($r) { 
         header("Content-Type: application/vnd.php.serialized");
         header("Content-Encoding: deflate");
         $r = array("result" => $r);
         die(gzdeflate(serialize($r));
      }
   }

   #-- your normal script can go on here
   //...
?>

  You can inject this into anywhere as it only engages, if a PHP-RPC
  request was detected. 



Added ext/contrib/is_utf8.php.











































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

#-- test if string uses UTF-8 encoding
# http://www.w3.org/International/questions/qa-forms-utf-8.en.php
# (Martin Dόrst, W3C)
function is_utf8($field) {
   return preg_match(
      '/^( [\09\0A\0D\x20-\x7E]               # ASCII
         | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
         |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
         | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
         |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
         |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
         | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
         |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
      )*$/x',
      $field
   );
}

?>

Added ext/contrib/pdo-2006-01-29.tar.gz.

cannot compute difference between binary files

Added ext/contrib/php5oo.php.















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
/**
 * Some functions from PHP5, that aren't actually senseful to replicate
 * for PHP4. The new native object semantics cannot be emulated anyhow.
 *
 * - see also ext/contrib/exceptions.php
 *
 */



 
/**
 * Make a real object copy. This is a token in PHP5, not a function.
 *
 * Uses serialize-trick from PHP_Compat, because PHP4 references can
 * neither be detected nor resolved otherwise.
 *
 * @stub
 * @since 5.0
 */
if (!function_exists("clone") && PHP_VERSION < "5.0") {
   eval('
   function clone($obj) {
   
      // this however duplicates sub-objects and arrays too
      $new = unserialize(serialize(($obj));
     
      if (method_exists($new, "__clone")) {
         $new->__clone();
      }

      return $new;
   }
   ');
}


?>

Added ext/contrib/phprequest.php.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
/*
   Allows http "POST" and "PUSH" requests with a Content-Type of
   "application/vnd.php.serialized". This isn't used in the wild.
*/

if (empty($_POST)
and (strtoupper($_SERVER["REQUEST_METHOD"][0]) == "P")
and (strtolower(trim(strtok($_SERVER["CONTENT_TYPE"], ";,(")))
     == "application/vnd.php.serialized"))   
{
   #-- search for bare request body
   if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
      $_POST = $GLOBALS["HTTP_RAW_POST_DATA"];
   }
   else {
      $f = fopen("php://input", "rb");
      $_POST = fread($f, 1<<22);
      fclose($f);
   }

   #-- uncompress and decode, if something found
   if ($_POST) {

      #-- strip known/supported encodings
      $enc = trim(strtok(strtolower($_SERVER["HTTP_CONTENT_ENCODING"]), ",;"));
      if ($enc == "deflate") {
         $_POST = gzinflate($_POST);
      }
      elseif ($enc == "compress") {
         $_POST = gzuncompress($_POST);
      }
      elseif ($enc == "gzip") {
         $_POST = function_exists("gzdecode") ? gzdecode($_POST) : gzinflate(substr($_POST, 10, strlen($_POST) - 18));
      }
      elseif (($enc == "x-bzip2") or ($enc == "bzip2")) {
         $_POST = function_exists("bzdecompress") ? bzdecompress($_POST) : NULL;
      }

      #-- decipher
      if ($_POST) {
         $_POST = unserialize($_POST);
      }
      #-- merge
      if ($_POST) {
         $_REQUEST = array_merge($_REQUEST, $_POST);
      }

   }
}

?>

Added ext/contrib/xmlrpc.php.











































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
<?php define("XMLRPC_VERSION", "0.3.10");
# api: PHP
# type: api
# provides: rpc, xml-rpc
# version: 0.3.10
# category: library
# priority: optional
# title: XML-RPC client and server
# description: serves remote procedure calls
# homepage: http://freshmeat.net/p/upgradephp
#
#  Supports XML-RPC (text/xml) and XML+RPC (application/rpc+xml) compressed,
#  and can be used as client or server interface. Works without XMLRPC and
#  XML extensions, but utilizes them for optimal speed whenever available.
#
#   XXXX   XXXX MMM     MMM LLL              RRRRRRR   PPPPPPP    CCCCCCC
#    XXXX XXXX  MMMM   MMMM LLL      +++     RRRRRRRR  PPPPPPPP  CCCCCCCCC
#     XXXXXXX   MMMMM MMMMM LLL      +++     RRR   RRR PPP   PPP CCC    CCC
#      XXXXX    MMMMMMMMMMM LLL  +++++++++++ RRR   RRR PPP   PPP CCC
#       XXX     MMM MMM MMM LLL  +++++++++++ RRRRRRRR  PPPPPPPP  CCC
#      XXXXX    MMM  M  MMM LLL      +++     RRRRRRR   PPPPPPP   CCC
#     XXXXXXX   MMM     MMM LLL      +++     RRR  RRR  PPP       CCC    CCC
#    XXXX XXXX  MMM     MMM LLLLLLL          RRR   RRR PPP       CCCCCCCCC
#   XXXX   XXXX MMM     MMM LLLLLLL          RRR   RRR PPP        CCCCCCC
#
#  This is Public Domain. (c) 2004 WhoEver wants to. [milky*erphesfurt·de]


#-- config
define("XMLRPC_PLUS", 0);        # use XML+RPC per default
define("XMLRPC_AUTO_TYPES", 0);  # detect base64+datetime strings and automatically generate the according xmlrpc object representations then
define("XMLRPC_AUTO_UTF8", 1);   # de/convert anything from and to UTF-8 automatically - if yourscripts use Latin1 natively, but the RPC server expects/sends UTF-8
define("XMLRPC_CHARSET", "utf-8");  # used in responses and requests
define("XMLRPC_AUTODISCOVERY", 0);  # "connections" automatically create methods
define("XMLRPC_FAST", 1);        # use PHPs XML-RPC extension where possible
define("XMLRPC_OO", 1);          # return XML-RPC/HTTP errors as objects
define("XMLRPC_DEBUG", 0);       # output error hints, write /tmp dumps - set this to 1, 2 or 3

#-- _server() settings
define("XMLRPC_LOG", "/tmp/xmlrpc.".@$_SERVER["SERVER_NAME"].".log");

#-- general data
#  (don't change the following, most are auto-configured values)
define("XMLRPC_UA", "xml+rpc/".XMLRPC_VERSION." (PHP/".PHP_VERSION."; ".PHP_OS.")");
define("XMLRPC_MIME_NEW", "application/rpc+xml");
define("XMLRPC_MIME_OLD", "text/xml");
define("XMLRPC_MIME", XMLRPC_MIME_OLD);
define("XMLRPC_ACCEPT", XMLRPC_MIME_NEW.", ".XMLRPC_MIME_OLD."; q=0.5");
define("XMLRPC_EPI", function_exists("xmlrpc_decode_request"));

#-- init
error_reporting(0);
if (isset($_SERVER["HTTP_CONTENT_TYPE"]) && empty($_SERVER["CONTENT_TYPE"])) {
   $_SERVER["CONTENT_TYPE"] = $_SERVER["HTTP_CONTENT_TYPE"];   // older CGI implementations
}




############################################################################
#                                                                          #
#  client part                                                             #
#                                                                          #
############################################################################


#-- Issue a request, call can take any number of arguments.
#     $result = xmlrpc("http://example.com/RPC2/", "method1", $arg1 ...);
#     $result = xmlrpc("xml+rpc://here.org/RPC3/", "ns.function", ...);
#   Results automatically have <datetime> values converted into Unix
#   timestamps and <base64> unpacked into strings.
#
function xmlrpc($server, $method=NULL /*, ... */) {
   if ($method) {
      $params = func_get_args();
      shift($params); shift($params);
      return
        xmlrpc_request($server, $method, $params);
   }
   else {
      return
        new xmlrpc_connection($server);
   }
}



#--  Generate and send request, decode response.
function xmlrpc_request($url, $method, $params=array(), $plus=XMLRPC_PLUS, $gzip=0) {
   global $xmlrpc_response_headers, $xmlrpc_error;
   
   #-- init whole lib for request (we are not-OO here)
   $xmlrpc_error = false;
   $xmlrpc_response_headers = array();
   
   #-- encapsulate req, transmit it
   $socket = xmlrpc_request_send($url, $method, $params, $plus, $gzip);
   if (!$socket) {
      return xmlrpc_error(-32768, "no connection", 0, "GLOBALVARS");
   }

   #-- wait for, read response
   $response = "";
   while (!feof($socket) && (strlen($DATA) <= 768<<10)) {
      $response .= fread($socket, 4<<10);
   }
   fclose($socket);
   if (XMLRPC_DEBUG >= 3) {
      echo "<code>$response</code>";
   }

   #-- decode answer and give results
   return xmlrpc_response_decode($response);
}


#-- an alias
function xmlrpc_call($url, $method, $params=array(), $plus=XMLRPC_PLUS, $gzip=0) {
   return xmlrpc_request($url, $method, $params, $plus, $gzip);
}



#-- marshall request parameters into array, hash, xml string
function xmlrpc_request_send($url, $method, &$params, $plus, $gzip, $blocking=true) {

   #-- get connection data
   $c = parse_url($url);
   ($host = $c["host"]);
   ($port = @$c["port"]) or ($port = 80);
   ($path = $c["path"]) or ($path = "/");
   if (strpos($c["scheme"], "+")) {
      $plus++;
   }
   if (strpos($c["scheme"], "gzip")) {
      $gzip++;
   }
   if (!$host) { return(NULL); }
   $inj = "";
   if ($str = $c["user"]) {
      if ($c["pass"]) { $str .= ":" . $c["pass"]; }
      $inj = "Authorization: Basic " . base64_encode($str) . "\n";
   }
   
   #-- mk request HTTP+XML block from params
   $request = xmlrpc_request_marshall($method, $params);
   $request = xmlrpc_request_http($request, $path, $host, $plus, $gzip, $inj);

   #-- connect, send request
   if ($socket = fsockopen($host, $port, $io_err, $io_err_s, 30)) {
      socket_set_blocking($socket, $blocking);
      socket_set_timeout($socket, 17, 555);
   }
   else {
      echo "Could not connect to '<b>$host</b>:$port$path' - error $io_err: $io_err_s.<br>\n";
      return(NULL);
   }
   fputs($socket, $request);

   #-- done here
   return($socket);
}


#-- marshall function call into XML+HTTP string
function xmlrpc_request_marshall($method, &$params) {

   #-- use xmlrpc-epi
   if (XMLRPC_FAST && XMLRPC_EPI) {
      $query = xmlrpc_encode_request($method, $params);
      return($query);
   }

   #-- build query
   $query = array(
      "methodCall" => array(
         "methodName" => array( ",0"=>$method ),
         "params" => array()
      )
   );
   foreach ($params as $i=>$p) {
      $query["methodCall"]["params"]["param,$i"] = xmlrpc_compact_value($p);
   }
   $query = array2xml($query, 1, 'encoding="'.XMLRPC_CHARSET.'" ');

   #-- encode?
   if (XMLRPC_AUTO_UTF8) {
      $query = utf8_encode($query);
   }
   
   return($query);   
}


#-- enclose body into HTTP request string
function xmlrpc_request_http(&$query, $path, $host, $plus, $gzip, $inj_header="") {

   #-- build request
   $n = "\015\012";
   $request = "POST $path HTTP/1.0$n"
            . "Host: $host$n"
            . ($inj_header ? str_replace("\n", $n, $inj_header) : "")
            . "User-Agent: " . XMLRPC_UA . "$n"
            . "Accept: ".XMLRPC_ACCEPT."$n"
            . (!XMLRPC_DEBUG ? "Accept-Encoding: deflate$n" : "")
            . "Content-Type: ".($plus ? XMLRPC_MIME_NEW : XMLRPC_MIME_OLD)
                              ."; charset=".XMLRPC_CHARSET."$n";

   #-- compress?
   if ($gzip) {
      $query = gzdeflate($query);
      $request .= "Content-Encoding: deflate$n";
   }
   $request .= "Content-Length: " . strlen($query) . "$n" . "$n";
   $request .= $query . "$n";

   return($request);
}


#-- unpack response from HTTP and XML representation
function xmlrpc_response_decode(&$response) {
   global $xmlrpc_response_headers;

   #-- split into headers and content
   $l1 = strpos($response, "\n\n");
   $l2 = strpos($response, "\n\r\n");
   if ($l2 && (!$l1 || ($l2<$l1))) {
      $head = substr($response, 0, $l2);
      $response = substr($response, $l2+3);
   }
   else {
      $head = substr($response, 0, $l1);
      $response = substr($response, $l2+2);
   }

   #-- decode headers, decompress body
   foreach (explode("\n", $head) as $line) {
      $xmlrpc_response_headers[strtolower(trim(strtok($line, ":")))] = trim(strtok("\000"));
   }
   if ($enc = trim(@$xmlrpc_response_headers["content-encoding"])) {
      if (($enc == "gzip") || ($enc == "x-gzip")) {
         $response = gzinflate(substr($response, 10, strlen($response)-18));
      }
      elseif (($enc == "compress") || ($enc == "x-compress")) {
         $response = gzuncompress($response);
      }
      elseif (($enc == "deflate") || ($enc == "x-deflate")) {
         $response = gzinflate($response);
      }
   }

   $r = xmlrpc_response_unmarshall($response);
   if (XMLRPC_DEBUG) {var_dump($r);}
   return($r);
}


#-- decode XML-RPC from string into array and extract its actual meaning
function xmlrpc_response_unmarshall(&$response) {
   global $xmlrpc_response_headers;

   #-- strip encoding
   if (XMLRPC_AUTO_UTF8) {
      xmlrpc_decode_utf8xml($response, @$xmlrpc_response_headers["content-type"].@$xmlrpc_response_headers["content-charset"]);
   }

   if (XMLRPC_DEBUG >= 4) { fwrite(fopen("/tmp/xmlrpc:resp_in_xml","w"), $response); }
   
   #-- use xmlrpc-epi
   if (XMLRPC_FAST && XMLRPC_EPI) {
      $r = xmlrpc_decode_request($response, $uu);
      xmlrpc_epi_decode_xtypes($r);
      if (is_array($r) && (count($r)==2) && isset($r["faultCode"]) && isset($r["faultString"])) {
         return xmlrpc_error($r["faultCode"], $r["faultString"], 1, "GLOBALVARS");
      }
      else {
         return($r);
      }
   }


   #-- unmarshall XML
   $response = xml2array($response);

   #-- fetch content (one returned element)
   if ($r = @$response["methodResponse,0"]["params,0"]["param,0"]["value,0"]) {
      $r = xmlrpc_decode_value($r);
      return($r);
   }
  
   #-- error cases
   #  (we should rather return an error object here)
   if (($r = @$response["methodResponse,0"]["fault,0"]["value,0"]) && ($r = xmlrpc_decode_value($r))) { 
      return xmlrpc_error($r["faultCode"], $r["faultString"], 1, "GLOBALVARS");
   }
   else {
      return xmlrpc_error(-32600, "xml+rpc: invalid response", 0, "GLBLVRS");
   }
   return(NULL);
}



#-- Establish a virtual XML+RPC or XML-RPC server connection (a pseudo
#   handshake is used to determine supported protocol / extensions).
class xmlrpc_connection {

   #-- init
   function xmlrpc_connection($url, $autodiscovery=0) {
      global $xmlrpc_response_headers;
      $this->server = $url;
      $this->plus = 0;
      $this->gzip = 0;

      #-- handshake to check supported protocol
      $funcs = $this->call("system.getVersion");
      $this->plus = (strpos($xmlrpc_response_headers["accept"], XMLRPC_MIME_NEW) !== false);
      $this->gzip = (strpos($xmlrpc_response_headers["accept_encoding"], "deflate") !== false);
      
      #-- auto-discovery, create 'method' names
      if ($funcs && (XMLRPC_AUTODISCOVERY || $autodiscovery)) {
         foreach ($funcs as $fn) {
            $short = $fn;
            if ($l = strpos($fn, ".")) {
               $short = substr($fn, $l + 1);
               if (substr($fn, 0, $l) == "system") { continue; }
            }
            $this->short = create_function("", "return xmlrpc_request('{$this->server}','$fn',func_get_args(),{$this->plus},{$this->gzip});");
         }
      }
   }
   
   #-- generical call (needs func name)
   function call($method /*, ... */) {
      $params = func_get_args();
      shift($params);
      $r = xmlrpc_request($this->serverm, $method, $params, $this->plus, $this->gzip);
      return($r);
   }
}

#-- an alias
class xmlrpc extends xmlrpc_connection {
}




############################################################################
#                                                                          #
#  server implementation                                                   #
#                                                                          #
############################################################################


#-- Check request and execute function if registered in $xmlrpc_methods[]
#   array.
function xmlrpc_server() {

   global $xmlrpc_methods;

   #-- server is active
   define("XMLRPC_SERVER", getmypid());
   if (XMLRPC_DEBUG) { error_reporting(E_ALL^E_NOTICE); }
   ob_start();

   #-- standard reply headers
   header("Accept: ".XMLRPC_MIME_NEW.", ".XMLRPC_MIME_OLD."; q=0.5");
   header("Accept-Encoding: deflate");
   header("X-Server: " . XMLRPC_UA);
   header("Connection: close");
   header("Cache-Control: private");

   #-- fixes for PHP/Apache
   if (function_exists("getallheaders")) {
      foreach (getallheaders() as $i=>$v) {
         $_SERVER[strtoupper(strtr("HTTP_$i", "-", "_"))] = $v;
      }
   }

   #-- check and get call
   $allowed = array(
      "REQUEST_METHOD" => array("POST", "PUT", "CALL"),
      "CONTENT_TYPE" => array(XMLRPC_MIME_NEW, XMLRPC_MIME_OLD),
   );
   foreach ($allowed as $WHAT=>$WHICH) {
      if (!in_array(trim(strtok($WRONG=$_SERVER[$WHAT], ";,(")), $WHICH)) {
         header("Status: 400 Go Away, Stupid!");
         if (!$WRONG) {
            $WRONG = "undefined";
         }
         die("<h2>Error</h2>Your request was bogus, <b>$WHAT</b> must be <i>"
             . implode("</i> or <i>", $WHICH) . "</i>, but yours was '<tt>$WRONG</tt>'.\n");
      }
   }
   if (!($xml_request = xmlrpc_fetch_post_chunk())) {
      header("Status: 500 How Sad");
      die("<h2>Error</h2>Could not fetch POST data.\n");
   }

   #-- decipher incoming XML request string
   $method = "";
   if (XMLRPC_FAST && XMLRPC_EPI) {
      $params = xmlrpc_decode_request($xml_request, $method);
      xmlrpc_epi_decode_xtypes($params);
   }
   else {
      $params = xmlrpc_request_unmarshall($xml_request, $method);
   }

   
   #-- add the few system.methods()
   //if (empty($xmlrpc_methods)) {
   //   $xmlrpc_methods = get_defined_functions();
   //}
   $xmlrpc_methods["system"] = "xmlrpc_system_methods";   # a class

   #-- call
   $result = xmlrpc_exec_method($method, $params);

   #-- send back result
   if (isset($result)) {
      if (isset($result)) {
         $resp["methodResponse"]["params"]["param"] = xmlrpc_compact_value($result);
      }
      else {
         $resp["methodResponse"]["params"] = array();
      }

      xmlrpc_send_response($resp);
   }
   else {
      $result = xmlrpc_error(0, "No Result");
      xmlrpc_send_response($result);
   }
}



#-- decode <methodCall> XML string into understandable chunks,
#   gives $params as return value and $method name via pass-by-ref
function xmlrpc_request_unmarshall(&$xml_request, &$method) {

   #-- mangle charset
   if (XMLRPC_AUTO_UTF8) {
      xmlrpc_decode_utf8xml($xml_request, $_SERVER["CONTENT_TYPE"].$_SERVER["HTTP_CONTENT_CHARSET"]);
   }

   #-- decode XML string into PHP arrays
   $call = xml2array($xml_request, 1);
   $xml_request = NULL;

   $call = $call["methodCall,0"];
   if (!$call) {
      xmlrpc_send_response(xmlrpc_error(-32600, "Bad Request, <methodCall> missing"));
   }
   $method = $call["methodName,0"][",0"];
   if (!$method) {
      xmlrpc_send_response(xmlrpc_error(-32600, "Bad Request, <methodName> missing"));
   } 

   $params = array();
   foreach ($call["params,1"] as $uu => $param) {
      $params[] = xmlrpc_decode_value($param["value,0"]);
   }

   return($params);
}



#-- Call the requested method (using the XML-method to PHP-function mapping
#   table and hints).
function xmlrpc_exec_method($method, $params) {

   global $xmlrpc_methods;
   if (XMLRPC_DEBUG >= 2) { error_reporting(E_ALL^E_NOTICE); }

   #-- check if allowed call
   $rf = strtr($method, ".", "_");
   $cl = strtok($method, ".");
   if (!$xmlrpc_methods[$method] && !$xmlrpc_methods[$cl]
      && !in_array($method, $xmlrpc_methods)
      && !in_array($rf, $xmlrpc_methods) && !in_array($cl, $xmlrpc_methods) )
   {
      xmlrpc_send_response(xmlrpc_error(-32601));
   }

   #-- real function call
   if ($php_func_name = $xmlrpc_methods[$method]) {
      $rf = $method = $php_func_name;
   }
   if (function_exists($rf)) {
      $result = call_user_func_array($rf, $params);
      if (XMLRPC_DEBUG >= 4) { fwrite(fopen("/tmp/xmlrpc:func_call_res","w"),serialize(array($rf,$result,$params))); }
      return($result);
   }
   #-- PHP object method calls
   else {
      $class = strtok($method, ".");
      $method = strtok("\000");
      if ($uu = $xmlrpc_methods[$class]) {
         $class = $uu;
      }
      if ($class && class_exists($class) && $method) {
         $obj = new $class;
         if (method_exists($obj, $method)) {
            $result = call_user_method_array($method, $obj, $params);  //<DEPRECATED>
            return($result);
         }
      }
   }

   #-- else error
   xmlrpc_send_response(xmlrpc_error(-32601));
}



#-- Get POST data from PHP (if it gives it to us).
function xmlrpc_fetch_post_chunk() {
   global $HTTP_RAW_POST_DATA;

   $data = false;
   if ($f = fopen("php://input", "rb")) {
      $data = fread($f, 0x0100000);
      fclose($f);
   }
   if (empty($data)) {
      ini_set("always_populate_raw_post_data", "true");  // well, maybe(!?)
      $data = $HTTP_RAW_POST_DATA;
      $HTTP_RAW_POST_DATA = "";
   }
   $enc = trim(strtolower($_SERVER["HTTP_CONTENT_ENCODING"]));
   $funcs = array("deflate"=>"gzinflate", "gzip"=>"gzdecode", "compress"=>"gzuncompress", "x-gzip"=>"gzdecode", "x-bzip2"=>"bzuncompress");
   if ($enc && ($pf = $funcs[$enc]) && function_exists($pf)) {
      $data = $pf($data);
   }
   return($data);
}


#-- converts UTF-8 documents into Latin-1 ones
function xmlrpc_decode_utf8xml(&$xml, $ct) {
   if (strpos(strtolower($ct), "utf-8") or preg_match('/<\?xml[^>]+encoding=["\']utf-8/i', $xml)) {
      $xml = utf8_decode($xml);
      $xml = preg_replace('/(<\?xml[^>]+encoding=["\'])utf-8(["\'])/i', '$1iso-8859-1$2', $xml, 1);
   }
}



#-- Creates an error object.
function xmlrpc_error($no=-32500, $str="", $type=1, $into_vars=0) {
   global $xmlrpc_error, $xmlrpc_errorcode;
   $errors = array(
           0 => "No Result",
      -32300 => "Transport error",
      -32400 => "Internal Server Error",
      -32500 => "Application error",
      -32600 => "Invalid message format / Bad request",
      -32601 => "Method does not exist",
      -32602 => "Parameter type mismatch",
      -32603 => "Internal XML-RPC error",
      -32604 => "Too many parameters",
      -32700 => "Not well-formed XML",
      -32701 => "Unsupported encoding - only ISO-8859-1 and UTF-8 capable",
      -32702 => "Invalid characters, encoding mismatch",
   );
   #-- build response xml/array
   if (!($str) && !($str = $errors[$no])) {
      $str = "Unknown Error";
   }
   if ($into_vars && !XMLRPC_OO) {
      $xmlrpc_error = $str;
      $xmlrpc_errorcode = $no;
      return(NULL);
   }
   else {
      return new xmlrpc_error($no, $str, $type);
   }
}


#-- error object
class xmlrpc_error {

   var $type = 1;   // else an HTTP error
   var $no;
   var $str;
   
   function xmlrpc_error($no, $str, $type=1) {
      $this->type = $type;
      $this->no = $no;
      $this->str = $str;
   }
   
   function send() {
      $error = xmlrpc_compact_value(array(
         "faultCode" => $no,
         "faultString" => $str,
      ));
      $resp = array(
         "methodResponse" => array(
            "fault" => $error
         )
      );
      xmlrpc_send_response($resp);
   }
}


#-- Sends a response.
function xmlrpc_send_response($r) {

   #-- error objects send itself (by calling _send_response() again ;-)
   if (is_object($r)) {
      $r->send();
   }

   #-- answer XML-RPC and XML+RPC requests
   $ct = trim(strtok(strtolower($_SERVER["CONTENT_TYPE"]), ";,("));  // from original request
   $cs = XMLRPC_CHARSET;
   header("Content-Type: $ct; charset=\"$cs\"");
   
   #-- make XML document from it
   if (is_array($r)) {
      $r = array2xml($r, 1, 'encoding="'.$cs.'" ');
   }

   #-- compress answer?
   if (!headers_sent()) {
      $enc = trim(strtolower($_SERVER["HTTP_ACCEPT_ENCODING"]));
      $funcs = array("deflate"=>"gzdeflate", "gzip"=>"gzencode", "compress"=>"gzcompress", "x-gzip"=>"gzencode", "x-bzip2"=>"bzcompress");
      if ($enc && ($pf = $funcs[$enc]) && function_exists($pf)) {
         header("Content-Encoding: $enc");
         $r = $pf($r);
      }
   }

   #-- send
   if (ob_get_level()) {
      #-- this prevents that PHP errors appear as garbage in our response
      $add .= "<!--\n" . ob_get_contents() . "\n-->";
      ob_end_clean();
   }
   header("Content-Length: " . strlen($r));
   print $r . $add;
   die;
}



#-- Provides "system.*" method namespace.
class xmlrpc_system_methods {

   function listMethods() {
      global $xmlrpc_methods;
      $r = array();
      foreach ($xmlrpc_methods as $i=>$i2) {
         $real = is_int($i) ? $i2 : $i;
         if (class_exists($real) && ($i2=$real) || class_exists($i2)) {
            foreach (get_class_methods($i2) as $add) {
               $r[] = $real.".".$add;
            }
         }
         else {
            $r[] = $real;
         }
      }
      return($r);
   }

   function time() {
      return new xmlrpc_datetime(time());
   }
}


############################################################################
#                                                                          #
#  misc functions                                                          #
#                                                                          #
############################################################################


function xmlrpc_log($message) {
}

function xmlrpc_die($error="", $str="") {
}



############################################################################
#                                                                          #
#  data representation mangling                                            #
#                                                                          #
############################################################################


#-- Makes compact-array2xml datavar from a PHP variable.
function xmlrpc_compact_value($var, $n=0) {

   #-- create compact-array2xml tree
   $root = array(
      "value,$n" => array(),
   );
   $r = &$root["value,$n"];

   #-- detect PHP values to be complex types in XML-RPC
   if (XMLRPC_AUTO_TYPES && is_string($var)) {
      if ((strlen($var) >= 64) && preg_match('/^[\w]+=*$/', $var)) {
         $var = new xmlrpc_base64($var);
      }
      elseif ((strlen($var)==17) && ($var[8]=="T") && preg_match('/^\d{8}T\d\d:\d\d:\d\d$/', $var)) {
         $var = new xmlrpc_datetime($var);
      }
   }

   #-- complex types
   if (is_object($var)) {
      $r = $var->out();
   }
   #-- arrays and hashes(structs)
   elseif (is_array($var)) {
      if (isset($var[0]) || empty($var)) {
         $r = array("array,$n" => array("data,0" => array()));
         $r = &$r["array,$n"]["data,0"];
         foreach ($var as $n=>$val) {
            $r = array_merge($r, xmlrpc_compact_value($val, $n));
         }
      }
      else {
         $r = array("struct,$n"=>array());
         $r = &$r["struct,$n"];
         $n = 0;
         foreach ($var as $i=>$val) {
            $r["member,$n"] = array_merge(array(
               "name,0" => array(",0" => "$i"),
            ), xmlrpc_compact_value($val, 1));
            $n++;
         }
      }
   }
   #-- simple types
   elseif (is_bool($var)) {
      $r = array(
         "boolean,$n" => array(",0" => ($var?1:0)),
      );
   }
   elseif (is_int($var)) {
      $r = array(
         "int,$n" => array(",0" => $var),
      );
   }
   elseif (is_float($var)) {
      $r = array(
         "double,$n" => array(",0" => $var),
      );
   }
   elseif (is_string($var)) {
      $r = array(
         "string,$n" => array(",0" => $var),
      );
   }
   return($root);
}


#-- Makes a PHP array from a compact-xml2array representation. $value must
#   always be the xml2array elements _below_ the ["value,0"] or ["data,0"]
#   or ["member,N"] entry.
function xmlrpc_decode_value($value) {
   $val = NULL;
   foreach ($value as $i=>$d) {

      #-- use single (text) content xml2array entry as actual $d var
      if (is_array($d) && isset($d[",0"])) {
         $d = $d[",0"];
      }

      #-- convert into PHP var based on type
      $type = strtok($i, ",");
      switch ($type) {

         case "array":
            $val = array();
            foreach ($d["data,0"] as $i=>$value) {
               $val[] = xmlrpc_decode_value($value);
            }
            break;

         case "struct":
            $val = array();
            foreach ($d as $uu=>$d2) {
               if (($in=$d2["name,0"][",0"]) && ($pos2=1) || ($in=$d2["name,1"][",0"]) && ($pos2=0)) {
                  $val[$in] = xmlrpc_decode_value($d2["value,$pos2"]);
               }
            }
            break;

         case "":    # handles also '<value>s</value>' instead
         case "0":   # of '<value><string>s</string></value>'
         case "string":
            $val =  is_array($d) ? "" : (string)$d;
            break;

         case "base64":
            $val = (XMLRPC_AUTO_TYPES>=2) ? base64_decode($d) : (string)$d;
            if ((XMLRPC_AUTO_UTF8 >= 2) && ($uu = utf8_decode($val))) {
               $val = $uu;
            }
            break;
            
      // case "real":  case "float":   // neither is allowed
         case "double":
            $val = (double)$d;
            break;
         case "i4":
         case "int":
            $val = (int)$d;
            break;

         case "boolean":
            $val = (boolean)$d;
            break;

         case "dateTime.iso8601":
            $val = xmlrpc_strtotime($d);
            break;

         default:
            if (defined("XMLRPC_SERVER")) {
               xmlrpc_send_response(xmlrpc_error(-32600, "Unknown data type '$type'"));
            }
            else {
               echo $xmlrpc_error = "UNKNOWN XML-RPC DATA TYPE '$type'<br>\n";
               $xmlrpc_errorcode = -32207;
            }
#           echo "<!-- UNKNOWN TYPE $type -->\n";
#           xmlrpc_log("bad data type '$type' enountered");
      }
   }
   return($val);
}


#-- More complex XML-RPC data types need object representation to
#   distinguish them from ordinary string and integer vars.
class xmlrpc_xtype {
   var $scalar = "";
   var $xmlrpc_type = "string";
   var $tag = "string";
   function xmlrpc_type($str) {
      $this->data = $str;
   }
   function out() {
      return array($this->tag.",0" => array(",0"=>$this->scalar));
   }
}
class xmlrpc_base64 extends xmlrpc_xtype {
   function xmlrpc_base64($str) {
      $this->tag = "base64";
      $this->xmlrpc_type = "base64";
      if (XMLRPC_AUTO_UTF8 >= 2) {
         $str = utf8_encode($str);
      }
      if (!preg_match("/^[=\w\s]+$/", $str)) {
         $this->encode=1;
      }
      $this->scalar = $str;
   }
   function out() {
      if (isset($this->encode)) {
         $this->scalar = chunk_split(base64_encode($this->scalar), 74, "\n");
      }
      return xmlrpc_xtype::out();
   }
}
class xmlrpc_datetime extends xmlrpc_xtype {
   function xmlrpc_datetime($t) {
      $this->tag = "dateTime.iso8601";
      $this->xmlrpc_type = "datetime";
      if (($t > 0) && ($t[8] != "T")) {
         $this->timestamp = $t;
         $t = xmlrpc_timetostr($t);
      }
      $this->scalar = $t;
   }
}

#-- Further simplify use of the above ones.
function xmlrpc_base64($string) {
   return(new xmlrpc_base64($string));
}
function xmlrpc_datetime($timestr) {
   return(new xmlrpc_datetime($timestr));
}


#-- Deciphers ISO datetime string into UNIX timestamp.
function xmlrpc_strtotime($str) {
   $tm = explode(":", substr($str, 9));
   $t = mktime($tm[0], $tm[1], $tm[2], substr($str, 4, 2), substr($str, 6, 2), substr($str, 0, 4));
   return($t);
}
function xmlrpc_timetostr($time) {
   return(gmstrftime("%Y%m%dT%T", $time));
}


#-- helping hand for the xmlrpc-epi extension of php
function xmlrpc_epi_decode_xtypes(&$r) {
   if (is_object($r) && isset($r->xmlrpc_type)) {
      if (isset($r->timestamp)) {
         $r = $r->timestamp;
      }
      else {
         $r = $r->scalar;
      }
   }
   elseif (is_array($r)) {
      foreach ($r as $i=>$v) {
         xmlrpc_epi_decode_xtypes($r[$i]);
      }
   }
}




############################################################################
#                                                                          #
#  simplified XML parser                                                   #
#                                                                          #
############################################################################


#-- Encode the two chars & and < into htmlentities (there is nothing said
#   about the possible other entities in the XML-RPC spec).
function xml_entities($str) {
   $e = array(
      "&" => "&amp;",
      "<" => "&lt;",
//      ">" => "&gt;",
   );
   return(strtr($str, $e));
}
function xml_decode_entities($str) {
   $e = array(
      "&lt;" => "<",
      "&gt;" => ">",
      "&apos;" => "'",
      "&quot;" => '"',
      "&amp;" => "&",
   );
   if (strpos($e, "&#") !== false) {
      $e = preg_replace('/&#(\d+);/e', 'chr($1)', $e);
      $e = preg_replace('/&#x([\da-fA-F]+);/e', 'chr(hexdec("$1"))', $e);
   }
   return(strtr($str, $e));
}


#-- Can split simplified XML into a PHP array structure. The now used
#   'compact' format will yield tag sub arrays with an "*,0" index and
#   just [",0"] for text nodes.
function xml2array($xml, $compact="ALWAYS") {
   $r = array();
   if (function_exists("xml_parser_create") && (strlen($xml) >= 512)) {
      $r = xml2array_php($xml);
   }
   else {
      xml2array_parse($xml, $r, $compact);
   }
   return($r);
}


#-- Recursively builds an array of the chunks fetched via strtok() from
#   the original XML input string.
function xml2array_parse(&$string, &$r, $compact=1) {
   $n = 0;
   do {
      #-- split chunks
      $l = strpos($string, "<");
      $p = strpos($string, ">", $l);
      $text = $attr=$close = $tag = false;
      if ($l === false) {
         $text = $string;
         $string = false;
      }
      else {
         $tag = strtok(substr($string, $l+1, $p-$l-1), " ");
         if ((strncmp($tag, "![CDATA[", 8)==0) && ($p = strpos($string, "]]>", $l))) {
            $text = substr($string, $l+9, $p-$l-9);
         }
         else {
            if ($l) {
               $text = xml_decode_entities(substr($string, 0, $l));
            }
            $attr = strtok("\000");
            $close = $attr && ($attr[strlen($attr)-1]=="/");
            $string = substr($string, $p+1);
         }
      }
      #-- insert text/body content into array
      if (trim($text)) {
#         if ($compact) {
             $r[",$n"] = $text;
#         }
#         else {
#            $r[] = $text;
#         }
         $n++;
      }
      #-- recurse for tags
      if ($tag && ($tag[0] >= 'A')) {    #-- don't read <? <! </ pseudo-tags
#         if ($compact) {
             $r["$tag,$n"] = array();
             $new = &$r["$tag,$n"];
#         } else {
#            $r[] = array($tag => array());
#            $new = &$r[count($r)-1][$tag];
#         }
         if (!$close) {
            xml2array_parse($string, $new, $compact);
         }
         $n++;
      }
      #-- stop if no more tags or content
      if (empty($tag) && empty($text) || empty($string)) {
         $tag = "/";
      }
   } while ($tag[0] != "/");
}


#-- Uses the XML extension of PHP to convert an XML stream into the
#   compact array representation.
function xml2array_php(&$xml, $compact=1) {

   $p = xml_parser_create(xml_which_charset($xml));
   xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, false);
   xml_parser_set_option($p, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");

   xml_parse_into_struct($p, $xml, $struct);

   $a = array();  // will hold all tag nodes
   $tree = array(&$a);  // stack of pointers to last node of any tree level
   $in = &$a;           // pointer to last created node

   foreach ($struct as $t) {
      unset($value);
      extract($t);

      $depth = count($tree) - 1;
      $in = &$tree[$depth];
      $tag .= "," . count($in);
//echo "#$depth, TAG=\"$tag\", TYP=$type, LEV=$level, VAL=$value\n";

      switch ($type[1]) {

         #--  OpEN
         case "p":
            $in[$tag] = array();
            if ($type=="open") {
               $tree[] = &$in[$tag];
            }
            if (isset($value) && trim($value)) {
               $in[$tag][",0"] = $value;
            }
            break;

         #--  CoMPLETE
         case "o":
            $in[$tag] = array();
            if (isset($value) && trim($value)) {
               $in[$tag][",0"] = $value;
            }
            break;

         #--  ClOSE
         case "l":
            array_pop($tree);
            break;

         #--  CdATA - usually just whitespace
         case "d":
            if (isset($value) && trim($value)) {
               $in[",".count($in)] = $value;
            }
            break;
         
         default:
            // case "attribute":
            // and anything else we do not want
      }
      
   }
   
   return($a);
}



function xml_which_charset(&$xml) {
   return( strpos(strtok($xml, "\n"), '-8859-1"') ? "iso-8859-1" : "utf-8" );
}



############################################################################
#                                                                          #
#  simplified XML creator                                                  #
#                                                                          #
############################################################################


#-- This is the opposite of the above xml2array, and can also work with the
#   so called $compact format.
function array2xml($r, $compact=1, $ins="") {
   $string = "<?xml version=\"1.0\" $ins?>";
   array2xml_push($string, $r, $compact);
   return($string);
}


#-- Recursively throws out the XMLified tree generated by the xml2array()
#   'parser' function.
function array2xml_push(&$string, &$r, $compact, $ind=-1) {
   $old_ind = ++$ind - 1;
   if ($old_ind < 0) { $old_ind = 0; }
   foreach ($r as $i=>$d) {
      $d = &$r[$i];
      if (is_scalar($d)) {
         $string .= xml_entities($d);
      }
      elseif (is_array($d)) {
         if ($compact) {
            $i = strtok($i, ","); 
         }
         $ls = str_repeat(" ", $ind);
         $string .= "\n$ls<$i>";
         $string .=  array2xml_push($string, $d, $compact, $ind);
         $ls = str_repeat(" ", $old_ind);
         $string .= "</$i>\n$ls";
      }
   }
}




?>

Added ext/contrib/xmlrpc.txt.





































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

XML-RPC is a "standard" (well, not yet exactly) for accessing remotely
provided 'Web services'. More exactly it is just a complicated encoding
standard for calling functions and procedures on a remote Web server
(and getting its calculation or data request results of course).

It is still in wide use for many interesting features like accessing
database content, searching, data conversion, and so on. It started as
a lightweight alternative to SOAP, which currently is more on the rise.
While SOAP is much more bloated, also XML-RPC is not the quickest RPC
format available, is not really standards-compliant (bogus specs over
the time), and so has probably only a limited lifetime now.
Therefore you should try to provide your services and access others`
via vanilla HTTP requests (form or url encoding), when possible; use
the "http.php" class for this.

(There is also a faster PHP-RPC standard on the rise, which provides
type-safe data transport over compressed and fast connections, without
the encoding overhead and charset issues when using XML-RPC.)



xmlrpc.php
――――――――――
The 'xmlrpc.php' script implements the XML-RPC spec., but adds a few
extensions, namely use of the (yet unregistered) "application/rpc+xml"
MIME type and compressed HTTP transportation. It uses a builtin stupid
XML parser (for the highly simplified XML-RPC message content) and thus
is totally independent of any PHP extensions. It of course takes
advantage of the XML extension where present (a lot faster), and it even
can make use of Epinions XML-RPC extension for PHP (really fast than).

It is mostly not object-oriented, but extremely easy to use for building
XML-RPC servers or calling remote procedures.


configuration
―――――――――――――
There are a few constants and variables that the 'xmlrpc.php' script
respects.

XMLRPC_PLUS
   If set to 1 enables use of the "application/rpc+xml" MIME type and
   request compression per default (for server and client). In 2004
   still not the recommended setting.

XMLRPC_AUTO_TYPES
   Allows the request encoder to automatically determine the <base64>
   and <dateTime.iso8061> types, even if you just used them as scalar PHP
   values. Otherwise you had to use 'new xmlrpc_base64("STrinG==")' and
   'new xmlrpc_datetime("20001020T00:00:00")' to prepare such values.

XMLRPC_AUTO_UTF8
   Takes care of transforming the complete RPC messages into/from UTF-8,
   what is useful if your scripts deal only with Latin1 and always expect
   this. <base64> are also de/encoded if you set this constant to 2.

XMLRPC_CHARSET
   The whole script is currently optimized to produce UTF-8 and decode
   requests from/into Latin-1 for your scripts.

XMLRPC_FAST
   Enables use of Epinions XML-RPC extension module for PHP automatically
   where available. You only want to disable this for debugging purposes.

XMLRPC_OO
   Engages error result objects, else you had to use the two global vars
   "$xmlrpc_error" and "$xmlrpc_errorstr" to detect such cases. If you
   enable it you must however compare all xmlrpc_request() result values
   against being an object (what does not happen for succeeded XML-RPC
   requests).

XMLRPC_AUTODISCOVERY
   If you create a "xmlrpc" or "xmlrpc_connection" object and this is
   enabled, you would get the object with function names of the
   automatically instantiated methods of the remotely provided service
   wrapped into one object (not yet), much like in the Python library
   for xmlrpc.

XMLRPC_LOG
   Creates a log file for incoming requests to the _server() part of xmlrpc
   (whenerver you activate it with the _server() call).


There are also a few automatically defined values, which you shouldn't
care about:

XMLRPC_MIME
   Contains the currently selected default MIME type for transport.
XMLRPC_MIME_NEW
   Contains the newer MIME type value. Do not change.
XMLRPC_MIME_OLD
   For compatibility with older XML-RPC clients and servers. Do not change.
XMLRPC_ACCEPT
   Again the MIME Types wrapped into a HTTP Accept: header for requests
   and responses.
XMLRPC_EPI
   Tells if the Epinions extension is available.


server configuration
――――――――――――――――――――
$xmlrpc_methods[]
   Every accessible method (for remote calls) must be defined here, for
   use with the xmlrpc_server(). There is a separate section on this one.


making xmlrpc() requests
――――――――――――――――――――――――
You can call a remote procedure by just using the short xmlrpc() call
syntax:

  $result = xmlrpc("http://example.com/rpc.php", "the.function", 1, 2, 3);

Where 1, 2 and 3 would be parameters to "the.function" on the remote server.
The number of parameters is not limited, and you do not need to give one at
all (if the remote procedure does not require them. The parameter values
are automatically encoded into XML-RPC representations except for <base64>
and <dateTime.iso8061> ones, for which you needed to create objects first.
The $result of course recieved in ordinary PHP representation of the remote
functions result value.


       xmlrpc_request()
       ――――――――――――――――
       Is basically the same as calling the xmlrpc() function, but that
       all parameters given to the remote function are now to be passed
       as array in the third parameter:

         $params = array(  "param1", "param2", "param3"  );
         $r = xmlrpc_request("server.com:80", "remoteMethod", $params);

       Also a fourth parameter to xmlrpc_request (boolean) says if to
       use the old XML-RPC or the faster XML+RPC interface. But beware,
       that this could fail if you connect to an older server.


       xmlrpc_connection
       ―――――――――――――――――
       You can also establish a 'connection' (this is purely virtual) to
       a remote XML-RPC server, using a xmlrpc_connection object as follows:

         $xc = new xmlrpc_connection("http://example.com/rpc.php");

       Then you could regularily call remote functions on that server:

         $result1 = $xc->call("function1");
         $result2 = $xc->call("function2", 2, $result1, 0x5F02);

       The xmlrpc_connection automatically chooses XML+RPC if available
       with the remote server.


       data types
       ――――――――――
       Unless XMLRPC_AUTO_TYPES was enabled (discouraged, because this is
       considered 'unreliable type guessing') you need to explicetely mark
       parameters passed to the xmlrpc() or xmlrpc_request() calls for
       their later XML-RPC type.

       To do so, you have the two class types 'xmlrpc_datetime' and
       'xmlrpc_base64' availabe. Use them as follows:

          $param1 = new xmlrpc_base64(  base64_encode($string1)  );
          $p2 = new xmlrpc_datetime(  time() + 60*60*24*7  );
          $r = xmlrpc("www.server.com/rpc/", "function1", $param1, $p2);

       Please note, that you needed to call base64_encode() yourself, and
       that the _datetime() can also use standard Unix timestamps as input.

       The XML-RPC <dateTime.iso8601> entites are, btw, automatically
       converted into Unix timestamps, if returned as result from xmlrpc()
       and xmlrpc_request() calls. This happens regardless of
       XMLRPC_AUTO_TYPES.

       If XMLRPC_AUTO_TYPES is set to 2, then even <base64> result values
       would be automatically converted into their plain (binary) string
       representation.


       "Bugs"
       ――――――
       pass-by-reference is not possible ;)



xmlrpc_server() use
―――――――――――――――――――
To make a set of functions available for remote calls, you would create
an interface script and make its URL public. Assuming that you had a
subdirectory "./myrpc" on your server, you would likely want to create 
the file "./myrpc/index.php" with following content:

   <?php

      $xmlrpc_methods = array(
         "myFunction",
         "mySecondOne",
      );
 
      include("xmlrpc.php");
      xmlrpc_server();
   ?>

So, by calling the xmlrpc_server() you make all registered functions
($xmlrpc_methods) available with the URL "xml+rpc://example.com/myrpc/" for
remote calls.


       $xmlrpc_methods[]
       ―――――――――――――――――
       All function names you list in this array (before calling the
       xmlrpc_server() function) will be available for remote calls. The
       function names are mapped to remote method names by having the
       _ underscore as alias the the . dot, which is commonly used. So a
       function whose name was "tools_register" was available as remotely
       callable method "tools_register" or "tools.register".

       Also with xmlrpc_server() it is possible to register member methods
       of object classes as remotely callable methods. All you needed to
       do is list your class in $xmlrpc_methods[].

       You can also give aliases, both for function names and for object
       classes:

          $xmlrpc_methods["callable.methodname"] = "here_function_name";
          $xmlrpc_methods["section"] = "here_class_name";

       The member methods of a class cannot be aliased however.


       xmlrpc_server()
       ―――――――――――――――
       Just fetches the current request, decodes it and executes the
       destination method (PHP function) if listed in the global
       $xmlrpc_methods[] variable.

       It automatically exits after sending the response or an error. So
       this is the last command in your xmlrpc wrapper script.


       xmlrpc_fetch_post_chunk()
       ―――――――――――――――――――――――――
       Begs PHP for the complete POST data stream. It only has two options
       to do so and may fail with some Webservers and earlier PHP versions.
       In either case try to set the "always_populate_raw_post_data" option
       in php.ini or from within a .htaccess file.

       To allow the server part to receive the XML-RPC message, you either
       need PHP 4.3 or later, or configure your PHP interpreter specifically
       to pass in the POSTed data stream. In you php.ini ([PHP] section) add:

         always_populate_raw_post_data = 1

       Or following in a .htaccess per-dir configuration
       file for Apache:

         php_option always_populate_raw_post_data=1


       xmlrpc_send_response()
       ――――――――――――――――――――――
       Is called from within xmlrpc_server() to send the response for the
       processed request (also sends error responses).


       xmlrpc_error()
       ――――――――――――――
       Creates a XML-RPC error result array.



---------------------------------------------------------------------------
internals
---------------------------------------------------------------------------
Unless you are interrested in an in-deep discussion of the "xmlrpc.php"
you should effectively stop reading here.


xmlrpc data representation encoders
―――――――――――――――――――――――――――――――――――
This lib uses the simple xml2array() compact format to do the initial work
of converting a XML file into an array representation. Various design
restrictions of the XML-RPC message format then impose certain structures
inside of the xml2array-compact representation, what is taken adavantage of.

For example <struct> entries have in the compact representation sub-elements
like ["member,0"], ["member,1"], ["member,2"] and so on. Each of which then
has two sub elements: ["name,0"] and ["value,1"].

The XML-RPC <array> instead had one ["data,0"] with sub-arrays of
["value,0"], ["value,1"], ["value,2"] and so on, which would be recursively
feed through:


      xmlrpc_decode_value()
      ―――――――――――――――――――――
      Makes a PHP representation of a part (one must start it with the
      content of a ["value,0"]) from a xml2array()-compact representation
      made out of a XML-RPC message.


      xmlrpc_compact_value()
      ――――――――――――――――――――――
      Converts a PHP array or scalar variable into an array suitable for
      transformation into a XML-RPC message string using the array2xml()
      function then.



generic functions
―――――――――――――――――
The xml2array() and array2xml() functions are stupid XML parsers and
probably only suitable for XML-RPC messages.


       xml2array()
       ―――――――――――
       Can decode a SimplifiedXML document into an array structure - and this
       in two formats. Internall xml+rpc uses only the so called "$compact
       format". If we had a XML document like the following:

       <xml>
         <more> <string> String </string>
         </more>
         <more> <string> String2 </string>
                <int>5</int>
         </more>
       </xml>

       It would return for the $compact=1 format, something like:

       array(
          "xml,0" => array(
             "more,0" => array(
                "string,0" = array(
                   ",0" => " String "
                )
             )
             "more,1" => array(
                "string,0" = array(
                   ",0" => " String2 "
                ),
                "int,1" = array(
                   ",0" => 5
                )
             )
          )
       );

       Where every tagname had a ","+NUMBER suffix, and text nodes would
       start with the comma. The numbers are always counted up in each
       nesting level from 0, regardless if it counted text or tag nodes.

       The not-compact format would hold another subarray to denote a deeper
       level tag node, but leave the text nodes as entries into the ordering
       array level. This was more suitable for XML like files, where you had
       mixed text and tag nodes in a level. For example:

       <html>
          string1
          <b>string2</b>
       </html>

       Would become in the not-compact format:

       array(
          0 => array(
             "html" => array(
                0 => "\n   string1\n   "
                1 => array(
                   "b" => array(
                       0 => "string2",
                   )
             )
          )
       )


       array2xml()
       ―――――――――――
       Regenerates a XML stream from an array structure like the one emitted
       by xml2array().


other functions
―――――――――――――――
If you want a different behaviour, you might want to alter one of
the following functions.


      xmlrpc_method_call()
      ――――――――――――――――――――
      Is responsible in the _server() part for invoking the requested
      function. It does so by using the $xmlrpc_methods[] array as mapping
      to the PHP functions to activate.

      If you would like to have a better mapping support, or even to add
      parameter type and number checking, then this is where you would
      want to start editing the code.


Deleted ext/dba.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
<?php
/*
   Load this with plugins/db/dba.php if your PHP provides only the
   older dbm_*() functions.
*/


#-- fake dba_* using dbm_* functions
if (!function_exists("dba_open") && function_exists("dbm_open")) {

   function dba_open($path, $mode, $handler, $a1=0) {
      if ($handler == "dbm") {
         return(dbmopen($path, $mode));
      }
      else return(false);
   }

   function dba_popen($a, $b, $c, $d=0) {
      return(dba_open($a, $b, $c));
   }

   function dba_exists($key, $handle) {
      return(dbmexists($handle, $key));
   }

   function dba_fetch($key, $handle) {
      return(dbmfetch($handle, $key));
   }

   function dba_insert($key, $string, $handle) {
      return(dbminsert($handle, $key, $string));
   }

   function dba_replace($key, $string, $handle) {
      return(dbmreplace($handle, $key, $string));
   }

   function dba_delete($key, $handle) {
      return(dbmdelete($handle, $key));
   }

   function dba_firstkey($handle) {
      return($GLOBALS["dbm_lastkey"] = dbmfirstkey($handle));
   }

   function dba_nextkey($handle) {
      return(dbmnextkey($handle, $GLOBALS["dbm_lastkey"]));
   }

   function dba_close($handle) {
      return(dbmclose($handle));
   }

   function dba_handlers() {
      return(array("dbm"));
   }

}


?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Changes to ext/exotic.php.

1
2
3
4
5
6
7
8
9
10
11
12
<?php
/*
   Following funtions have been removed from the core emulation script, because
   they are considered too special to be commonly used in WWW scripts. Anybody
   using them, probably takes extra precautions prior calling them (you could
   still load this script). Some of these functions could also be too difficult
   to be reimplemented 100% exactly.
*/



#-- calls PHP interpreter itself (really only works with 4.3 onwards)




|







1
2
3
4
5
6
7
8
9
10
11
12
<?php
/*
   Following funtions have been removed from the core emulation script, because
   they are considered too special to be commonly used in WWW scripts. Anybody
   using these, probably takes extra precautions prior calling them (you could
   still load this script). Some of these functions could also be too difficult
   to be reimplemented 100% exactly.
*/



#-- calls PHP interpreter itself (really only works with 4.3 onwards)
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
      $fn = escapeshellcmd($fn);
      $result = system("php -lqCf '$fn'", $err);
      return($err==0);
   }
}


#-- print enumerated lsit of last-called functions
if (!function_exists("debug_print_backtrace") && function_exists("debug_backtrace")) {
   function debug_print_backtrace() {
      $d = debug_backtrace();
      foreach ($d as $i=>$info) {
         #-- index
         echo "#" . ($i) . "  ";
         







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
      $fn = escapeshellcmd($fn);
      $result = system("php -lqCf '$fn'", $err);
      return($err==0);
   }
}


#-- print enumerated list of last-called functions
if (!function_exists("debug_print_backtrace") && function_exists("debug_backtrace")) {
   function debug_print_backtrace() {
      $d = debug_backtrace();
      foreach ($d as $i=>$info) {
         #-- index
         echo "#" . ($i) . "  ";
         

Deleted ext/fakezlib.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<?php
/*
   This script simulates the gz*() functions, without actually providing
   compression functionality. The generated data streams will be correct,
   but reading compressed files isn't possible.
   
   Not very useful; should only be used if there is no other way. But if
   your provider seriously doesn't have PHP with builtin zlib support,
   you seriously were better off simply switching to someone else...
*/


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

    function gzopen($fp, $mode) {
       $mode = preg_replace('/[^carwb+]/', '', $mode);
       return(fopen($fp, $mode));
    }
    function gzread($fp, $len) {
       return(fread($fp, $len));
    }
    function gzwrite($fp, $string) {
       return(fwrite($fp, $string));
    }
    function gzputs($fp, $string) {
       return(fputs($fp, $string));
    }
    function gzclose($fp) {
       return(fclose($fp));
    }
    function gzeof($fp) {
       return(feof($fp));
    }
    function gzseek($fp, $offs) {
       return(fseek($fp, $offs, SEEK_SET));
    }
    function gzrewind($fp) {
       return(frewind($fp));
    }
    function gztell($fp) {
       return(ftell($fp));
    }

    function gzpassthru($fp) {
       while (!gzeof($fp)) {
          print(gzred($fp, 1<<20));
       }
       gzclose($fp);
    }
    function readgzfile($fn) {
       if ($fp = gzopen($fn, "rb")) {
          gzpassthru($fp);
       }
    }
   
    function gzfile($fn) {
       return(file($fn));
    }

    function gzgetc($fp) {
       return(fgetc($fp));
    }
    function gzgets($fp, $len) {
       return(fgets($fp, $len));
    }
    function gzgetss($fp, $len, $allowedtags="") {
       return(fgetss($fp, $len, $allowedtags));
    }

 }


 #-- fake compression methods
 if (!function_exists("gzdeflate")) {

    // only returns uncompressed deflate streams
    function gzdeflate($data, $level=0) {
        $gz = "";
        $end = strlen($data);
        $p = 0;
        do {
           $c = $end - $pos;
           if ($c >= 65536) {
              $c = 0xFFFF;
              $end = 0x00;
           }
           else {
              $end = 0x01;
           }
           $gz .= pack("Cvv",
                     ($end << 7) + (00 << 5),  // LAST=0/1, BTYPE=00
                     $c,                       // LEN
                     $c ^ 0xFFFF               // NLEN
                  );
           $gz .= substr($data, $p, $c);
           $p += $c;
        }
        while ($p < $end);
        return($gz);
    }

    // only can strip deflate headers, cannot decompress
    function gzinflate($data, $length=NULL) {
       $end = strlen($data);
       $gz = "";
       if (isset($length) && (($max*0.99) > $length)) {
          trigger_error("gzinflate(): gave up, decompressed string is likely longer than requested", E_USER_ERROR);
          return;
       }
       $out = "";
       $p = 0;
       do {
          $head = ord($data[$p]);
          $last = ($head >> 7);
          if (($head & 0x60) != 00) {
             trigger_error("gzinflate(): cannot decode compressed stream", E_USER_ERROR);
             return;
          }
          $head = unpack("v1LEN/v1NLEN", substr($data, $p+1, 4));
          $c = $head["LEN"];
          if (($c ^ 0xFFFF) != $head["NLEN"]) {
             trigger_error("gzinflate(): data error in stream", E_USER_ERROR);
             return;
          }
          $p += 5;
          $out .= substr($data, $p, $c);
          $p += $c;
       }
       while (($p < $end) && !$last);
       return($out);
    }


//    function gzcompress() {
//    }
//    function gzuncompress() {
//    }

    // without real compression support again
    function gzencode($data, $level=0) {
       $isize = strlen($data);
       $crc32 = crc32($data);
       $gz = "";
       {
          $gz .= pack("nCCVCC",
             $_ID = 0x1f8b,
             $_CM = 0x08,  // deflate fmt
             $_FLG = 0x00, // nothing extra
             $_MTIME = time(),
             $_XFL = 0x00, // no bonus flags
             $_OS = 255    // "unknown"
          );
          $gz .= gzdeflate($data);
          $gz .= pack("VV", $crc32, $isize);
       }
       return($gz);
    }

 }

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































Deleted 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/gettext.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
<?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
   to the desired language manually. Additionally all your scripts
   could contain following (may also work with standard gettext):
     $_ENV["LANGUAGE"] = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
   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





|













|







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
<?php
/*
  api: PHP
  type: functions
  title: gettext()
  description: emulates PHP gettext extension 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
   to the desired language manually. Additionally all your scripts
   could contain following (may also work with standard gettext):
     $_ENV["LANGUAGE"] = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
   That'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

Deleted ext/gettext.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

PHP-only gettext emulation
--------------------------

The "gettext.php" include script tries to reimplement GNU gettext in
pure PHP. It is incomplete and divergent in many ways, but seems to
work well in its goal to be a quick drop-in replacement.

You load the script, like you'd include the "upgrade.php" script, and
then have the family of gettext functions always available - if they
are compiled in into your PHP binary or not. This way you can freely
use standardized i18n features safely on any web server and with all
your applications.

There are however a few minor obstacles and differences in between
the original and the emulation which you have to take care of. Most
of the incompatibilites descend from lousily documented behaviour of
the original and from lack of extensqive testing of the emulated
versions.

 - You should use setlocale() before any bindtextdomain(), because
   this emulation does load the .mo/.po data files only once.

 - The emulation only ever loads one translation file (it never
   retrieves translation strings from different localizations,
   so it is less useful in conjunction with Accept-Language header
   settings - where multiple languages could be given).
   [Original gettext may or may not load from multiple files??]

 - To be compliant with the native implementation, you have to make
   sure, that the .mo files are built from the *.po source files.
   (The emulation tries to work on both, but it really shouldn't do
   that.)

 - Order of environment variable precedence is:
     1. LANGUAGE
     2. LC_ALL
     3. LC_MESSAGE
     4. LANG                    (multiple langs)
     5. setlocale()
     6. HTTP_ACCEPT_LANGUAGE    (incompliant with GNU gettext)

 - There is a second variant of the script, which tries to handle
   plural forms. This has multiple limitations:
     - does not employ a full Plural-Forms parser (a C expression
       which must be interpreted at runtime)
     - matches and works only with a few built-in language plural
       form syntaxes and orderings
     - and it's fully untested as of yet

 - It constructs a global $_GETTEXT[] variable which contains all
   messages and translations at runtime in-memory. That means, it
   is far more memory-hungry and less scalable than the original
   GNU libintl in C.



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































Changes to ext/mime.php.

1
2
3
4
5
6


7
8
9
10
11
12
13
14
<?php
/*
   Simulates the mime_magic extension. Was originally implemented for
   [http://nanoweb.si.kz/], but that mime magic data reading was
   reinjected for this version (more unclean, though).
   You still need to get the "mime_magic" file to use this, please see


   file(1) for more informations.
   Also simulates the image type/mime/ext functions.
*/


#-- mime-magic, type will be detected by analyzing the content
if (!function_exists("mime_content_type")) {
   function mime_content_type($fn) {





|
>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
/*
   Simulates the mime_magic extension. Was originally implemented for
   [http://nanoweb.si.kz/], but that mime magic data reading was
   reinjected for this version (more unclean, though).

   It uses the system-wide "mime_magic" file to do this. See file(1).
   On Windows you might need to install it first.
   
   Also simulates the image type/mime/ext functions.
*/


#-- mime-magic, type will be detected by analyzing the content
if (!function_exists("mime_content_type")) {
   function mime_content_type($fn) {

Added ext/nonstandard/base64.php.

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
/**
 *
 * This script implements the base64-encoding functions and base32 and
 * base16 as described in RFC3548.
 *
 * @since never
 * @nonstandard
 *
 */
if (!function_exists("base16_encode")) {


   #-- URL and filename safe variants of base64-encoding
   function base64_encode_safe($str) {
      return strtr(base64_encode($str), "+/", "-_");
   }
   function base64_decode_safe($b64) {
      return base64_decode(strtr($str, "-_", "+/"));
   }


   #-- base16
   function base16_encode($str) {
      $str = unpack("H".(2*strlen($str)), $str);
      $str = chunk_split($str[1]);
      return($str);
   }
   function base16_decode($b16) {
      $b16 = preg_replace("/\s+/", '', $b16);
      $b16 = pack("H*", $b16);
      return($b16);
   }


   #-- base32
   function base32_encode() {
      
      # strtoupper()
      # "A-Z,0-7,="
   }

}
?>

Deleted ext/odbc.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

die("'odbc.php' is incomplete. Don't use this yet.\n");

/*
   This is just another SQL interface wrapper. It reimplements the ODBC
   functions in PHP by itself chaining to PEAR::DB (a double wrapper,
   to simplify this initial version).
    - does not use integers as connection_id

   Because any mysql_*() calls are easier replaced with odbc_() funcs,
   but at the same time offer the same degree of database independence,
   this can often make more sense than transitioning to PEAR::DB or the
   ADOdb classes.
    - PEAR::DB provides the saner OO-interface
    - ADOdb is slightly faster, but has a less nicely abstracted API
*/


#-- declare odbc interface functions
if (!function_exists("odbc_connect")) {

   #-- load PEAR::DB
   require_once("DB.php");


   #-- initialize connection
   function odbc_connect($dsn, $user, $password, $cursor_type=NULL) {

      #-- mangle $dsn for PEAR
      $dsn = str_replace("://", "://$user:$password@", $dsn);
      // ... rename dbtype identifiers

      #-- connect
      $c = DB::connect($dsn);
      if (!PEAR::isError($c)) {
         return($c);
      }
   }

   #-- incomplete
   function odbc_pconnect($dsn, $user, $password, $cursor_type=NULL) {
      return odbc_connect($dsn, $user, $password, $cursor_type);
   }
   
   #-- end connection
   function odbc_close($db) {
      $db->disconnect();
   }
   
   
   #-- SQL command execution
   function odbc_exec($db, $query) {
      return $db->query($db);
   }
   function odbc_do($db, $query) {
      return odbc_exec($db, $query);
   }


   #-- sql pre-parsing
   function odbc_prepare($db, $query) {
      return( array($db, $db->prepare($db)) );
   }
   #-- and execution of prepared query
   function odbc_execute($pq, $args=NULL) {
      return $pq[0]->execute($pq[1], $args);
   }


   #-- return result row
   function odbc_fetch_array($res) {
      return $res->fetchRow(DB_FETCHMODE_ASSOC);
   }
   function odbc_fetch_row($res) {
      return $res->fetchRow(DB_FETCHMODE_ORDERED);
   }
   function odbc_fetch_object($res) {
      return $res->fetchRow(DB_FETCHMODE_OBJECT);
   }
   function odbc_fetch_into($res, $count, &$array) {
      $array = array();
      while ($count--) {
         $array[] =  $res->fetchRow(DB_FETCHMODE_ORDERED);
      }
   }
   
   
   #-- more functions on result sets
   function odbc_free_result(&$res) {
      $res->free();
      $res = NULL;
   }
   function odbc_next_result($res) {
      return $res->nextResult();
   }
   function odbc_num_fields($res) {
      return $res->numCols();
   }
   function odbc_num_rows($res) {
      return $res->numRows();
   }
   
   
   #-- and there's more
   //...

   

}


?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































Deleted ext/old.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
<?php
/*
   Here we collect PHP functions for versions before 4.1 - it should be
   noted that 4.0.x versions can't be made compatible with newer
   versions anyhow, because the newer superglobals ($_GET, $_REQUEST) are
   missing. Most of this is untested.
   Have a look at PEAR::PHP_Compat for emulation of some of these (it's
   not complete in this regard, too).
*/

#---------------------------------------------------------------- 4.0.7 ---

#-- simulate superglobals
# you still had to put "global $_REQUEST,$_GET,..." into any function that
# used them - so this workaround is not all too useful anyhow, you should
# not accept PHP versions prior 4.0.7 for your scripts in any case!
if (!isset($GLOBALS["_REQUEST"])) {
   $GLOBALS["_GET"] = & $HTTP_GET_VARS;
   $GLOBALS["_POST"] = & $HTTP_POST_VARS;
   $GLOBALS["_SERVER"] = & $HTTP_SERVER_VARS;
   $GLOBALS["_ENV"] = & $HTTP_ENV_VARS;
   $GLOBALS["_COOKIE"] = & $HTTP_COOKIE_VARS;
   $GLOBALS["_FILES"] = & $HTTP_POST_FILES;
   $GLOBALS["_REQUEST"] = array_merge($HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS);
}


#---------------------------------------------------------------- 4.0.6 ---


#-- uses callback function to remove entries from array
if (!function_exists("array_filter")) {
   function array_filter($array, $callback="is_int") {
      foreach ($array as $key=>$val) {
         if (!call_user_func_array($callback, array($val))) {
            unset($array[$key]);
         }
      }
      return($array);
   }
}


#-- uses callback function to change array values, multiple input arrays
if (!function_exists("array_map")) {
   function array_map() {
      $arrays = get_func_args();
      $callback = shift($arrays);
      $r = &$arrays[0];
      foreach ($r as $key=>$val) {
         $val = call_user_func_array($callback, $arrays);
         $r[$key] = $val;
      }
      return($r);
   }
}


#-- checks for existence or only syntax of function or obj/class+method name
if (!function_exists("is_callable")) {
   function is_callable($var, $syntax_only=0) {
      $a = get_func_args();
      if (count($a) >= 3) {
         $fin = & $a[2];
      }

      #-- class/object+method
      if (is_array($var)) {
         if (count($var)!=2) {
            return false;
         }
         list($obj, $method) = $var;
         $class = $obj;
         if (is_object($obj)) {
            $class = get_class($obj);
         }

         if ($syntax_only) {
            $r = preg_match('/^\w+$/', $method);
            if (!is_object($obj)) {
               $r = $r && preg_match('/^\w+$/', $obj);
            }
         }
         else {
            if (is_object($obj)) {
               $r = method_exists($obj, $method);
            }
            else {
               $all = get_class_methods($obj);
               $r = in_array($method, $all);
            }
         }
         if ($r) { $fin = strtolower("$class:$method"); }
      }
      #-- simple function name
      elseif (is_string($var)) {
         if ($syntax_only) {
            $r = preg_match('/^\w+$/', $var);
         }
         else {
            $r = function_exists($var);
         }
         if ($r) { $fin = strtolower($var); }
      }
      #-- ooops
      else {
         $r = false;
      }
      return $r;
   }
}




#---------------------------------------------------------------- 4.0.5 ---
# chroot


#-- return index of value in array
if (!function_exists("array_search")) {
   function array_search($value, $array, $strict=false) {
      $strict = $strict ? true : false;
      foreach ($array as $key=>$v) {
         if ($strict&&($v===$value) || !$strict&&($v==$value)) {
            return($key);
         }
      }
      return(NULL);  // PHP prior 4.2 also did so
   }
}


#-- recursively collapse array into one value (via user callback)
if (!function_exists("array_reduce")) {
   function array_reduce($array, $callback, $value=NULL) {
      foreach ($array as $v) {
         if (is_array($v)) {
            $v = array_reduce($v, $callback);
         }
         else {
            $v = call_user_func_array($callback, array($value, $v));
         }
         $value = $v;
      }
      return($value);
   }
}


#-- checks variable to be of a simple type
if (!function_exists("is_scalar")) {
   function is_scalar($var) {
      return( !is_array($var) && !is_object($var) );
   }
}

#-- only static value (mix of C/English/European/US)
if (!function_exists("localeconv")) {
   function localeconv() {
      return array (
        'decimal_point' => '.',
        'thousands_sep' => '',
        'int_curr_symbol' => 'EUR ',   // more international than USD
        'currency_symbol' => '€',      // unnamed/trans currency symbol
        'mon_decimal_point' => '.',
        'mon_thousands_sep' => ',',
        'positive_sign' => '',
        'negative_sign' => '-',
        'int_frac_digits' => 2,
        'frac_digits' => 2,
        'p_cs_precedes' => 1,
        'p_sep_by_space' => 0,
        'n_cs_precedes' => 1,
        'n_sep_by_space' => 0,
        'p_sign_posn' => 1,
        'n_sign_posn' => 1,
        'grouping' => array (0=>3, 1=>3,),
        'mon_grouping' => array(0=>3, 1=>3,),
      );
   }
}


#-- function by name
if (!function_exists("call_user_func_array")) {
   function call_user_func_array($callback, $param_array=array()) {
      if ($param_array) {
         $param_array = array_values($param_array);
         $params = "'" . implode("','", $param_array) . "'";
      }
      if (is_array($callback)) {
         $obj = &$callback[0];
         $method = $callback[1];
         if (!method_exists($obj, $method)) {
            trigger_error("call_user_method_array: method '$method' does not exist", E_ERROR);
         }
         elseif (is_object($obj)) {
            eval("return \$obj->$method($params);");
         }
         else {
            eval("return $obj::$method($params);");
         }
      }
      elseif (!function_exists("$callback")) {
         trigger_error("call_user_func_array: function '$method' does not exist", E_ERROR);
      }
      else {
         switch (count($param_array)) {
            case 0:
               return $callback();
            case 1:
               return $callback($param_array[0]);
            case 2:
               return $callback($param_array[0], $param_array[1]);
            case 3:
               return $callback($param_array[0], $param_array[1], $param_array[2]);
            case 4:
               return $callback($param_array[0], $param_array[1], $param_array[2], $param_array[3]);
            default:
               eval("return $callback($params);");
         }
      }
   }
   function call_user_method_array($method, &$obj, $param_array=array()) {
      call_user_func_array(array(&$obj, $method), $param_array);
   }
}




#---------------------------------------------------------------- 4.0.4 ---



#-- adds all values of given array into total sum
if (!function_exists("array_sum")) {
   function array_sum($array) {
      $sum = 0;
      foreach ($array as $val) {
         $sum += $val;
      }
      return $sum;
   }
}

#-- value of constant (if their name was returned as string from somewhere)
if (!function_exists("constant")) {
   function constant($name) {
      if (defined($name)) {
         eval("return $name");
      }
      else {
         return NULL;
      }
   }
}

#-- more a language construct
if (!function_exists("is_null")) {
   function is_null($var) {
      return($var === NULL);
   }
}



#---------------------------------------------------------------- 4.0.3 ---
# register_tick_function
# unregister_tick_function

if (!function_exists("pathinfo")) {
   function pathinfo($fn) {
      preg_match("#^(?:(.+)/)?([^/]+?(?:\.([^/\.]+))?)$#", $fn, $uu);
      return array(
         "dirname" => $uu[1],
         "basename" => $uu[2],
         "extension" => $uu[3],
      );
   }
}

if (!function_exists("escapeshellarg")) {
   function escapeshellarg($arg) {
      $arg = str_replace("'", "'\\''", $arg);
      return "'$arg'";
   }
}

if (!function_exists("is_uploaded_file")) {
   function is_uploaded_file($fn) {
      ( $dir = get_cfg_var("upload_tmp_dir") )
       or
      ( $dir = dirname(tempnam("", "")) );
      return( realpath($dir) == realpath(dirname($fn)) );
   }
}

if (!function_exists("move_uploaded_file")) {
   function move_uploaded_file($fn, $dest) {
      if (is_uploaded_file($fn)) {
         return copy($fn, $dest) && unlink($fn);
      }
   }
}


#---------------------------------------------------------------- 4.0.2 ---
# ob_get_length



if (!function_exists("strncasecmp")) {
   function strncasecmp($str1, $str2, $len=0) {
      if ($len > 0) {
         $str1 = substr($str1, 0, $len);
         $str2 = substr($str2, 0, $len);
      }
      return strcasecmp($str1, $str2);
   }
}


if (!function_exists("wordwrap")) {
   function wordwrap($text, $width=75, $break="\n", $hardcut=0) {
      $out = "";
      foreach (explode("\n", $text) as $line) {
         if ($out) {
            $out .= "\n";
         }
         while (strlen($line)) {
            if ($hardcut) {
               $l = $width;
            }
            else {
               $l = strrpos(substr($text, 0, $width), " ");
               if ($l && ($l < strlen($line))) {
                  $l = strlen($line);
               }
               if ($l === false) {
                  $l = $width;
               }
            }
            $out .= substr($line, 0, $l);
            $out .= "\n";
            $line = substr(0, $l);
         }
      }
      return($out);
   }
}

if (!function_exists("php_uname")) {
   function php_uname($mode="a") {
      switch ($mode) {
         case "s":  $p = "--kernel-name";  break;
         case "n":  $p = "--node-name";  break;
         case "r":  $p = "--release";  break;
         case "v":  $p = "--kernel-version";  break;
         case "m":  $p = "--machine";  break;
         default:  $p = "--all";  break;
      }
      return `uname $p`;
   }
}



#---------------------------------------------------------------- 4.0.1 ---
# levensth
# fflush() - unimplementable
# array_unique
# array_diff
# array_intersect
# array_merge_recursive
# crc32
# fscanf
# sscanf
# str_pad
# set_file_buffer
# spliti

if (!function_exists("php_sapi_name")) {
   function php_sapi_name() {
      if (isset($_ENV["CGI_INTERFACE"])) {
         return "cgi";
      }
      elseif (strpos($_ENV["SERVER_SOFTWARE"], "Apache") !== false) {
         return "apache";
      }
      // ...
      else {
         return "cgi";  // the silly "cli" variation didn't exist before 4.2
      }
   }
}

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































Deleted ext/openssl.php.

1
2
3
4
5
<?php
/*
   Ok, that's a joke. (Not that this wasn't possible, though ...)
*/
?>
<
<
<
<
<










Added ext/pdo.pgsql.php.





















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
<?php if (!class_exists("PDO_PGSQL")) {
/** File PDO_pgsql.class.php		*
 *(C) Andrea Giammarchi [2005/10/13]	*/

// Requires PDOStatement_pgsql.class.php , drived by PDO.class.php file
#<builtin>#require_once('PDOStatement_pgsql.class.php');

/**
 * Class PDO_pgsql
 * 	This class is used from class PDO to manage a PostgreSQL database.
 *      Look at PDO.clas.php file comments to know more about PostgreSQL connection.
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO.class.php
 * 			PDOStatement_pgsql.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/13
 * @LastModified	2005/10/14 12:30
 * @Version		0.1 - tested
 */ 
class PDO_pgsql {
	
	/**
	 * 'Private' variables:
	 *	__connection:Resource		Database connection
         *	__dbinfo:String			Database connection params
         *      __persistent:Boolean		Connection mode, is true on persistent, false on normal (deafult) connection
         *      __errorCode:String		Last error code
         *      __errorInfo:Array		Detailed errors
	 *      __result:Resource		Last query resource
	 */
	var $__connection;
	var $__dbinfo;
	var $__persistent = false;
	var $__errorCode = '';
	var $__errorInfo = Array('');
	var $__result = null;
	
	/**
	 * Public constructor:
	 *	Checks connection and database selection
         *       	new PDO_pgsql( &$host:String, &$db:String, &$user:String, &$pass:String )
	 * @Param	String		Database connection params
	 */
	function PDO_pgsql(&$string_dsn) {
		if(!@$this->__connection = &pg_connect($string_dsn))
			$this->__setErrors('DBCON', true);
		else
			$this->__dbinfo = &$string_dsn;
	}
	
	/** NOT NATIVE BUT MAYBE USEFULL FOR PHP < 5.1 PDO DRIVER
	 * Public method
         * Calls pg_close function.
	 *	this->close( Void ):Boolean
         * @Return	Boolean		True on success, false otherwise
	 */
	function close() {
		$result = is_resource($this->__connection);
		if($result)
			pg_close($this->__connection);
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns a code rappresentation of an error
         *       	this->errorCode( void ):String
         * @Return	String		String rappresentation of the error
	 */
	function errorCode() {
		return $this->__errorCode;
	}
	
	/**
	 * Public method:
	 *	Returns an array with error informations
         *       	this->errorInfo( void ):Array
         * @Return	Array		Array with 3 keys:
         * 				0 => error code
         *                              1 => error number
         *                              2 => error string
	 */
	function errorInfo() {
		return $this->__errorInfo;
	}
	
	/**
	 * Public method:
	 *	Excecutes a query and returns affected rows
         *       	this->exec( $query:String ):Mixed
         * @Param	String		query to execute
         * @Return	Mixed		Number of affected rows or false on bad query.
	 */
	function exec($query) {
		$result = 0;
		$this->__uquery($query);
		if(!is_null($this->__result))
			$result = pg_affected_rows($this->__result);
		if(is_null($result))
			$result = false;
		return $result;
	}
	
	/** NOT REALLY SUPPORTED, returned value is not last inserted id
	 * Public method:
	 *	Returns pg_last_oid function
         *       	this->lastInsertId( void ):String
         * @Return	String		OID returned from Postgre
	 */
	function lastInsertId() {
		$result = 0;
		if(!is_null($this->__result))
			$result =  pg_last_oid($this->__result);
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns a new PDOStatement
         *       	this->prepare( $query:String, $array:Array ):PDOStatement
         * @Param	String		query to prepare
         * @Param	Array		this variable is not used but respects PDO original accepted parameters
         * @Return	PDOStatement	new PDOStatement to manage
	 */
	function prepare($query, $array = Array()) {
		return new PDOStatement_pgsql($query, $this->__connection, $this->__dbinfo);
	}
	
	/**
	 * Public method:
	 *	Executes directly a query and returns an array with result or false on bad query
         *       	this->query( $query:String ):Mixed
         * @Param	String		query to execute
         * @Return	Mixed		false on error, array with all info on success
	 */
	function query($query) {
		$query = pg_prepare($this->__connection, "__pdo_query__", $query);
		$query = pg_execute($this->__connection, "__pdo_query__");
		$this->__errorCode = &$query->state;
		if($query) {
			$result = Array();
			while($r = pg_fetch_assoc($query))
				array_push($result, $r);
		}
		else {
			$result = false;
			$this->__setErrors('SQLER');
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->quote( $string:String ):String
         * @Param	String		string to quote
         * @Return	String		a correctly quoted string
	 */
	function quote($string) {
		return ("'".pg_escape_string($string)."'");
	}
	
	
	// NOT TOTALLY SUPPORTED PUBLIC METHODS
        /**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->getAttribute( $attribute:Integer ):Mixed
         * @Param	Integer		a constant [	PDO_ATTR_SERVER_INFO,
         * 						PDO_ATTR_SERVER_VERSION,
         *                                              PDO_ATTR_CLIENT_VERSION,
         *                                              PDO_ATTR_PERSISTENT	]
         * @Return	Mixed		correct information or false
	 */
	function getAttribute($attribute) {
		$result = false;
		switch($attribute) {
			case PDO_ATTR_SERVER_INFO:
				$result = pg_parameter_status($this->__connection, 'server_encoding');
				break;
			case PDO_ATTR_SERVER_VERSION:
				$result = pg_parameter_status($this->__connection, 'server_version');
				break;
			case PDO_ATTR_CLIENT_VERSION:
				$result = pg_parameter_status($this->__connection, 'server_version');
				$result .= ' '.pg_parameter_status($this->__connection, 'client_encoding');
				break;
			case PDO_ATTR_PERSISTENT:
				$result = $this->__persistent;
				break;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets database attributes, in this version only connection mode.
         *       	this->setAttribute( $attribute:Integer, $mixed:Mixed ):Boolean
         * @Param	Integer		PDO_* constant, in this case only PDO_ATTR_PERSISTENT
         * @Param	Mixed		value for PDO_* constant, in this case a Boolean value
         * 				true for permanent connection, false for default not permament connection
         * @Return	Boolean		true on change, false otherwise
	 */
	function setAttribute($attribute, $mixed) {
		$result = false;
		if($attribute === PDO_ATTR_PERSISTENT && $mixed != $this->__persistent) {
			$result = true;
			$this->__persistent = (boolean) $mixed;
			pg_close($this->__connection);
			if($this->__persistent === true)
				$this->__connection = &pg_connect($this->__dbinfo);
			else
				$this->__connection = &pg_pconnect($this->__dbinfo);
		}
		return $result;
	}
	
	
	// UNSUPPORTED PUBLIC METHODS
	function beginTransaction() {
		return false;
	}
	
	function commit() {
		return false;
	}
	
	function rollBack() {
		return false;
	}
	
	
	// PRIVATE METHODS [ UNCOMMENTED ]
	function __setErrors($er) {
		if(!is_string($this->__errorCode))
			$errno = $this->__errorCode;
		if(!is_resource($this->__connection)) {
			$errno = 1;
			$errst = pg_last_error();
		}
		else {
			$errno = 1;
			$errst = pg_last_error($this->__connection);
		}
		$this->__errorCode = &$er;
		$this->__errorInfo = Array($this->__errorCode, $errno, $errst);
	}
	
	function __uquery(&$query) {
		if(!@$this->__result = pg_query($this->__connection, $query)) {
			$this->__setErrors('SQLER');
			$this->__result = null;
		}
		return $this->__result;
	}
}
?><?php
/** File PDOStatement_pgsql.class.php	*
 *(C) Andrea Giammarchi [2005/10/13]	*/

/**
 * Class PDOStatement_pgsql
 * 	This class is used from class PDO_pgsql to manage a PostgreSQL database.
 *      Look at PDO.clas.php file comments to know more about PostgreSQL connection.
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO.class.php
 * 			PDO_pgsql.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/19
 * @LastModified	2006/01/29 09:30 [fixed execute bug]
 * @Version		0.1b - tested
 */ 
class PDOStatement_pgsql {
	
	/**
	 * 'Private' variables:
	 *	__connection:Resource		Database connection
         *	__dbinfo:Array			Array with 4 elements used to manage connection
         *      __persistent:Boolean		Connection mode, is true on persistent, false on normal (deafult) connection
         *      __query:String			Last query used
         *      __result:Resource		Last result from last query
         *      __fetchmode:Integer		constant PDO_FETCH_* result mode
         *      __errorCode:String		Last error string code
         *      __errorInfo:Array		Last error informations, code, number, details
         *      __boundParams:Array		Stored bindParam
	 */
	var $__connection;
	var $__dbinfo;
	var $__persistent = false;
	var $__query = '';
	var $__result = null;
	var $__fetchmode = PDO::FETCH_BOTH;
	var $__errorCode = '';
	var $__errorInfo = Array('');
	var $__boundParams = Array();
	
	/**
	 * Public constructor:
	 *	Called from PDO to create a PDOStatement for this database
         *       	new PDOStatement_pgsql( &$__query:String, &$__connection:Resource, $__dbinfo:String )
	 * @Param	String		query to prepare
         * @Param	Resource	database connection
         * @Param	String		database file name
	 */
	function PDOStatement_pgsql(&$__query, &$__connection, &$__dbinfo) {
		$this->__query = &$__query;
		$this->__connection = &$__connection;
		$this->__dbinfo = &$__dbinfo;
	}
	
	/**
	 * Public method:
	 *	Replace ? or :named values to execute prepared query
         *       	this->bindParam( $mixed:Mixed, &$variable:Mixed, $type:Integer, $lenght:Integer ):Void
         * @Param	Mixed		Integer or String to replace prepared value
         * @Param	Mixed		variable to replace
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
	 */
	function bindParam($mixed, &$variable, $type = null, $lenght = null) {
		if(is_string($mixed))
			$this->__boundParams[$mixed] = $variable;
		else
			array_push($this->__boundParams, $variable);
	}
	
	/**
	 * Public method:
	 *	Checks if query was valid and returns how may fields returns
         *       	this->columnCount( void ):Void
	 */
	function columnCount() {
		$result = 0;
		if(!is_null($this->__result))
			$result = pg_num_fields($this->__result);
		return $result; 
	}
	
	/**
	 * Public method:
	 *	Returns a code rappresentation of an error
         *       	this->errorCode( void ):String
         * @Return	String		String rappresentation of the error
	 */
	function errorCode() {
		return $this->__errorCode;
	}
	
	/**
	 * Public method:
	 *	Returns an array with error informations
         *       	this->errorInfo( void ):Array
         * @Return	Array		Array with 3 keys:
         * 				0 => error code
         *                              1 => error number
         *                              2 => error string
	 */
	function errorInfo() {
		return $this->__errorInfo;
	}
	
	/**
	 * Public method:
	 *	Excecutes a query and returns true on success or false.
         *       	this->exec( $array:Array ):Boolean
         * @Param	Array		If present, it should contain all replacements for prepared query
         * @Return	Boolean		true if query has been done without errors, false otherwise
	 */
	function execute($array = Array()) {
		if(count($this->__boundParams) > 0)
			$array = &$this->__boundParams;
		$__query = $this->__query;
		if(count($array) > 0) {
			foreach($array as $k => $v) {
				if(!is_int($k) || substr($k, 0, 1) === ':') {
					if(!isset($tempf))
						$tempf = $tempr = array();
					array_push($tempf, $k);
					array_push($tempr, "'".pg_escape_string($v)."'");
				}
				else {
					$parse = create_function('$v', 'return "\'".pg_escape_string($v)."\'";');
					$__query = preg_replace("/(\?)/e", '$parse($array[$k++]);', $__query);
					break;
				}
			}
			if(isset($tempf))
				$__query = str_replace($tempf, $tempr, $__query);
		}
		if(is_null($this->__result = &$this->__uquery($__query)))
			$keyvars = false;
		else
			$keyvars = true;
		$this->__boundParams = array();
		return $keyvars;
	}
	
	/**
	 * Public method:
	 *	Returns, if present, next row of executed query or false.
         *       	this->fetch( $mode:Integer, $cursor:Integer, $offset:Integer ):Mixed
         * @Param	Integer		PDO_FETCH_* constant to know how to read next row, default PDO_FETCH_BOTH
         * 				NOTE: if $mode is omitted is used default setted mode, PDO_FETCH_BOTH
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Return	Mixed		Next row of executed query or false if there is nomore.
	 */
	function fetch($mode = PDO_FETCH_BOTH, $cursor = null, $offset = null) {
		if(func_num_args() == 0)
			$mode = &$this->__fetchmode;
		$result = false;
		if(!is_null($this->__result)) {
			switch($mode) {
				case PDO_FETCH_NUM:
					$result = pg_fetch_row($this->__result);
					break;
				case PDO_FETCH_ASSOC:
					$result = pg_fetch_assoc($this->__result);
					break;
				case PDO_FETCH_OBJ:
					$result = pg_fetch_object($this->__result);
					break;
				case PDO_FETCH_BOTH:
				default:
					$result = pg_fetch_array($this->__result);
					break;
			}
		}
		if(!$result)
			$this->__result = null;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns an array with all rows of executed query.
         *       	this->fetchAll( $mode:Integer ):Array
         * @Param	Integer		PDO_FETCH_* constant to know how to read all rows, default PDO_FETCH_BOTH
         * 				NOTE: this doesn't work as fetch method, then it will use always PDO_FETCH_BOTH
         *                                    if this param is omitted
         * @Return	Array		An array with all fetched rows
	 */
	function fetchAll($mode = PDO_FETCH_BOTH) {
		$result = array();
		if(!is_null($this->__result)) {
			switch($mode) {
				case PDO_FETCH_NUM:
					while($r = pg_fetch_row($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_ASSOC:
					while($r = pg_fetch_assoc($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_OBJ:
					while($r = pg_fetch_object($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_BOTH:
				default:
					while($r = pg_fetch_array($this->__result))
						array_push($result, $r);
					break;
			}
		}
		$this->__result = null;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns, if present, first column of next row of executed query
         *       	this->fetchSingle( void ):Mixed
         * @Return	Mixed		Null or next row's first column
	 */
	function fetchSingle() {
		$result = null;
		if(!is_null($this->__result)) {
			$result = @pg_fetch_row($this->__result);
			if($result)
				$result = $result[0];
			else
				$this->__result = null;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns number of last affected database rows
         *       	this->rowCount( void ):Integer
         * @Return	Integer		number of last affected rows
         * 				NOTE: works with INSERT, UPDATE and DELETE query type
	 */
	function rowCount() {
		$result = 0;
		if(!is_null($this->__result))
			$result = pg_affected_rows($this->__result);
		return $result;
	}
	
	
	// NOT TOTALLY SUPPORTED PUBLIC METHODS	
	/**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->getAttribute( $attribute:Integer ):Mixed
         * @Param	Integer		a constant [	PDO_ATTR_SERVER_INFO,
         * 						PDO_ATTR_SERVER_VERSION,
         *                                              PDO_ATTR_CLIENT_VERSION,
         *                                              PDO_ATTR_PERSISTENT	]
         * @Return	Mixed		correct information or false
	 */
	function getAttribute($attribute) {
		$result = false;
		switch($attribute) {
			case PDO_ATTR_SERVER_INFO:
				$result = pg_parameter_status($this->__connection, 'server_encoding');
				break;
			case PDO_ATTR_SERVER_VERSION:
				$result = pg_parameter_status($this->__connection, 'server_version');
				break;
			case PDO_ATTR_CLIENT_VERSION:
				$result = pg_parameter_status($this->__connection, 'server_version');
				$result .= ' '.pg_parameter_status($this->__connection, 'client_encoding');
				break;
			case PDO_ATTR_PERSISTENT:
				$result = $this->__persistent;
				break;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets database attributes, in this version only connection mode.
         *       	this->setAttribute( $attribute:Integer, $mixed:Mixed ):Boolean
         * @Param	Integer		PDO_* constant, in this case only PDO_ATTR_PERSISTENT
         * @Param	Mixed		value for PDO_* constant, in this case a Boolean value
         * 				true for permanent connection, false for default not permament connection
         * @Return	Boolean		true on change, false otherwise
	 */
	function setAttribute($attribute, $mixed) {
		$result = false;
		if($attribute === PDO_ATTR_PERSISTENT && $mixed != $this->__persistent) {
			$result = true;
			$this->__persistent = (boolean) $mixed;
			pg_close($this->__connection);
			if($this->__persistent === true)
				$this->__connection = &pg_connect($this->__dbinfo);
			else
				$this->__connection = &pg_pconnect($this->__dbinfo);
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets default fetch mode to use with this->fetch() method.
         *       	this->setFetchMode( $mode:Integer ):Boolean
         * @Param	Integer		PDO_FETCH_* constant to use while reading an execute query with fetch() method.
         * 				NOTE: PDO_FETCH_LAZY and PDO_FETCH_BOUND are not supported
         * @Return	Boolean		true on change, false otherwise
	 */
	function setFetchMode($mode) {
		$result = false;
		switch($mode) {
			case PDO_FETCH_NUM:
			case PDO_FETCH_ASSOC:
			case PDO_FETCH_OBJ:
			case PDO_FETCH_BOTH:
				$result = true;
				$this->__fetchmode = &$mode;
				break;
		}
		return $result;
	}
	
	
	// UNSUPPORTED PUBLIC METHODS
        function bindColumn($mixewd, &$param, $type = null, $max_length = null, $driver_option = null) {
		return false;
	}
	
	function __setErrors($er) {
		if(!is_string($this->__errorCode))
			$errno = $this->__errorCode;
		if(!is_resource($this->__connection)) {
			$errno = 1;
			$errst = pg_last_error();
		}
		else {
			$errno = 1;
			$errst = pg_last_error($this->__connection);
		}
		$this->__errorCode = &$er;
		$this->__errorInfo = Array($this->__errorCode, $errno, $errst);
	}
	
	function __uquery(&$query) {
		if(!@$query = pg_query($this->__connection, $query)) {
			$this->__setErrors('SQLER');
			$query = null;
		}
		return $query;
	}
	
}


}//if!class_exists
?>

Changes to 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")) {






























}

















































































































































?>
|
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
<?php if(!class_exists('PDO')) {
/**
 * title: PDO
 * description: PDO emulation for PHP 5.0 and 4.x, with PDO_MySQL built-in
 * author: Andrea Giammarchi
 * author_url: http://www.devpro.it/
 * license: PHPL 2.02
 * url: http://webscripts.softpedia.com/script/PHP-Clases/PDO-for-PHP-4-12854.html
 * version: 0.1b
 * api: php
 * priority: auto
 * category: database
 *
 *
 * File PDO.class.php			*
 * 	Porting of native PHP 5.1 PDO	*
 *      object usable with PHP 4.X.X	*
 *      and PHP 5.0.X version.		*
 * ------------------------------------ *     
 * (C) Andrea Giammarchi [2005/10/19]	*
 * ____________________________________
 *
 *
 * This package includes the PDO MySQL driver. To also get support for
 * Postgres and SQLite, include pdo.pgsql.php and .sqlite.php as well.
 * Of course it's not a complete implementation, but believed to be
 * compatible to even the early PHP4 versions.
 *
 * IMPORTANT: For compatibility with PHP 5.0 and this emulation, you must
 * use the global PDO constants, and not the static PDO:: class versions.
 * PDO_FETCH_ASSOC, PDO_ATTR_*, ... as seen below.
 *
 */

	
// SUPPORTED STATIC ENVIROMENT VARIABLES
define('PDO_ATTR_SERVER_VERSION', 4);	// server version
define('PDO_ATTR_CLIENT_VERSION', 5);	// client version
define('PDO_ATTR_SERVER_INFO', 6);	// server informations
define('PDO_ATTR_PERSISTENT', 12);	// connection mode, persistent or normal

// SUPPORTED STATIC PDO FETCH MODE VARIABLES
define('PDO_FETCH_ASSOC', 2);		// such mysql_fetch_assoc
define('PDO_FETCH_NUM', 3);		// such mysql_fetch_row
define('PDO_FETCH_BOTH', 4);		// such mysql_fetch_array
define('PDO_FETCH_OBJ', 5);		// such mysql_fetch_object

// UNSUPPORTED STATIC PDO FETCH MODE VARIABLES
define('PDO_FETCH_LAZY', 1);		// usable but not supported, default is PDO_FETCH_BOTH and will be used
define('PDO_FETCH_BOUND', 6);		// usable but not supported, default is PDO_FETCH_BOTH and will be used

/**
 * Class PDO
 * 	PostgreSQL, SQLITE and MYSQL PDO support for PHP 4.X.X or PHP 5.0.X users, compatible with PHP 5.1.0 (RC1).
 *
 * DESCRIPTION [directly from http://us2.php.net/manual/en/ref.pdo.php]
 * 	The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP.
 *      Each database driver that implements the PDO interface can expose database-specific features as regular extension functions.
 *      Note that you cannot perform any database functions using the PDO extension by itself;
 *      you must use a database-specific PDO driver to access a database server.
 *
 * HOW TO USE
 * 	To know how to use PDO driver and all its methods visit php.net wonderful documentation.
 *      http://us2.php.net/manual/en/ref.pdo.php
 *      In this class some methods are not available and actually this porting is only for MySQL, SQLITE and PostgreSQL.
 *
 * LIMITS
 * 	For some reasons ( time and php used version with this class ) some PDO methods are not availables and
 *      someother are not totally supported.
 *      
 *      PDO :: UNSUPPORTED METHODS:
 *      	- beginTransaction 	[ mysql 3 has not transaction and manage them is possible only with a direct BEGIN 
 *              			  or COMMIT query ]
 *              - commit
 *              - rollback
 *              
 *      PDO :: NOT TOTALLY SUPPORTED METHODS:
 *      	- getAttribute		[ accepts only PDO_ATTR_SERVER_INFO, PDO_ATTR_SERVER_VERSION,
 *              			  PDO_ATTR_CLIENT_VERSION and PDO_ATTR_PERSISTENT attributes ]
 *              - setAttribute		[ supports only PDO_ATTR_PERSISTENT modification ]
 *              - lastInsertId		[ only fo PostgreSQL , returns only pg_last_oid ]
 *
 *      - - - - - - - - - - - - - - - - - - - - 
 *              
 *      PDOStatement :: UNSUPPORTED METHODS:
 *      	- bindColumn 		[ is not possible to undeclare a variable and using global scope is not
 *              			  really a good idea ]
 *              
 *      PDOStatement :: NOT TOTALLY SUPPORTED METHODS:
 *      	- getAttribute		[ accepts only PDO_ATTR_SERVER_INFO, PDO_ATTR_SERVER_VERSION,
 *              			  PDO_ATTR_CLIENT_VERSION and PDO_ATTR_PERSISTENT attributes ]
 *              - setAttribute		[ supports only PDO_ATTR_PERSISTENT modification ]
 *              - setFetchMode		[ supports only PDO_FETCH_NUM, PDO_FETCH_ASSOC, PDO_FETCH_OBJ and
 *              			  PDO_FETCH_BOTH database reading mode ]
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO_mysql.class.php
 *                      PDO_sqlite.class.php
 *                      PDOStatement_mysql.class.php
 *                      PDOStatement_sqlite.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/13
 * @LastModified	2005/12/01 21:40
 * @Version		0.1b - tested, supports only PostgreSQL, MySQL or SQLITE databases
 */ 
class PDO {
	
	/** Modified on 2005/12/01 to support new PDO constants on PHP 5.1.X */
	/*
	--won't work with php4--
	const FETCH_ASSOC = PDO_FETCH_ASSOC;
	const FETCH_NUM = PDO_FETCH_NUM;
	const FETCH_BOTH = PDO_FETCH_BOTH;
	const FETCH_OBJ = PDO_FETCH_OBJ;
	const FETCH_LAZY = PDO_FETCH_LAZY;
	const FETCH_BOUND = PDO_FETCH_BOUND;
	const ATTR_SERVER_VERSION = PDO_ATTR_SERVER_VERSION;
	const ATTR_CLIENT_VERSION = PDO_ATTR_CLIENT_VERSION;
	const ATTR_SERVER_INFO = PDO_ATTR_SERVER_INFO;
	const ATTR_PERSISTENT = PDO_ATTR_PERSISTENT;
	*/
	function FETCH_ASSOC(){return PDO_FETCH_ASSOC;}
	function FETCH_NUM(){return PDO_FETCH_NUM;}
	function FETCH_BOTH(){return PDO_FETCH_BOTH;}
	function FETCH_OBJ(){return PDO_FETCH_OBJ;}
	function FETCH_LAZY(){return PDO_FETCH_LAZY;}
	function FETCH_BOUND(){return PDO_FETCH_BOUND;}
	function ATTR_SERVER_VERSION(){return PDO_ATTR_SERVER_VERSION;}
	function ATTR_CLIENT_VERSION(){return PDO_ATTR_CLIENT_VERSION;}
	function ATTR_SERVER_INFO(){return PDO_ATTR_SERVER_INFO;}
	function ATTR_PERSISTENT(){return PDO_ATTR_PERSISTENT;}
	
	/**
	 * 'Private' variables:
	 *	__driver:PDO_*		Dedicated PDO database class
	 */
	var $__driver;
	
	/**
	 * Public constructor
	 *	http://us2.php.net/manual/en/function.pdo-construct.php
	 */
	function PDO($string_dsn, $string_username = '', $string_password = '', $array_driver_options = null) {
		$con = &$this->__getDNS($string_dsn);
		if($con['dbtype'] === 'mysql') {
			#<builtin>#require_once('PDO_mysql.class.php');
			if(isset($con['port']))
				$con['host'] .= ':'.$con['port'];
			$this->__driver = new PDO_mysql(
				$con['host'],
				$con['dbname'],
				$string_username,
				$string_password
			);
		}
		elseif($con['dbtype'] === 'sqlite2' || $con['dbtype'] === 'sqlite') {
			#<builtin>#require_once('PDO_sqlite.class.php');
			$this->__driver = new PDO_sqlite($con['dbname']);
		}
		elseif($con['dbtype'] === 'pgsql') {
			#<builtin>#require_once('PDO_pgsql.class.php');
			$string_dsn = "host={$con['host']} dbname={$con['dbname']} user={$string_username} password={$string_password}";
			if(isset($con['port']))
				$string_dsn .= " port={$con['port']}";
			$this->__driver = new PDO_pgsql($string_dsn);
		}
	}
	
	/** UNSUPPORTED
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-begintransaction.php
	 */
	function beginTransaction() {
		$this->__driver->beginTransaction();
	}
	
	/** NOT NATIVE BUT MAYBE USEFULL FOR PHP < 5.1 PDO DRIVER
	 * Public method
	 * Calls database_close function.
	 *	this->close( Void ):Boolean
	 * @Return	Boolean		True on success, false otherwise
	 */
	function close() {
		return $this->__driver->close();
	}
	
	/** UNSUPPORTED
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-commit.php
	 */
	function commit() {
		$this->__driver->commit();
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-exec.php
	 */
	function exec($query) {
		return $this->__driver->exec($query);
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-errorcode.php
	 */
	function errorCode() {
		return $this->__driver->errorCode();
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-errorinfo.php
	 */
	function errorInfo() {
		return $this->__driver->errorInfo();
	}
	
	/** NOT TOTALLY UNSUPPORTED
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-getattribute.php
	 */
	function getAttribute($attribute) {
		return $this->__driver->getAttribute($attribute);
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-lastinsertid.php
	 */
	function lastInsertId() {
		return $this->__driver->lastInsertId();
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-prepare.php
	 */
	function prepare($query, $array = Array()) {
		return $this->__driver->prepare($query, $array = Array());
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-query.php
	 */
	function query($query) {
		return $this->__driver->query($query);
	}
	
	/** 
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-quote.php
	 */
	function quote($string) {
		return $this->__driver->quote($string);
	}
	
	/** UNSUPPORTED
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-rollback.php
	 */
	function rollBack() {
		$this->__driver->rollBack();
	}
	
	/** NOT TOTALLY UNSUPPORTED
	 * Public method
	 *	http://us2.php.net/manual/en/function.pdo-setattribute.php
	 */
	function setAttribute($attribute, $mixed) {
		return $this->__driver->setAttribute($attribute, $mixed);
	}
	
	// PRIVATE METHOD [uncommented]
	function __getDNS(&$string) {
		$result = array();
		$pos = strpos($string, ':');
		$parameters = explode(';', substr($string, ($pos + 1)));
		$result['dbtype'] = strtolower(substr($string, 0, $pos));
		for($a = 0, $b = count($parameters); $a < $b; $a++) {
			$tmp = explode('=', $parameters[$a]);
			if(count($tmp) == 2)
				$result[$tmp[0]] = $tmp[1];
			else
				$result['dbname'] = $parameters[$a];
		}
		return $result;
	}
}





?><?php
/** File PDO_mysql.class.php		*
 *(C) Andrea Giammarchi [2005/10/13]	*/

// Requires PDOStatement_mysql.class.php , drived by PDO.class.php file
#<builtin>#require_once('PDOStatement_mysql.class.php');

/**
 * Class PDO_mysql
 * 	This class is used from class PDO to manage a MySQL database.
 *      Look at PDO.clas.php file comments to know more about MySQL connection.
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO.class.php
 * 			PDOStatement_mysql.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/13
 * @LastModified	2005/18/14 12:30
 * @Version		0.1 - tested
 */ 
class PDO_mysql {
	
	/**
	 * 'Private' variables:
	 *	__connection:Resource		Database connection
         *	__dbinfo:Array			Array with 4 elements used to manage connection
         *      __persistent:Boolean		Connection mode, is true on persistent, false on normal (deafult) connection
         *      __errorCode:String		Last error code
         *      __errorInfo:Array		Detailed errors
	 */
	var $__connection;
	var $__dbinfo;
	var $__persistent = false;
	var $__errorCode = '';
	var $__errorInfo = Array('');
	
	/**
	 * Public constructor:
	 *	Checks connection and database selection
         *       	new PDO_mysql( &$host:String, &$db:String, &$user:String, &$pass:String )
	 * @Param	String		host with or without port info
         * @Param	String		database name
         * @Param	String		database user
         * @Param	String		database password
	 */
	function PDO_mysql(&$host, &$db, &$user, &$pass) {
		if(!@$this->__connection = &mysql_connect($host, $user, $pass))
			$this->__setErrors('DBCON');
		else {
			if(!@mysql_select_db($db, $this->__connection))
				$this->__setErrors('DBER');
			else
				$this->__dbinfo = Array($host, $user, $pass, $db);
		}
	}
	
	/** NOT NATIVE BUT MAYBE USEFULL FOR PHP < 5.1 PDO DRIVER
	 * Public method
         * Calls mysql_close function.
	 *	this->close( Void ):Boolean
         * @Return	Boolean		True on success, false otherwise
	 */
	function close() {
		$result = is_resource($this->__connection);
		if($result) {
			mysql_close($this->__connection);
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns a code rappresentation of an error
         *       	this->errorCode( void ):String
         * @Return	String		String rappresentation of the error
	 */
	function errorCode() {
		return $this->__errorCode;
	}
	
	/**
	 * Public method:
	 *	Returns an array with error informations
         *       	this->errorInfo( void ):Array
         * @Return	Array		Array with 3 keys:
         * 				0 => error code
         *                              1 => error number
         *                              2 => error string
	 */
	function errorInfo() {
		return $this->__errorInfo;
	}
	
	/**
	 * Public method:
	 *	Excecutes a query and returns affected rows
         *       	this->exec( $query:String ):Mixed
         * @Param	String		query to execute
         * @Return	Mixed		Number of affected rows or false on bad query.
	 */
	function exec($query) {
		$result = 0;
		if(!is_null($this->__uquery($query)))
			$result = mysql_affected_rows($this->__connection);
		if(is_null($result))
			$result = false;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns last inserted id
         *       	this->lastInsertId( void ):Number
         * @Return	Number		Last inserted id
	 */
	function lastInsertId() {
		return mysql_insert_id($this->__connection);
	}
	
	/**
	 * Public method:
	 *	Returns a new PDOStatement
         *       	this->prepare( $query:String, $array:Array ):PDOStatement
         * @Param	String		query to prepare
         * @Param	Array		this variable is not used but respects PDO original accepted parameters
         * @Return	PDOStatement	new PDOStatement to manage
	 */
	function prepare($query, $array = Array()) {
		return new PDOStatement_mysql($query, $this->__connection, $this->__dbinfo);
	}
	
	/**
	 * Public method:
	 *	Executes directly a query and returns an array with result or false on bad query
         *       	this->query( $query:String ):Mixed
         * @Param	String		query to execute
         * @Return	Mixed		false on error, array with all info on success
	 */
	function query($query) {
		$query = @mysql_unbuffered_query($query, $this->__connection);
		if($query) {
			$result = Array();
			while($r = mysql_fetch_assoc($query))
				array_push($result, $r);
		}
		else {
			$result = false;
			$this->__setErrors('SQLER');
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->quote( $string:String ):String
         * @Param	String		string to quote
         * @Return	String		a correctly quoted string
	 */
	function quote($string) {
		return ('"'.mysql_escape_string($string).'"');
	}
	
	
	// NOT TOTALLY SUPPORTED PUBLIC METHODS
        /**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->getAttribute( $attribute:Integer ):Mixed
         * @Param	Integer		a constant [	PDO_ATTR_SERVER_INFO,
         * 						PDO_ATTR_SERVER_VERSION,
         *                                              PDO_ATTR_CLIENT_VERSION,
         *                                              PDO_ATTR_PERSISTENT	]
         * @Return	Mixed		correct information or false
	 */
	function getAttribute($attribute) {
		$result = false;
		switch($attribute) {
			case PDO_ATTR_SERVER_INFO:
				$result = mysql_get_host_info($this->__connection);
				break;
			case PDO_ATTR_SERVER_VERSION:
				$result = mysql_get_server_info($this->__connection);
				break;
			case PDO_ATTR_CLIENT_VERSION:
				$result = mysql_get_client_info();
				break;
			case PDO_ATTR_PERSISTENT:
				$result = $this->__persistent;
				break;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets database attributes, in this version only connection mode.
         *       	this->setAttribute( $attribute:Integer, $mixed:Mixed ):Boolean
         * @Param	Integer		PDO_* constant, in this case only PDO_ATTR_PERSISTENT
         * @Param	Mixed		value for PDO_* constant, in this case a Boolean value
         * 				true for permanent connection, false for default not permament connection
         * @Return	Boolean		true on change, false otherwise
	 */
	function setAttribute($attribute, $mixed) {
		$result = false;
		if($attribute === PDO_ATTR_PERSISTENT && $mixed != $this->__persistent) {
			$result = true;
			$this->__persistent = (boolean) $mixed;
			mysql_close($this->__connection);
			if($this->__persistent === true)
				$this->__connection = &mysql_pconnect($this->__dbinfo[0], $this->__dbinfo[1], $this->__dbinfo[2]);
			else
				$this->__connection = &mysql_connect($this->__dbinfo[0], $this->__dbinfo[1], $this->__dbinfo[2]);
			mysql_select_db($this->__dbinfo[3], $this->__connection);
		}
		return $result;
	}
	
	
	// UNSUPPORTED PUBLIC METHODS
	function beginTransaction() {
		return false;
	}
	
	function commit() {
		return false;
	}
	
	function rollBack() {
		return false;
	}
	
	
	// PRIVATE METHODS [ UNCOMMENTED ]
	function __setErrors($er) {
		if(!is_resource($this->__connection)) {
			$errno = mysql_errno();
			$errst = mysql_error();
		}
		else {
			$errno = mysql_errno($this->__connection);
			$errst = mysql_error($this->__connection);
		}
		$this->__errorCode = &$er;
		$this->__errorInfo = Array($this->__errorCode, $errno, $errst);
	}
	
	function __uquery(&$query) {
		if(!@$query = mysql_query($query, $this->__connection)) {
			$this->__setErrors('SQLER');
			$query = null;
		}
		return $query;
	}
}







?><?php
/** File PDOStatement_mysql.class.php	*
 *(C) Andrea Giammarchi [2005/10/13]	*/

/**
 * Class PDOStatement_mysql
 * 	This class is used from class PDO_mysql to manage a MySQL database.
 *      Look at PDO.clas.php file comments to know more about MySQL connection.
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO.class.php
 * 			PDO_mysql.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/13
 * @LastModified	2006/01/29 09:30 [fixed execute bug]
 * @Version		0.1b - tested
 */ 
class PDOStatement_mysql {
	
	/**
	 * 'Private' variables:
	 *	__connection:Resource		Database connection
         *	__dbinfo:Array			Array with 4 elements used to manage connection
         *      __persistent:Boolean		Connection mode, is true on persistent, false on normal (deafult) connection
         *      __query:String			Last query used
         *      __result:Resource		Last result from last query
         *      __fetchmode:Integer		constant PDO_FETCH_* result mode
         *      __errorCode:String		Last error string code
         *      __errorInfo:Array		Last error informations, code, number, details
         *      __boundParams:Array		Stored bindParam
	 */
	var $__connection;
	var $__dbinfo;
	var $__persistent = false;
	var $__query = '';
	var $__result = null;
	var $__fetchmode = PDO::FETCH_BOTH;
	var $__errorCode = '';
	var $__errorInfo = Array('');
	var $__boundParams = Array();
	
	/**
	 * Public constructor:
	 *	Called from PDO to create a PDOStatement for this database
         *       	new PDOStatement_sqlite( &$__query:String, &$__connection:Resource, $__dbinfo:Array )
	 * @Param	String		query to prepare
         * @Param	Resource	database connection
         * @Param	Array		4 elements array to manage connection
	 */
	function PDOStatement_mysql(&$__query, &$__connection, &$__dbinfo) {
		$this->__query = &$__query;
		$this->__connection = &$__connection;
		$this->__dbinfo = &$__dbinfo;
	}
	
	/**
	 * Public method:
	 *	Replace ? or :named values to execute prepared query
         *       	this->bindParam( $mixed:Mixed, &$variable:Mixed, $type:Integer, $lenght:Integer ):Void
         * @Param	Mixed		Integer or String to replace prepared value
         * @Param	Mixed		variable to replace
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
	 */
	function bindParam($mixed, &$variable, $type = null, $lenght = null) {
		if(is_string($mixed))
			$this->__boundParams[$mixed] = $variable;
		else
			array_push($this->__boundParams, $variable);
	}
	
	/**
	 * Public method:
	 *	Checks if query was valid and returns how may fields returns
         *       	this->columnCount( void ):Void
	 */
	function columnCount() {
		$result = 0;
		if(!is_null($this->__result))
			$result = mysql_num_fields($this->__result);
		return $result; 
	}
	
	/**
	 * Public method:
	 *	Returns a code rappresentation of an error
         *       	this->errorCode( void ):String
         * @Return	String		String rappresentation of the error
	 */
	function errorCode() {
		return $this->__errorCode;
	}
	
	/**
	 * Public method:
	 *	Returns an array with error informations
         *       	this->errorInfo( void ):Array
         * @Return	Array		Array with 3 keys:
         * 				0 => error code
         *                              1 => error number
         *                              2 => error string
	 */
	function errorInfo() {
		return $this->__errorInfo;
	}
	
	/**
	 * Public method:
	 *	Excecutes a query and returns true on success or false.
         *       	this->exec( $array:Array ):Boolean
         * @Param	Array		If present, it should contain all replacements for prepared query
         * @Return	Boolean		true if query has been done without errors, false otherwise
	 */
	function execute($array = Array()) {
		if(count($this->__boundParams) > 0)
			$array = &$this->__boundParams;
		$__query = $this->__query;
		if(count($array) > 0) {
			foreach($array as $k => $v) {
				if(!is_int($k) || substr($k, 0, 1) === ':') {
					if(!isset($tempf))
						$tempf = $tempr = array();
					array_push($tempf, $k);
					array_push($tempr, '"'.mysql_escape_string($v).'"');
				}
				else {
					$parse = create_function('$v', 'return \'"\'.mysql_escape_string($v).\'"\';');
					$__query = preg_replace("/(\?)/e", '$parse($array[$k++]);', $__query);
					break;
				}
			}
			if(isset($tempf))
				$__query = str_replace($tempf, $tempr, $__query);
		}
		if(is_null($this->__result = &$this->__uquery($__query)))
			$keyvars = false;
		else
			$keyvars = true;
		$this->__boundParams = array();
		return $keyvars;
	}
	
	/**
	 * Public method:
	 *	Returns, if present, next row of executed query or false.
         *       	this->fetch( $mode:Integer, $cursor:Integer, $offset:Integer ):Mixed
         * @Param	Integer		PDO_FETCH_* constant to know how to read next row, default PDO_FETCH_BOTH
         * 				NOTE: if $mode is omitted is used default setted mode, PDO_FETCH_BOTH
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Return	Mixed		Next row of executed query or false if there is nomore.
	 */
	function fetch($mode = PDO_FETCH_BOTH, $cursor = null, $offset = null) {
		if(func_num_args() == 0)
			$mode = &$this->__fetchmode;
		$result = false;
		if(!is_null($this->__result)) {
			switch($mode) {
				case PDO_FETCH_NUM:
					$result = mysql_fetch_row($this->__result);
					break;
				case PDO_FETCH_ASSOC:
					$result = mysql_fetch_assoc($this->__result);
					break;
				case PDO_FETCH_OBJ:
					$result = mysql_fetch_object($this->__result);	
					break;
				case PDO_FETCH_BOTH:
				default:
					$result = mysql_fetch_array($this->__result);
					break;
			}
		}
		if(!$result)
			$this->__result = null;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns an array with all rows of executed query.
         *       	this->fetchAll( $mode:Integer ):Array
         * @Param	Integer		PDO_FETCH_* constant to know how to read all rows, default PDO_FETCH_BOTH
         * 				NOTE: this doesn't work as fetch method, then it will use always PDO_FETCH_BOTH
         *                                    if this param is omitted
         * @Return	Array		An array with all fetched rows
	 */
	function fetchAll($mode = PDO_FETCH_BOTH) {
		$result = array();
		if(!is_null($this->__result)) {
			switch($mode) {
				case PDO_FETCH_NUM:
					while($r = mysql_fetch_row($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_ASSOC:
					while($r = mysql_fetch_assoc($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_OBJ:
					while($r = mysql_fetch_object($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_BOTH:
				default:
					while($r = mysql_fetch_array($this->__result))
						array_push($result, $r);
					break;
			}
		}
		$this->__result = null;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns, if present, first column of next row of executed query
         *       	this->fetchSingle( void ):Mixed
         * @Return	Mixed		Null or next row's first column
	 */
	function fetchSingle() {
		$result = null;
		if(!is_null($this->__result)) {
			$result = @mysql_fetch_row($this->__result);
			if($result)
				$result = $result[0];
			else
				$this->__result = null;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns number of last affected database rows
         *       	this->rowCount( void ):Integer
         * @Return	Integer		number of last affected rows
         * 				NOTE: works with INSERT, UPDATE and DELETE query type
	 */
	function rowCount() {
		return mysql_affected_rows($this->__connection);
	}
	
	
	// NOT TOTALLY SUPPORTED PUBLIC METHODS
        /**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->getAttribute( $attribute:Integer ):Mixed
         * @Param	Integer		a constant [	PDO_ATTR_SERVER_INFO,
         * 						PDO_ATTR_SERVER_VERSION,
         *                                              PDO_ATTR_CLIENT_VERSION,
         *                                              PDO_ATTR_PERSISTENT	]
         * @Return	Mixed		correct information or false
	 */
	function getAttribute($attribute) {
		$result = false;
		switch($attribute) {
			case PDO_ATTR_SERVER_INFO:
				$result = mysql_get_host_info($this->__connection);
				break;
			case PDO_ATTR_SERVER_VERSION:
				$result = mysql_get_server_info($this->__connection);
				break;
			case PDO_ATTR_CLIENT_VERSION:
				$result = mysql_get_client_info();
				break;
			case PDO_ATTR_PERSISTENT:
				$result = $this->__persistent;
				break;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets database attributes, in this version only connection mode.
         *       	this->setAttribute( $attribute:Integer, $mixed:Mixed ):Boolean
         * @Param	Integer		PDO_* constant, in this case only PDO_ATTR_PERSISTENT
         * @Param	Mixed		value for PDO_* constant, in this case a Boolean value
         * 				true for permanent connection, false for default not permament connection
         * @Return	Boolean		true on change, false otherwise
	 */
	function setAttribute($attribute, $mixed) {
		$result = false;
		if($attribute === PDO_ATTR_PERSISTENT && $mixed != $this->__persistent) {
			$result = true;
			$this->__persistent = (boolean) $mixed;
			mysql_close($this->__connection);
			if($this->__persistent === true)
				$this->__connection = &mysql_pconnect($this->__dbinfo[0], $this->__dbinfo[1], $this->__dbinfo[2]);
			else
				$this->__connection = &mysql_connect($this->__dbinfo[0], $this->__dbinfo[1], $this->__dbinfo[2]);
			mysql_select_db($this->__dbinfo[3], $this->__connection);
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets default fetch mode to use with this->fetch() method.
         *       	this->setFetchMode( $mode:Integer ):Boolean
         * @Param	Integer		PDO_FETCH_* constant to use while reading an execute query with fetch() method.
         * 				NOTE: PDO_FETCH_LAZY and PDO_FETCH_BOUND are not supported
         * @Return	Boolean		true on change, false otherwise
	 */
	function setFetchMode($mode) {
		$result = false;
		switch($mode) {
			case PDO_FETCH_NUM:
			case PDO_FETCH_ASSOC:
			case PDO_FETCH_OBJ:
			case PDO_FETCH_BOTH:
				$result = true;
				$this->__fetchmode = &$mode;
				break;
		}
		return $result;
	}
	
	
	// UNSUPPORTED PUBLIC METHODS
        function bindColumn($mixewd, &$param, $type = null, $max_length = null, $driver_option = null) {
		return false;
	}
	
	function __setErrors($er) {
		if(!is_resource($this->__connection)) {
			$errno = mysql_errno();
			$errst = mysql_error();
		}
		else {
			$errno = mysql_errno($this->__connection);
			$errst = mysql_error($this->__connection);
		}
		$this->__errorCode = &$er;
		$this->__errorInfo = Array($this->__errorCode, $errno, $errst);
		$this->__result = null;
	}
	
	function __uquery(&$query) {
		if(!@$query = mysql_query($query, $this->__connection)) {
			$this->__setErrors('SQLER');
			$query = null;
		}
		return $query;
	}
	
}




}//if!class_exists
?>

Added ext/pdo.sqlite.php.























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
<?php if (!class_exists("PDO_SQLITE")) {
/** File PDO_sqlite.class.php		*
 *(C) Andrea Giammarchi [2005/10/13]	*/

// Requires PDOStatement_sqlite.class.php , drived by PDO.class.php file
#<builtin>#require_once('PDOStatement_sqlite.class.php');

/**
 * Class PDO_sqlite
 * 	This class is used from class PDO to manage a SQLITE version 2 database.
 *      Look at PDO.clas.php file comments to know more about SQLITE connection.
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO.class.php
 * 			PDOStatement_sqlite.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/13
 * @LastModified	2005/18/14 12:30
 * @Version		0.1 - tested
 */ 
class PDO_sqlite {
	
	/**
	 * 'Private' variables:
	 *	__connection:Resource		Database connection
         *	__dbinfo:String			Database filename
         *      __persistent:Boolean		Connection mode, is true on persistent, false on normal (deafult) connection
         *      __errorCode:String		Last error code
         *      __errorInfo:Array		Detailed errors
	 */
	var $__connection;
	var $__dbinfo;
	var $__persistent = false;
	var $__errorCode = '';
	var $__errorInfo = Array('');
	
	/**
	 * Public constructor:
	 *	Checks connection and database selection
         *       	new PDO_mysql( &$host:String, &$db:String, &$user:String, &$pass:String )
	 * @Param	String		host with or without port info
         * @Param	String		database name
         * @Param	String		database user
         * @Param	String		database password
	 */
	function PDO_sqlite(&$string_dsn) {
		if(!@$this->__connection = &sqlite_open($string_dsn))
			$this->__setErrors('DBCON', true);
		else
			$this->__dbinfo = &$string_dsn;
	}
	
	/** NOT NATIVE BUT MAYBE USEFULL FOR PHP < 5.1 PDO DRIVER
	 * Public method
         * Calls sqlite_close function.
	 *	this->close( Void ):Boolean
         * @Return	Boolean		True on success, false otherwise
	 */
	function close() {
		$result = is_resource($this->__connection);
		if($result) {
			sqlite_close($this->__connection);
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns a code rappresentation of an error
         *       	this->errorCode( void ):String
         * @Return	String		String rappresentation of the error
	 */
	function errorCode() {
		return $this->__errorCode;
	}
	
	/**
	 * Public method:
	 *	Returns an array with error informations
         *       	this->errorInfo( void ):Array
         * @Return	Array		Array with 3 keys:
         * 				0 => error code
         *                              1 => error number
         *                              2 => error string
	 */
	function errorInfo() {
		return $this->__errorInfo;
	}
	
	/**
	 * Public method:
	 *	Excecutes a query and returns affected rows
         *       	this->exec( $query:String ):Mixed
         * @Param	String		query to execute
         * @Return	Mixed		Number of affected rows or false on bad query.
	 */
	function exec($query) {
		$result = 0;
		if(!is_null($this->__uquery($query)))
			$result = sqlite_changes($this->__connection);
		if(is_null($result))
			$result = false;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns last inserted id
         *       	this->lastInsertId( void ):Number
         * @Return	Number		Last inserted id
	 */
	function lastInsertId() {
		return sqlite_last_insert_rowid($this->__connection);
	}
	
	/**
	 * Public method:
	 *	Returns a new PDOStatement
         *       	this->prepare( $query:String, $array:Array ):PDOStatement
         * @Param	String		query to prepare
         * @Param	Array		this variable is not used but respects PDO original accepted parameters
         * @Return	PDOStatement	new PDOStatement to manage
	 */
	function prepare($query, $array = Array()) {
		return new PDOStatement_sqlite($query, $this->__connection, $this->__dbinfo);
	}
	
	/**
	 * Public method:
	 *	Executes directly a query and returns an array with result or false on bad query
         *       	this->query( $query:String ):Mixed
         * @Param	String		query to execute
         * @Return	Mixed		false on error, array with all info on success
	 */
	function query($query) {
		$query = @sqlite_unbuffered_query($query, $this->__connection, $this->__dbinfo);
		if($query) {
			$result = Array();
			while($r = sqlite_fetch_array($query, SQLITE_ASSOC))
				array_push($result, $r);
		}
		else {
			$result = false;
			$this->__setErrors('SQLER');
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->quote( $string:String ):String
         * @Param	String		string to quote
         * @Return	String		a correctly quoted string
	 */
	function quote($string) {
		return ("'".sqlite_escape_string($string)."'");
	}


	// NOT TOTALLY SUPPORTED PUBLIC METHODS
        /**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->getAttribute( $attribute:Integer ):Mixed
         * @Param	Integer		a constant [	PDO_ATTR_SERVER_INFO,
         * 						PDO_ATTR_SERVER_VERSION,
         *                                              PDO_ATTR_CLIENT_VERSION,
         *                                              PDO_ATTR_PERSISTENT	]
         * @Return	Mixed		correct information or null
	 */
	function getAttribute($attribute) {
		$result = null;
		switch($attribute) {
			case PDO_ATTR_SERVER_INFO:
				$result = sqlite_libencoding();
				break;
			case PDO_ATTR_SERVER_VERSION:
			case PDO_ATTR_CLIENT_VERSION:
				$result = sqlite_libversion();
				break;
			case PDO_ATTR_PERSISTENT:
				$result = $this->__persistent;
				break;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets database attributes, in this version only connection mode.
         *       	this->setAttribute( $attribute:Integer, $mixed:Mixed ):Boolean
         * @Param	Integer		PDO_* constant, in this case only PDO_ATTR_PERSISTENT
         * @Param	Mixed		value for PDO_* constant, in this case a Boolean value
         * 				true for permanent connection, false for default not permament connection
         * @Return	Boolean		true on change, false otherwise
	 */
	function setAttribute($attribute, $mixed) {
		$result = false;
		if($attribute === PDO_ATTR_PERSISTENT && $mixed != $this->__persistent) {
			$result = true;
			$this->__persistent = (boolean) $mixed;
			sqlite_close($this->__connection);
			if($this->__persistent === true)
				$this->__connection = &sqlite_popen($this->__dbinfo);
			else
				$this->__connection = &sqlite_open($this->__dbinfo);
		}
		return $result;
	}
	
	
	// UNSUPPORTED PUBLIC METHODS
	function beginTransaction() {
		return false;
	}
	
	function commit() {
		return false;
	}
	
	function rollBack() {
		return false;
	}
	
	
	// PRIVATE METHODS
	function __setErrors($er, $connection = false) {
		if(!is_resource($this->__connection)) {
			$errno = 1;
			$errst = 'Unable to open or find database.';
		}
		else {
			$errno = sqlite_last_error($this->__connection);
			$errst = sqlite_error_string($errno);
		}
		$this->__errorCode = &$er;
		$this->__errorInfo = Array($this->__errorCode, $errno, $errst);
	}
	
	function __uquery(&$query) {
		if(!@$query = sqlite_query($query, $this->__connection)) {
			$this->__setErrors('SQLER');
			$query = null;
		}
		return $query;
	}
}
?><?php
/** File PDOStatement_sqlite.class.php	*
 *(C) Andrea Giammarchi [2005/10/13]	*/

/**
 * Class PDOStatement_sqlite
 * 	This class is used from class PDO_sqlite to manage a MySQL database.
 *      Look at PDO.clas.php file comments to know more about MySQL connection.
 * ---------------------------------------------
 * @Compatibility	>= PHP 4
 * @Dependencies	PDO.class.php
 * 			PDO_sqlite.class.php
 * @Author		Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Mail		andrea [ at ] 3site [ dot ] it
 * @Date		2005/10/13
 * @LastModified	2006/01/29 09:30 [fixed execute bug]
 * @Version		0.1b - tested
 */ 
class PDOStatement_sqlite {
	
	/**
	 * 'Private' variables:
	 *	__connection:Resource		Database connection
         *	__dbinfo:Array			Array with 4 elements used to manage connection
         *      __persistent:Boolean		Connection mode, is true on persistent, false on normal (deafult) connection
         *      __query:String			Last query used
         *      __result:Resource		Last result from last query
         *      __fetchmode:Integer		constant PDO_FETCH_* result mode
         *      __errorCode:String		Last error string code
         *      __errorInfo:Array		Last error informations, code, number, details
         *      __boundParams:Array		Stored bindParam
	 */
	var $__connection;
	var $__dbinfo;
	var $__persistent = false;
	var $__query = '';
	var $__result = null;
	var $__fetchmode = PDO::FETCH_BOTH;
	var $__errorCode = '';
	var $__errorInfo = Array('');
	var $__boundParams = Array();
	
	/**
	 * Public constructor:
	 *	Called from PDO to create a PDOStatement for this database
         *       	new PDOStatement_sqlite( &$__query:String, &$__connection:Resource, $__dbinfo:String )
	 * @Param	String		query to prepare
         * @Param	Resource	database connection
         * @Param	String		database file name
	 */
	function PDOStatement_sqlite(&$__query, &$__connection, &$__dbinfo) {
		$this->__query = &$__query;
		$this->__connection = &$__connection;
		$this->__dbinfo = &$__dbinfo;
	}
	
	/**
	 * Public method:
	 *	Replace ? or :named values to execute prepared query
         *       	this->bindParam( $mixed:Mixed, &$variable:Mixed, $type:Integer, $lenght:Integer ):Void
         * @Param	Mixed		Integer or String to replace prepared value
         * @Param	Mixed		variable to replace
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
	 */
	function bindParam($mixed, &$variable, $type = null, $lenght = null) {
		if(is_string($mixed))
			$this->__boundParams[$mixed] = $variable;
		else
			array_push($this->__boundParams, $variable);
	}
	
	/**
	 * Public method:
	 *	Checks if query was valid and returns how may fields returns
         *       	this->columnCount( void ):Void
	 */
	function columnCount() {
		$result = 0;
		if(!is_null($this->__result))
			$result = sqlite_num_fields($this->__result);
		return $result; 
	}
	
	/**
	 * Public method:
	 *	Returns a code rappresentation of an error
         *       	this->errorCode( void ):String
         * @Return	String		String rappresentation of the error
	 */
	function errorCode() {
		return $this->__errorCode;
	}
	
	/**
	 * Public method:
	 *	Returns an array with error informations
         *       	this->errorInfo( void ):Array
         * @Return	Array		Array with 3 keys:
         * 				0 => error code
         *                              1 => error number
         *                              2 => error string
	 */
	function errorInfo() {
		return $this->__errorInfo;
	}
	
	/**
	 * Public method:
	 *	Excecutes a query and returns true on success or false.
         *       	this->exec( $array:Array ):Boolean
         * @Param	Array		If present, it should contain all replacements for prepared query
         * @Return	Boolean		true if query has been done without errors, false otherwise
	 */
	function execute($array = Array()) {
		if(count($this->__boundParams) > 0)
			$array = &$this->__boundParams;
		$__query = $this->__query;
		if(count($array) > 0) {
			foreach($array as $k => $v) {
				if(!is_int($k) || substr($k, 0, 1) === ':') {
					if(!isset($tempf))
						$tempf = $tempr = array();
					array_push($tempf, $k);
					array_push($tempr, "'".sqlite_escape_string($v)."'");
				}
				else {
					$parse = create_function('$v', 'return "\'".sqlite_escape_string($v)."\'";');
					$__query = preg_replace("/(\?)/e", '$parse($array[$k++]);', $__query);
					break;
				}
			}
			if(isset($tempf))
				$__query = str_replace($tempf, $tempr, $__query);
		}
		if(is_null($this->__result = &$this->__uquery($__query)))
			$keyvars = false;
		else
			$keyvars = true;
		$this->__boundParams = array();
		return $keyvars;
	}
	
	/**
	 * Public method:
	 *	Returns, if present, next row of executed query or false.
         *       	this->fetch( $mode:Integer, $cursor:Integer, $offset:Integer ):Mixed
         * @Param	Integer		PDO_FETCH_* constant to know how to read next row, default PDO_FETCH_BOTH
         * 				NOTE: if $mode is omitted is used default setted mode, PDO_FETCH_BOTH
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Param	Integer		this variable is not used but respects PDO original accepted parameters
         * @Return	Mixed		Next row of executed query or false if there is nomore.
	 */
	function fetch($mode = PDO_FETCH_BOTH, $cursor = null, $offset = null) {
		if(func_num_args() == 0)
			$mode = &$this->__fetchmode;
		$result = false;
		if(!is_null($this->__result)) {
			switch($mode) {
				case PDO_FETCH_NUM:
					$result = sqlite_fetch_array($this->__result, SQLITE_NUM);
					break;
				case PDO_FETCH_ASSOC:
					$result = sqlite_fetch_array($this->__result, SQLITE_ASSOC);
					break;
				case PDO_FETCH_OBJ:
					$result = sqlite_fetch_object($this->__result);
					break;
				case PDO_FETCH_BOTH:
				default:
					$result = sqlite_fetch_array($this->__result, SQLITE_BOTH);
					break;
			}
		}
		if(!$result)
			$this->__result = null;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns an array with all rows of executed query.
         *       	this->fetchAll( $mode:Integer ):Array
         * @Param	Integer		PDO_FETCH_* constant to know how to read all rows, default PDO_FETCH_BOTH
         * 				NOTE: this doesn't work as fetch method, then it will use always PDO_FETCH_BOTH
         *                                    if this param is omitted
         * @Return	Array		An array with all fetched rows
	 */
	function fetchAll($mode = PDO_FETCH_BOTH) {
		$result = array();
		if(!is_null($this->__result)) {
			switch($mode) {
				case PDO_FETCH_NUM:
					while($r = sqlite_fetch_array($this->__result, SQLITE_NUM))
						array_push($result, $r);
					break;
				case PDO_FETCH_ASSOC:
					while($r = sqlite_fetch_array($this->__result, SQLITE_ASSOC))
						array_push($result, $r);
					break;
				case PDO_FETCH_OBJ:
					while($r = sqlite_fetch_object($this->__result))
						array_push($result, $r);
					break;
				case PDO_FETCH_BOTH:
				default:
					while($r = sqlite_fetch_array($this->__result, SQLITE_BOTH))
						array_push($result, $r);
					break;
			}
		}
		$this->__result = null;
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns, if present, first column of next row of executed query
         *       	this->fetchSingle( void ):Mixed
         * @Return	Mixed		Null or next row's first column
	 */
	function fetchSingle() {
		$result = null;
		if(!is_null($this->__result)) {
			$result = @sqlite_fetch_array($this->__result, SQLITE_NUM);
			if($result)
				$result = $result[0];
			else
				$this->__result = null;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Returns number of last affected database rows
         *       	this->rowCount( void ):Integer
         * @Return	Integer		number of last affected rows
         * 				NOTE: works with INSERT, UPDATE and DELETE query type
	 */
	function rowCount() {
		return sqlite_changes($this->__connection);
	}
	
	
	// NOT TOTALLY SUPPORTED PUBLIC METHODS	
	/**
	 * Public method:
	 *	Quotes correctly a string for this database
         *       	this->getAttribute( $attribute:Integer ):Mixed
         * @Param	Integer		a constant [	PDO_ATTR_SERVER_INFO,
         * 						PDO_ATTR_SERVER_VERSION,
         *                                              PDO_ATTR_CLIENT_VERSION,
         *                                              PDO_ATTR_PERSISTENT	]
         * @Return	Mixed		correct information or null
	 */
	function getAttribute($attribute) {
		$result = null;
		switch($attribute) {
			case PDO_ATTR_SERVER_INFO:
				$result = sqlite_libencoding();
				break;
			case PDO_ATTR_SERVER_VERSION:
			case PDO_ATTR_CLIENT_VERSION:
				$result = sqlite_libversion();
				break;
			case PDO_ATTR_PERSISTENT:
				$result = $this->__persistent;
				break;
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets database attributes, in this version only connection mode.
         *       	this->setAttribute( $attribute:Integer, $mixed:Mixed ):Boolean
         * @Param	Integer		PDO_* constant, in this case only PDO_ATTR_PERSISTENT
         * @Param	Mixed		value for PDO_* constant, in this case a Boolean value
         * 				true for permanent connection, false for default not permament connection
         * @Return	Boolean		true on change, false otherwise
	 */
	function setAttribute($attribute, $mixed) {
		$result = false;
		if($attribute === PDO_ATTR_PERSISTENT && $mixed != $this->__persistent) {
			$result = true;
			$this->__persistent = (boolean) $mixed;
			sqlite_close($this->__connection);
			if($this->__persistent === true)
				$this->__connection = &sqlite_popen($this->__dbinfo);
			else
				$this->__connection = &sqlite_open($this->__dbinfo);
		}
		return $result;
	}
	
	/**
	 * Public method:
	 *	Sets default fetch mode to use with this->fetch() method.
         *       	this->setFetchMode( $mode:Integer ):Boolean
         * @Param	Integer		PDO_FETCH_* constant to use while reading an execute query with fetch() method.
         * 				NOTE: PDO_FETCH_LAZY and PDO_FETCH_BOUND are not supported
         * @Return	Boolean		true on change, false otherwise
	 */
	function setFetchMode($mode) {
		$result = false;
		switch($mode) {
			case PDO_FETCH_NUM:
			case PDO_FETCH_ASSOC:
			case PDO_FETCH_OBJ:
			case PDO_FETCH_BOTH:
				$result = true;
				$this->__fetchmode = &$mode;
				break;
		}
		return $result;
	}
	
	
	// UNSUPPORTED PUBLIC METHODS
        function bindColumn($mixewd, &$param, $type = null, $max_length = null, $driver_option = null) {
		return false;
	}
	
	function __setErrors($er, $connection = false) {
		if(!is_resource($this->__connection)) {
			$errno = 1;
			$errst = 'Unable to open database.';
		}
		else {
			$errno = sqlite_last_error($this->__connection);
			$errst = sqlite_error_string($errno);
		}
		$this->__errorCode = &$er;
		$this->__errorInfo = Array($this->__errorCode, $errno, $errst);
		$this->__result = null;
	}
	
	function __uquery(&$query) {
		if(!@$query = sqlite_query($query, $this->__connection)) {
			$this->__setErrors('SQLER');
			$query = null;
		}
		return $query;
	}
	
}



}//if!class_exists
?>

Added ext/php40.php.















































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
<?php
/**
 *
 * @group 4_0
 * @since 4.0
 * @untested
 *
 *
 * Here we collect PHP functions for versions before 4.1.
 *
 * YOU AIN'T GONNA NEED IT.
 *
 * It should be noted that 4.0.x versions can't be made compatible with
 * newer versions anyhow, because the newer superglobals ($_GET, $_REQUEST)
 * are missing - or not **superglobal** at least.
 *
 */

#---------------------------------------------------------------- 4.0.7 ---

#-- simulate superglobals
# you still had to put "global $_REQUEST,$_GET,..." into any function that
# used them - so this workaround is not all too useful anyhow, you should
# not accept PHP versions prior 4.0.7 for your scripts in any case!
if (!isset($GLOBALS["_REQUEST"])) {
   $GLOBALS["_GET"] = & $HTTP_GET_VARS;
   $GLOBALS["_POST"] = & $HTTP_POST_VARS;
   $GLOBALS["_SERVER"] = & $HTTP_SERVER_VARS;
   $GLOBALS["_ENV"] = & $HTTP_ENV_VARS;
   $GLOBALS["_COOKIE"] = & $HTTP_COOKIE_VARS;
   $GLOBALS["_FILES"] = & $HTTP_POST_FILES;
   $GLOBALS["_REQUEST"] = array_merge($HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS);
}


#---------------------------------------------------------------- 4.0.6 ---


#-- uses callback function to remove entries from array
if (!function_exists("array_filter")) {
   function array_filter($array, $callback="is_int") {
      foreach ($array as $key=>$val) {
         if (!call_user_func_array($callback, array($val))) {
            unset($array[$key]);
         }
      }
      return($array);
   }
}


#-- uses callback function to change array values, multiple input arrays
if (!function_exists("array_map")) {
   function array_map() {
      $arrays = get_func_args();
      $callback = shift($arrays);
      $r = &$arrays[0];
      foreach ($r as $key=>$val) {
         $val = call_user_func_array($callback, $arrays);
         $r[$key] = $val;
      }
      return($r);
   }
}


#-- checks for existence or only syntax of function or obj/class+method name
if (!function_exists("is_callable")) {
   function is_callable($var, $syntax_only=0) {
      $a = get_func_args();
      if (count($a) >= 3) {
         $fin = & $a[2];
      }

      #-- class/object+method
      if (is_array($var)) {
         if (count($var)!=2) {
            return false;
         }
         list($obj, $method) = $var;
         $class = $obj;
         if (is_object($obj)) {
            $class = get_class($obj);
         }

         if ($syntax_only) {
            $r = preg_match('/^\w+$/', $method);
            if (!is_object($obj)) {
               $r = $r && preg_match('/^\w+$/', $obj);
            }
         }
         else {
            if (is_object($obj)) {
               $r = method_exists($obj, $method);
            }
            else {
               $all = get_class_methods($obj);
               $r = in_array($method, $all);
            }
         }
         if ($r) { $fin = strtolower("$class:$method"); }
      }
      #-- simple function name
      elseif (is_string($var)) {
         if ($syntax_only) {
            $r = preg_match('/^\w+$/', $var);
         }
         else {
            $r = function_exists($var);
         }
         if ($r) { $fin = strtolower($var); }
      }
      #-- ooops
      else {
         $r = false;
      }
      return $r;
   }
}




#---------------------------------------------------------------- 4.0.5 ---
# chroot


#-- return index of value in array
if (!function_exists("array_search")) {
   function array_search($value, $array, $strict=false) {
      $strict = $strict ? true : false;
      foreach ($array as $key=>$v) {
         if ($strict&&($v===$value) || !$strict&&($v==$value)) {
            return($key);
         }
      }
      return(NULL);  // PHP prior 4.2 also did so
   }
}


#-- recursively collapse array into one value (via user callback)
if (!function_exists("array_reduce")) {
   function array_reduce($array, $callback, $value=NULL) {
      foreach ($array as $v) {
         if (is_array($v)) {
            $v = array_reduce($v, $callback);
         }
         else {
            $v = call_user_func_array($callback, array($value, $v));
         }
         $value = $v;
      }
      return($value);
   }
}


#-- checks variable to be of a simple type
if (!function_exists("is_scalar")) {
   function is_scalar($var) {
      return( !is_array($var) && !is_object($var) );
   }
}

#-- only static value (mix of C/English/European/US)
if (!function_exists("localeconv")) {
   function localeconv() {
      return array (
        'decimal_point' => '.',
        'thousands_sep' => '',
        'int_curr_symbol' => 'EUR ',   // more international than USD
        'currency_symbol' => '€',      // unnamed/trans currency symbol
        'mon_decimal_point' => '.',
        'mon_thousands_sep' => ',',
        'positive_sign' => '',
        'negative_sign' => '-',
        'int_frac_digits' => 2,
        'frac_digits' => 2,
        'p_cs_precedes' => 1,
        'p_sep_by_space' => 0,
        'n_cs_precedes' => 1,
        'n_sep_by_space' => 0,
        'p_sign_posn' => 1,
        'n_sign_posn' => 1,
        'grouping' => array (0=>3, 1=>3,),
        'mon_grouping' => array(0=>3, 1=>3,),
      );
   }
}


#-- function by name
if (!function_exists("call_user_func_array")) {
   function call_user_func_array($callback, $param_array=array()) {
      if ($param_array) {
         $param_array = array_values($param_array);
         $params = "'" . implode("','", $param_array) . "'";
      }
      if (is_array($callback)) {
         $obj = &$callback[0];
         $method = $callback[1];
         if (!method_exists($obj, $method)) {
            trigger_error("call_user_method_array: method '$method' does not exist", E_ERROR);
         }
         elseif (is_object($obj)) {
            eval("return \$obj->$method($params);");
         }
         else {
            eval("return $obj::$method($params);");
         }
      }
      elseif (!function_exists("$callback")) {
         trigger_error("call_user_func_array: function '$method' does not exist", E_ERROR);
      }
      else {
         switch (count($param_array)) {
            case 0:
               return $callback();
            case 1:
               return $callback($param_array[0]);
            case 2:
               return $callback($param_array[0], $param_array[1]);
            case 3:
               return $callback($param_array[0], $param_array[1], $param_array[2]);
            case 4:
               return $callback($param_array[0], $param_array[1], $param_array[2], $param_array[3]);
            default:
               eval("return $callback($params);");
         }
      }
   }
   function call_user_method_array($method, &$obj, $param_array=array()) {
      call_user_func_array(array(&$obj, $method), $param_array);
   }
}




#---------------------------------------------------------------- 4.0.4 ---



#-- adds all values of given array into total sum
if (!function_exists("array_sum")) {
   function array_sum($array) {
      $sum = 0;
      foreach ($array as $val) {
         $sum += $val;
      }
      return $sum;
   }
}

#-- value of constant (if their name was returned as string from somewhere)
if (!function_exists("constant")) {
   function constant($name) {
      if (defined($name)) {
         eval("return $name");
      }
      else {
         return NULL;
      }
   }
}

#-- more a language construct
if (!function_exists("is_null")) {
   function is_null($var) {
      return($var === NULL);
   }
}



#---------------------------------------------------------------- 4.0.3 ---
# register_tick_function
# unregister_tick_function

if (!function_exists("pathinfo")) {
   function pathinfo($fn) {
      preg_match("#^(?:(.+)/)?([^/]+?(?:\.([^/\.]+))?)$#", $fn, $uu);
      return array(
         "dirname" => $uu[1],
         "basename" => $uu[2],
         "extension" => $uu[3],
      );
   }
}

if (!function_exists("escapeshellarg")) {
   function escapeshellarg($arg) {
      $arg = str_replace("'", "'\\''", $arg);
      return "'$arg'";
   }
}

if (!function_exists("is_uploaded_file")) {
   function is_uploaded_file($fn) {
      ( $dir = get_cfg_var("upload_tmp_dir") )
       or
      ( $dir = dirname(tempnam("", "")) );
      return( realpath($dir) == realpath(dirname($fn)) );
   }
}

if (!function_exists("move_uploaded_file")) {
   function move_uploaded_file($fn, $dest) {
      if (is_uploaded_file($fn)) {
         return copy($fn, $dest) && unlink($fn);
      }
   }
}


#---------------------------------------------------------------- 4.0.2 ---
# ob_get_length



if (!function_exists("strncasecmp")) {
   function strncasecmp($str1, $str2, $len=0) {
      if ($len > 0) {
         $str1 = substr($str1, 0, $len);
         $str2 = substr($str2, 0, $len);
      }
      return strcasecmp($str1, $str2);
   }
}


if (!function_exists("wordwrap")) {
   function wordwrap($text, $width=75, $break="\n", $hardcut=0) {
      $out = "";
      foreach (explode("\n", $text) as $line) {
         if ($out) {
            $out .= "\n";
         }
         while (strlen($line)) {
            if ($hardcut) {
               $l = $width;
            }
            else {
               $l = strrpos(substr($text, 0, $width), " ");
               if ($l && ($l < strlen($line))) {
                  $l = strlen($line);
               }
               if ($l === false) {
                  $l = $width;
               }
            }
            $out .= substr($line, 0, $l);
            $out .= "\n";
            $line = substr(0, $l);
         }
      }
      return($out);
   }
}

if (!function_exists("php_uname")) {
   function php_uname($mode="a") {
      switch ($mode) {
         case "s":  $p = "--kernel-name";  break;
         case "n":  $p = "--node-name";  break;
         case "r":  $p = "--release";  break;
         case "v":  $p = "--kernel-version";  break;
         case "m":  $p = "--machine";  break;
         default:  $p = "--all";  break;
      }
      return `uname $p`;
   }
}



#---------------------------------------------------------------- 4.0.1 ---
# levensth
# fflush() - unimplementable
# array_unique
# array_diff
# array_intersect
# array_merge_recursive
# crc32
# fscanf
# sscanf
# str_pad
# set_file_buffer
# spliti

if (!function_exists("php_sapi_name")) {
   function php_sapi_name() {
      if (isset($_ENV["CGI_INTERFACE"])) {
         return "cgi";
      }
      elseif (strpos($_ENV["SERVER_SOFTWARE"], "Apache") !== false) {
         return "apache";
      }
      // ...
      else {
         return "cgi";  // the silly "cli" variation didn't exist before 4.2
      }
   }
}

?>

Deleted ext/posix.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
<?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);
      return(!$error);
   }
   
   function posix_getcwd() {
      return realpath(getcwd());
   }
   
   function posix_kill($pid, $sig) {
      $cmd = "kill -" . ((int)$sig) . " " . ((int)$pid);
      exec($cmd, $uu, $error);
      return(!$error);
   }

   function posix_uname() {
      return array(
         "sysname" => `/bin/uname -s`,
         "nodename" => `/bin/uname -n`,
         "release" => `/bin/uname -r`,
         "version" => `/bin/uname -v`,
         "machine" => `/bin/uname -m`,
         "domainname" => `/bin/domainname`,
      );
   }
}


?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































Added ext/stubs/dba.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
<?php
/*
   Load this with plugins/db/dba.php if your PHP provides only the
   older dbm_*() functions.
*/


#-- fake dba_* using dbm_* functions
if (!function_exists("dba_open") && function_exists("dbm_open")) {

   function dba_open($path, $mode, $handler, $a1=0) {
      if ($handler == "dbm") {
         return(dbmopen($path, $mode));
      }
      else return(false);
   }

   function dba_popen($a, $b, $c, $d=0) {
      return(dba_open($a, $b, $c));
   }

   function dba_exists($key, $handle) {
      return(dbmexists($handle, $key));
   }

   function dba_fetch($key, $handle) {
      return(dbmfetch($handle, $key));
   }

   function dba_insert($key, $string, $handle) {
      return(dbminsert($handle, $key, $string));
   }

   function dba_replace($key, $string, $handle) {
      return(dbmreplace($handle, $key, $string));
   }

   function dba_delete($key, $handle) {
      return(dbmdelete($handle, $key));
   }

   function dba_firstkey($handle) {
      return($GLOBALS["dbm_lastkey"] = dbmfirstkey($handle));
   }

   function dba_nextkey($handle) {
      return(dbmnextkey($handle, $GLOBALS["dbm_lastkey"]));
   }

   function dba_close($handle) {
      return(dbmclose($handle));
   }

   function dba_handlers() {
      return(array("dbm"));
   }

}


?>

Added ext/stubs/zlib.php.





































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<?php
/*
   This script simulates the gz*() functions, without actually providing
   compression functionality. The generated data streams will be correct,
   but reading compressed files isn't possible.
   
   Not very useful; should only be used if there is no other way. But if
   your provider seriously doesn't have PHP with builtin zlib support,
   you seriously were better off simply switching to someone else...
*/


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

    function gzopen($fp, $mode) {
       $mode = preg_replace('/[^carwb+]/', '', $mode);
       return(fopen($fp, $mode));
    }
    function gzread($fp, $len) {
       return(fread($fp, $len));
    }
    function gzwrite($fp, $string) {
       return(fwrite($fp, $string));
    }
    function gzputs($fp, $string) {
       return(fputs($fp, $string));
    }
    function gzclose($fp) {
       return(fclose($fp));
    }
    function gzeof($fp) {
       return(feof($fp));
    }
    function gzseek($fp, $offs) {
       return(fseek($fp, $offs, SEEK_SET));
    }
    function gzrewind($fp) {
       return(frewind($fp));
    }
    function gztell($fp) {
       return(ftell($fp));
    }

    function gzpassthru($fp) {
       while (!gzeof($fp)) {
          print(gzred($fp, 1<<20));
       }
       gzclose($fp);
    }
    function readgzfile($fn) {
       if ($fp = gzopen($fn, "rb")) {
          gzpassthru($fp);
       }
    }
   
    function gzfile($fn) {
       return(file($fn));
    }

    function gzgetc($fp) {
       return(fgetc($fp));
    }
    function gzgets($fp, $len) {
       return(fgets($fp, $len));
    }
    function gzgetss($fp, $len, $allowedtags="") {
       return(fgetss($fp, $len, $allowedtags));
    }

 }


 #-- fake compression methods
 if (!function_exists("gzdeflate")) {

    // only returns uncompressed deflate streams
    function gzdeflate($data, $level=0) {
        $gz = "";
        $end = strlen($data);
        $p = 0;
        do {
           $c = $end - $pos;
           if ($c >= 65536) {
              $c = 0xFFFF;
              $end = 0x00;
           }
           else {
              $end = 0x01;
           }
           $gz .= pack("Cvv",
                     ($end << 7) + (00 << 5),  // LAST=0/1, BTYPE=00
                     $c,                       // LEN
                     $c ^ 0xFFFF               // NLEN
                  );
           $gz .= substr($data, $p, $c);
           $p += $c;
        }
        while ($p < $end);
        return($gz);
    }

    // only can strip deflate headers, cannot decompress
    function gzinflate($data, $length=NULL) {
       $end = strlen($data);
       $gz = "";
       if (isset($length) && (($max*0.99) > $length)) {
          trigger_error("gzinflate(): gave up, decompressed string is likely longer than requested", E_USER_ERROR);
          return;
       }
       $out = "";
       $p = 0;
       do {
          $head = ord($data[$p]);
          $last = ($head >> 7);
          if (($head & 0x60) != 00) {
             trigger_error("gzinflate(): cannot decode compressed stream", E_USER_ERROR);
             return;
          }
          $head = unpack("v1LEN/v1NLEN", substr($data, $p+1, 4));
          $c = $head["LEN"];
          if (($c ^ 0xFFFF) != $head["NLEN"]) {
             trigger_error("gzinflate(): data error in stream", E_USER_ERROR);
             return;
          }
          $p += 5;
          $out .= substr($data, $p, $c);
          $p += $c;
       }
       while (($p < $end) && !$last);
       return($out);
    }


//    function gzcompress() {
//    }
//    function gzuncompress() {
//    }

    // without real compression support again
    function gzencode($data, $level=0) {
       $isize = strlen($data);
       $crc32 = crc32($data);
       $gz = "";
       {
          $gz .= pack("nCCVCC",
             $_ID = 0x1f8b,
             $_CM = 0x08,  // deflate fmt
             $_FLG = 0x00, // nothing extra
             $_MTIME = time(),
             $_XFL = 0x00, // no bonus flags
             $_OS = 255    // "unknown"
          );
          $gz .= gzdeflate($data);
          $gz .= pack("VV", $crc32, $isize);
       }
       return($gz);
    }

 }

?>

Added ext/unfinished/bcmath.old.php.

























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
/**
 * These two alternate bcmath implementations, don't emulate arbitrary
 * precision at all. And therefore, have been removed from bcmath.php.
 *
 */


#-- GMP
if (!function_exists("bcadd") && function_exists("gmp_strval")) {
   function bcadd($a, $b) {
      return gmp_strval(gmp_add($a, $b));
   }
   function bcsub($a, $b) {
      return gmp_strval(gmp_sub($a, $b));
   }
   function bcmul($a, $b) {
      return gmp_strval(gmp_mul($a, $b));
   }
   function bcdiv($a, $b, $precision=NULL) {
      $qr = gmp_div_qr($a, $b);
      $q = gmp_strval($qr[0]);
      $r = gmp_strval($qr[1]);
      if ((!$r) || ($precision===0)) {
         return($q);
      }
      else {
         if (isset($precision)) {
            $r = substr($r, 0, $precision);
         }
         return("$q.$r");
      }
   }
   function bcmod($a, $b) {
      return gmp_strval(gmp_mod($a, $b));
   }
   function bcpow($a, $b) {
      return gmp_strval(gmp_pow($a, $b));
   }
   function bcpowmod($x, $y, $mod) {
      return gmp_strval(gmp_powm($x, $y, $mod));
   }
   function bcsqrt($x) {
      return gmp_strval(gmp_sqrt($x));
   }
   function bccomp($a, $b) {
      return gmp_cmp($a, $b);
   }
   function bcscale($scale="IGNORED") {
      trigger_error("bcscale(): ignored", E_USER_ERROR);
   }
}//gmp emulation



#-- bigint
// @dl("php_big_int".PHP_SHLIB_SUFFIX))
if (!function_exists("bcadd") && function_exists("bi_serialize")) {
   function bcadd($a, $b) {
      return bi_to_str(bi_add($a, $b));
   }
   function bcsub($a, $b) {
      return bi_to_str(bi_sub($a, $b));
   }
   function bcmul($a, $b) {
      return bi_to_str(bi_mul($a, $b));
   }
   function bcdiv($a, $b) {
      return bi_to_str(bi_div($a, $b));
   }
   function bcmod($a, $b) {
      return bi_to_str(bi_mod($a, $b));
   }
   function bcpow($a, $b) {
      return bi_to_str(bi_pow($a, $b));
   }
   function bcpowmod($a, $b, $c) {
      return bi_to_str(bi_powmod($a, $b, $c));
   }
   function bcsqrt($a) {
      return bi_to_str(bi_sqrt($a));
   }
   function bccomp($a, $b) {
      return bi_cmp($a, $b);
   }
   function bcscale($scale="IGNORED") {
      trigger_error("bcscale(): ignored", E_USER_ERROR);
   }
}


?>

Added ext/unfinished/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
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
<?php
/**
 * @group 5_2_FILTER
 * @since 5.2
 *
 * filter_*() functions can probably be reimplemented for PHP5.0 and PHP4.x
 *
 *
 */




/**
 * Gets numeric filter index, from its textual name.
 *
 * @param  string
 * @return integer
 */
function filter_id($name) {
   $map = array(
      "int" => FILTER_VALIDATE_INT,
      "boolean" => FILTER_VALIDATE_BOOLEAN,
      "float" => FILTER_VALIDATE_FLOAT,
      "validate_regexp" => FILTER_VALIDATE_REGEXP,
      "validate_url" => FILTER_VALIDATE_URL,
      "validate_email" => FILTER_VALIDATE_EMAIL,
      "validate_ip" => FILTER_VALIDATE_IP,
      "string" => FILTER_SANITIZE_STRING,
      "stripped" => FILTER_SANITIZE_STRIPPED,
      "encoded" => FILTER_SANITIZE_ENCODED,
      "special_chars" => FILTER_SANITIZE_SPECIAL_CHARS,
      "unsafe_raw" => FILTER_UNSAFE_RAW,
      "email" => FILTER_SANITIZE_EMAIL,
      "url" => FILTER_SANITIZE_URL,
      "number_int" => FILTER_SANITIZE_NUMBER_INT,
      "number_float" => FILTER_SANITIZE_NUMBER_FLOAT,
      "magic_quotes" => FILTER_SANITIZE_MAGIC_QUOTES,
      "callback" => FILTER_CALLBACK,
   );
   if (isset($map[$name])) {
      return($map[$name]);
   }
   else {
      trigger_error(E_USER_ERROR, "no filter by name '".htmlentities($name)."'");
   }
}



/**
 * Returns list of filter names.
 *
 * @return array
 */
function filter_list() {
   return array(
      "int",
      "boolean",
      "float",
      "validate_regexp",
      "validate_url",
      "validate_email",
      "validate_ip",
      "string",
      "stripped",
      "encoded",
      "special_chars",
      "unsafe_raw",
      "email",
      "url",
      "number_int",
      "number_float",
      "magic_quotes",
      "callback",
   );
}



/**
 * filter id and flag constants,
 * may not match real values yet, just for testing
 *
 */
define("INPUT_POST", 1);
define("INPUT_GET", 2);
define("INPUT_COOKIE", 4);
define("INPUT_ENV", 8);
define("INPUT_SERVER", 16);
define("INPUT_SESSION", 32);
define("INPUT_REQUEST", 64);
define("FILTER_FLAG_NONE", 		0x0000000);
define("FILTER_REQUIRE_SCALAR",		0x0000001);
define("FILTER_REQUIRE_ARRAY",		0x0000002);
define("FILTER_FORCE_ARRAY",		0x0000006);
define("FILTER_NULL_ON_FAILURE",	0x0000080);
define("FILTER_VALIDATE_INT", 1083);
define("FILTER_VALIDATE_BOOLEAN", 1084);
define("FILTER_VALIDATE_FLOAT", 1085);
define("FILTER_VALIDATE_REGEXP", 1086);
define("FILTER_VALIDATE_URL", 1087);
define("FILTER_VALIDATE_EMAIL", 1088);
define("FILTER_VALIDATE_IP", 1089);
define("FILTER_DEFAULT", 1090);
define("FILTER_UNSAFE_RAW", 1091);
define("FILTER_SANITIZE_STRING", 1092);
define("FILTER_SANITIZE_STRIPPED", 1093);
define("FILTER_SANITIZE_ENCODED", 1094);
define("FILTER_SANITIZE_SPECIAL_CHARS", 1095);
define("FILTER_SANITIZE_EMAIL", 1096);
define("FILTER_SANITIZE_URL", 1097);
define("FILTER_SANITIZE_NUMBER_INT", 1098);
define("FILTER_SANITIZE_NUMBER_FLOAT", 1099);
define("FILTER_SANITIZE_MAGIC_QUOTES", 1100);
define("FILTER_CALLBACK", 1101);
define("FILTER_FLAG_ALLOW_OCTAL", 	0x0000100);
define("FILTER_FLAG_ALLOW_HEX", 	0x0000200);
define("FILTER_FLAG_STRIP_LOW", 	0x0000400);
define("FILTER_FLAG_STRIP_HIGH", 	0x0000800);
define("FILTER_FLAG_ENCODE_LOW", 	0x0001000);
define("FILTER_FLAG_ENCODE_HIGH",	0x0002000);
define("FILTER_FLAG_ENCODE_AMP",	0x0004000);
define("FILTER_FLAG_NO_ENCODE_QUOTES",	0x0008000);
define("FILTER_FLAG_EMPTY_STRING_NULL", 0x0010000);
define("FILTER_FLAG_ALLOW_FRACTION", 	0x0020000);
define("FILTER_FLAG_ALLOW_THOUSAND",	0x0040000);
define("FILTER_FLAG_ALLOW_SCIENTIFIC",	0x0080000);
define("FILTER_FLAG_SCHEME_REQUIRED",	0x0100000);
define("FILTER_FLAG_HOST_REQUIRED",	0x0200000);
define("FILTER_FLAG_PATH_REQUIRED",	0x0400000);
define("FILTER_FLAG_QUERY_REQUIRED",	0x0800000);
define("FILTER_FLAG_IPV4", 		0x1000000);
define("FILTER_FLAG_IPV6", 		0x2000000);
define("FILTER_FLAG_NO_RES_RANGE",	0x4000000);
define("FILTER_FLAG_NO_PRIV_RANGE", 	0x8000000);


/**
 * Get list of variables from _REQUEST, _GET, _POST, _COOKIE, _SERVER, _ENV
 * or _SESSION array, piped through some of the filters.
 *
 * @param integer  input array flag ids
 * @param mixed    mapping varname => filter_id or filter/flags hash
 * @global $_REQUEST,$_GET,$_POST,$_SERVER,$_ENV,$_SESSION,$_COOKIE
 */
function filter_input_array($GPCSESR, $def=array()) {
   $r = array();
   
   if ($GPCSESR & INPUT_REQUEST) {
      $r = array_merge($r, filter_var_array($_REQUEST, $def));
   }
   if ($GPCSESR & INPUT_POST) {
      $r = array_merge($r, filter_var_array($_POST, $def));
   }
   if ($GPCSESR & INPUT_GET) {
      $r = array_merge($r, filter_var_array($_GET, $def));
   }
   if ($GPCSESR & INPUT_COOKIE) {
      $r = array_merge($r, filter_var_array($_COOKIE, $def));
   }
   if ($GPCSESR & INPUT_SERVER) {
      $r = array_merge($r, filter_var_array($_SERVER, $def));
   }
   if ($GPCSESR & INPUT_ENV) {
      $r = array_merge($r, filter_var_array($_ENV, $def));
   }
   
   return($r);
}



/**
 * Get a single variable filtered from input arrays.
 *
 * @param bitmask
 * @param string
 * @param bitmask
 * @param bitmask
 * @return string
 */
function filter_input($_INPUT, $name, $filter=0, $flags=0) {
   return filter_input_array($_INPUT, array($name => array("filter"=>$filter, "flags"=>$flags)));
}




/**
 * Extract a list of variables from an array. Apply filters.
 *
 * @param array   source data
 * @param array   variable list
 * @return array  filtered vars
 */
function filter_var_array($hash, $def=array()) {
   $r = array();

   #-- variable names from list
   foreach($def as $varname=>$filt) {
   
      #-- do we have it?
      if (!isset($hash[$varname])) {
      }
      #-- filter id and flags
      elseif (is_array($filt)) {
         $r[$varname] = filter_var($hash[$name], $filt["filter"], $filt["flags"]);
      }
      #-- filter without args
      else {
         $r[$varname] = filter_var($hash[$name], $filt);
      }
   }
   
   return($r);
}


/**
 * isset() test in _GET,_POST,... arrays
 *
 */
function filter_has_var($_INPUT, $varname) {
   return false
   or ($_INPUT & INPUT_REQUEST) and isset($_REQUEST[$varname])
   or ($_INPUT & INPUT_SERVER) and isset($_SERVER[$varname])
   or ($_INPUT & INPUT_COOKIE) and isset($_COOKIE[$varname])
   or ($_INPUT & INPUT_POST) and isset($_POST[$varname])
   or ($_INPUT & INPUT_GET) and isset($_GET[$varname])
   or ($_INPUT & INPUT_ENV) and isset($_ENV[$varname]);
}



/**
 * Input filtering main function.
 *
 * @param mixed $var
 */
function filter_var($var, $filter=FILTER_SANITIZE_STRING, $options=array()) {

   #-- recursively call ourselves for array input
   if (is_array($var)) {
     array_walk_recursive($var, "filter_var__walk", array($filter, $options));
     return $var;
   }
   
   #-- extract options
   $flags = 0x0000000;
   $regexp = "//";
   $callback = "";
   $min_range = INT_MIN;
   $max_range = INT_MAX;
   if (is_array($options)) {
      extract($options);   // regexp, callback, min_range, max_range, flags
   }
   elseif (is_int($options)) {
      $flags = $options;
   }
   
   #-- clean up flags
   $FAILURE = $flags & FILTER_NULL_ON_FAILURE ? NULL : false;
   $flags = $flags & ~FILTER_NULL_ON_FAILURE;
   $flags = $flags & ~FILTER_REQUIRE_SCALAR;
   $flags = $flags & ~FILTER_REQUIRE_ARRAY;
   $flags = $flags & ~FILTER_FORCE_ARRAY;

   
   #-- regular expressions for simple filters
   $rx = array(
       "int" => "/^[-+]?(\d{1,9})$/",
       "oct" => "/^0([0-7]{1,12})$/",
       "hex" => => "/^(0x)?([0-0a-fA-F]{1,12})$/",
       "bool_true" => => "/^(true|yes|on|1)$/",
       "bool_false" => => "/^(false|no|off|0|)$/",
       "float" => => "/^([+-]?\d+(\.\d+)([eE]\d+))$/",
       "char_low" => => "[\000-\037]",
       "char_high" => => "[\177-\377]",
   );


   #-- generic string code
   if (1) {
      #-- rm ASCII <32
      if ($flags & FILTER_FLAG_STRIP_LOW) {
         $var = preg_replace("/$rx[char_low]+/", "", $var);
      }
      #-- rm ASCII >127
      if ($flags & FILTER_FLAG_STRIP_HIGH) {
         $var = preg_replace("/$rx[char_high]+/", "", $var);
      }
   }


   #-- integer
   if ($filter == FILTER_VALIDATE_INT) {

      #-- octal
      if ($flags & FILTER_FLAG_ALLOW_OCTAL) {
         if (preg_match($rx["oct"], $var)) {
            $var = octdec($var);
         }
         else {
            return $FAILURE;
         }
      }

      #-- hex
      elseif ($flags & FILTER_FLAG_ALLOW_HEX) {
         if (preg_match($rx["hex"], $var, $uu)) {
            $var = hexdec($uu[2]);
         }
         else {
            return $FAILURE;
         }
      }

      #-- plain int
      elseif (preg_match($rx["int"])) {
         $var = (int) $var;
      }
      else {
         return $FAILURE;
      }
      
      #-- range
      if (($var < $min_range) or ($var > $max_range)) {
         return $FAILURE;
      }
      else {
         return $var;
      }
   }

   
   #-- boolean
   elseif ($filter == FILTER_VALIDATE_BOOLEAN) {
      if (preg_match($rx["bool_true"], $var) {
         return TRUE;
      }
      elseif (preg_match($rx["bool_false"], $var) {
         return FALSE;
      }
      else {
         return $FAILURE;
      }
   }


   #-- float
   elseif ($filter = FILTER_VALIDATE_FLOAT) {
      return preg_match($rx["float"], $var) ? (float)$var : $FAILURE;
   }


   #-- regexp
   elseif ($filter = FILTER_VALIDATE_REGEXP) {
      if ($regexp) {
         return preg_match($regexp, $var) ? $var : $FAILURE;
      }
      else {
         trigger_error(E_USER_ERROR, "no regexp supplied for FILTER_VALIDATE_REGEXP");
      }
   }



// FILTER_VALIDATE_URL


// FILTER_VALIDATE_EMAIL


// FILTER_VALIDATE_IP






   #-- strip_tags
   elseif ($filter == FILTER_SANITIZE_STRING) {

      #-- remove angle brackets and everything in between
      $var = strip_tags($var);

      #-- quotes
      if ($flags & FILTER_FLAG_NO_ENCODE_QUOTES) {
         // nothing
      }
      else {
         $var = strtr(array("'", '"'), array("&#39;", "&#34;"), $var);
      }

      #-- encode ASCII <32
      if ($flags & FILTER_FLAG_ENCODE_LOW) {
         $var = preg_replace("/($rx[char_low]+)/e", "'&#'.ord('$1').';'", $var);
      }
      #-- encode ASCII >127
      if ($flags & FILTER_FLAG_ENCODE_HIGH) {
         $var = preg_replace("/($rx[char_high]+)/e", "'&#'.ord('$1').';'", $var);
      }


      #-- AMPERSAND
      if ($flags & FILTER_FLAG_ENCODE_AMP) {
         $var = str_replace("&", "&#38;", $var);
      }

      return $var;
   }


   #-- urlencoded
   elseif  ($filter == FILTER_SANITIZE_ENCODED) {
   
      $var = urlencode($var);

      #-- encode ASCII <32
      if ($flags & FILTER_FLAG_ENCODE_LOW) {
         $var = preg_replace("/($rx[char_low]+)/e", "rawurlencode('$1')", $var);
      }
      #-- encode ASCII >127
      if ($flags & FILTER_FLAG_ENCODE_HIGH) {
         $var = preg_replace("/($rx[char_high]+)/e", "rawurlencode('$1')", $var);
      }
       
      return $var;
   }


   #-- htmlspecialchars()
   elseif ($filter == FILTER_SANITIZE_SPECIAL_CHARS) {

      #-- encode rest
      $var = htmlspecialchars($var);

      #-- always encode ASCII<32
      if (1) {
         $var = preg_replace("/($rx[char_low]+)/e", "'&#'.ord('$1').';'", $var);
      }
      #-- encode ASCII >127
      if ($flags & FILTER_FLAG_ENCODE_HIGH) {
         $var = preg_replace("/($rx[char_high]+)/e", "'&#'.ord('$1').';'", $var);
      }

      return $var;
   }


   #-- binary
   elseif ($filter == FILTER_UNSAFE_RAW)) {
   
      #-- "raw": encode AMPERSAND
      if ($flags & FILTER_FLAG_ENCODE_AMP) {
         $var = str_replace("&", "%", $var);           // ???????????????
      }
   
      #-- rm ASCII <32
      if ($flags & FILTER_FLAG_STRIP_LOW) {
         $var = preg_replace("/$rx[char_low]+/", "", $var);
      }
      #-- rm ASCII >127
      if ($flags & FILTER_FLAG_STRIP_HIGH) {
         $var = preg_replace("/$rx[char_high]+/", "", $var);
      }
      #-- encode ASCII <32
      if ($flags & FILTER_FLAG_ENCODE_LOW) {
         $var = preg_replace("/($rx[char_low]+)/e", "rawurlencode('$1')", $var);
      }
      #-- encode ASCII >127
      if ($flags & FILTER_FLAG_ENCODE_HIGH) {
         $var = preg_replace("/($rx[char_high]+)/e", "rawurlencode('$1')", $var);
      }


      return $var;
   }


   #-- email
   elseif ($filter == FILTER_SANITIZE_EMAIL) {
      return preg_replace("/[^-\w\d!#\$%&'*+\/=?\^`{\|}~@\.\[\]]+/", "", $var);
   }


   #-- url
   elseif ($filter == FILTER_SANITIZE_URL) {
      return preg_replace("/[^-\w\d\$.+!*'(),{}\|\\~\^\[\]\`<>#%\";\/?:@&=]+/", "", $var);
   }


   #-- number_int
   elseif ($filter == FILTER_SANITIZE_NUMBER_INT) {
      return preg_replace("/(^[^-+\d]|[^\d]+)/", "", $var);
   }


   #-- number_float
   elseif ($filter == FILTER_SANITIZE_NUMBER_INT) {
      // FILTER_FLAG_ALLOW_FRACTION
      // FILTER_FLAG_ALLOW_THOUSAND
      // FILTER_FLAG_ALLOW_SCIENTIFIC
      return preg_replace("/(^[^-+\d]|[^\d.eE]+)/", "", $var);
   }


   #-- magic_quotes
   elseif ($filter == FILTER_SANITIZE_MAGIC_QUOTES) {
      return addslashes($var);
   }


   #-- callback function
   elseif ($filter == FILTER_CALLBACK) {
      return call_user_func($callback);
   }

         
   #-- filter unknown         
   else {
      trigger_error(E_USER_ERROR, "Uh, oh. Unknown filter id #".$filter);
      return $FAILURE;
   }
   
}


/**
 * Callback wrapper; needed for array_walk_recursive().
 *
 */
function filter_var__walk(&$var, $key, $filter, $options) {
   $var = filter_var($var, $filter, $options);
}



/**
 * @tests
 
123 === filter_var("123", FILTER_VALIDATE_INT)
FALSE === filter_var("--123", FILTER_VALIDATE_INT)
123 == filter_var("+123", FILTER_VALIDATE_INT)
15 === filter_var("0xF", FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)
FALSE === filter_var("-0xFFFF", FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)
"12&#38;3" === filter_var("12&3", FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP)
"1&#9;2'&5" === ("1\t2'3&<4>5", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES|FILTER_FLAG_ENCODE_LOW)
 
 */

?>

Added ext/unfinished/odbc.php.



































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

die("'odbc.php' is incomplete. Don't use this yet.\n");

/*
   This is just another SQL interface wrapper. It reimplements the ODBC
   functions in PHP by itself chaining to PEAR::DB (a double wrapper,
   to simplify this initial version).
    - does not use integers as connection_id

   Because any mysql_*() calls are easier replaced with odbc_() funcs,
   but at the same time offer the same degree of database independence,
   this can often make more sense than transitioning to PEAR::DB or the
   ADOdb classes.
    - PEAR::DB provides the saner OO-interface
    - ADOdb is slightly faster, but has a less nicely abstracted API
*/


#-- declare odbc interface functions
if (!function_exists("odbc_connect")) {

   #-- load PEAR::DB
   require_once("DB.php");


   #-- initialize connection
   function odbc_connect($dsn, $user, $password, $cursor_type=NULL) {

      #-- mangle $dsn for PEAR
      $dsn = str_replace("://", "://$user:$password@", $dsn);
      // ... rename dbtype identifiers

      #-- connect
      $c = DB::connect($dsn);
      if (!PEAR::isError($c)) {
         return($c);
      }
   }

   #-- incomplete
   function odbc_pconnect($dsn, $user, $password, $cursor_type=NULL) {
      return odbc_connect($dsn, $user, $password, $cursor_type);
   }
   
   #-- end connection
   function odbc_close($db) {
      $db->disconnect();
   }
   
   
   #-- SQL command execution
   function odbc_exec($db, $query) {
      return $db->query($db);
   }
   function odbc_do($db, $query) {
      return odbc_exec($db, $query);
   }


   #-- sql pre-parsing
   function odbc_prepare($db, $query) {
      return( array($db, $db->prepare($db)) );
   }
   #-- and execution of prepared query
   function odbc_execute($pq, $args=NULL) {
      return $pq[0]->execute($pq[1], $args);
   }


   #-- return result row
   function odbc_fetch_array($res) {
      return $res->fetchRow(DB_FETCHMODE_ASSOC);
   }
   function odbc_fetch_row($res) {
      return $res->fetchRow(DB_FETCHMODE_ORDERED);
   }
   function odbc_fetch_object($res) {
      return $res->fetchRow(DB_FETCHMODE_OBJECT);
   }
   function odbc_fetch_into($res, $count, &$array) {
      $array = array();
      while ($count--) {
         $array[] =  $res->fetchRow(DB_FETCHMODE_ORDERED);
      }
   }
   
   
   #-- more functions on result sets
   function odbc_free_result(&$res) {
      $res->free();
      $res = NULL;
   }
   function odbc_next_result($res) {
      return $res->nextResult();
   }
   function odbc_num_fields($res) {
      return $res->numCols();
   }
   function odbc_num_rows($res) {
      return $res->numRows();
   }
   
   
   #-- and there's more
   //...

   

}


?>

Added ext/unfinished/openssl.php.











>
>
>
>
>
1
2
3
4
5
<?php
/*
   Ok, that's a joke. (Not that this wasn't possible, though ...)
*/
?>

Added ext/unfinished/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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
/*
   api: php
   type: class
   title: PDO
   priority: never
   status: unfinished
   
   TODO.
   
   PDO is a standardized SQL wrapper for PHP. It's meant to replace the
   plethora of mysql_/pgsql_ functions and former SQL wrappers PEARDB,
   MDB2, ADODB, ... and become what DBI is for Perl.
   
   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.)
   
   We'll only implement here:
   - PDO_MYSQL
*/


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


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

?>

Added ext/unfinished/posix.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
<?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);
      return(!$error);
   }
   
   function posix_getcwd() {
      return realpath(getcwd());
   }
   
   function posix_kill($pid, $sig) {
      $cmd = "kill -" . ((int)$sig) . " " . ((int)$pid);
      exec($cmd, $uu, $error);
      return(!$error);
   }

   function posix_uname() {
      return array(
         "sysname" => `/bin/uname -s`,
         "nodename" => `/bin/uname -n`,
         "release" => `/bin/uname -r`,
         "version" => `/bin/uname -v`,
         "machine" => `/bin/uname -m`,
         "domainname" => `/bin/domainname`,
      );
   }
}


?>

Deleted tests/_listemulated.

1
2
3
4
5
6
7
8
9
10
<?php

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

$r = get_defined_functions();
$r = $r["user"];
echo "emulated functions are:\n";
print_r($r);

?>
<
<
<
<
<
<
<
<
<
<




















Deleted tests/_runparts.

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

#-- params
if [ -z "$1" ]
then
   echo "syntax:  _runparts [php412] [php501]  | more"
   echo "Runs all PHP scripts in the tests/ directory with two interpreter versions"
   echo "side by side, for comparison. If you don't have two of them installed, you"
   echo "could simply specify 'cat' or 'false' as the second argument."
else

   #-- go
   cd `dirname $0`
   OLD=$1
   NEW=$2
   [ -z "$NEW" ] && NEW="cat"
   for SCRIPT in *
   do
      $OLD $SCRIPT | tr -d "\r" | fmt -w 36 -s > /tmp/1
      $NEW $SCRIPT | tr -d "\r" | fmt -w 36 -s > /tmp/2
      echo "-----------------------------------------------------------------"
      echo "$SCRIPT"
      echo "-----------------------------------------------------------------"
      pr -m --columns=2 -t  /tmp/1 /tmp/2
      echo "--"
   done

fi   
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted tests/array_change_key_case.

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

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

$a = array("low"=>32, "CamelCase"=>"Wiki");
print_r($a);
echo "\n";
$a = array_change_key_case($a, CASE_UPPER);
print_r($a);

?>


<
<
<
<
<
<
<
<
<
<
<
<
<


























Deleted tests/array_chunk.

1
2
3
4
5
6
7
8
9
10
11
12
<?php

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

$a = array("a", "b", "c", "d", "e");
$r = array_chunk($a, 2, 1);
echo 'array_chunk($a, 2, 1) = ';
print_r($r);

?>


<
<
<
<
<
<
<
<
<
<
<
<
























Deleted tests/array_combine.

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

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


?>
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c);
<?php
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c);
?>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Deleted tests/array_diff_assoc.

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

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


?>
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000,         15=>555);
$res = array_diff_assoc($a, $b);

print_r($res);
<?php
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000,         15=>555);
$res = array_diff_assoc($a, $b);
print_r($res);
?>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted tests/array_fill.

1
2
3
4
5
6
7
8
9
10
<?php

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

$a = 17;
$a = array_fill(1, 17, $a);
print_r($a);

?>

<
<
<
<
<
<
<
<
<
<




















Deleted tests/array_intersect_assoc.

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

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

?>
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000, 555);
$res = array_intersect_assoc($a, $b);

print_r($res);
<?php
$a = array(5=>5, 14=>10000, "ccc"=>555, 555);
$b = array(5=>5, 13=>10000, 555);
$res = array_intersect_assoc($a, $b);
print_r($res);
?>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































Deleted tests/array_udiff_uassoc.

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

include("../ext/array.php");

#-- from manual --

class cr {
    var $priv_member;
    function cr($val)
    {
        $this->priv_member = $val;
    }
}
    function comp_func_cr($a, $b)
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }
    
    function comp_func_key($a, $b)
    {
        if ($a === $b) return 0;
        return ($a > $b)? 1:-1;
    }


$a = array(
   "0.1" => new cr(9),
   "0.5" => new cr(12),
   0 => new cr(23),
   1=> new cr(4),
   2 => new cr(-15),
);
$b = array(
   "0.2" => new cr(9),
   "0.5" => new cr(22),
   0 => new cr(3),
   1=> new cr(4),
   2 => new cr(-15),
);

$result = array_udiff_uassoc($a, $b, "comp_func_cr", "comp_func_key");
$expected = array (
  '0.1' => new cr(9),
  '0.5' => new cr(12),
  0 => new cr(23),
);
print_r($result);

if ($result == $expected) {
   echo "\n--> works correctly\n";
}

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































Deleted tests/array_walk_recursive.

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

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

$a = array(
  "x1",
  "x2\\",
  array(
     "x3aaa1",
     "x3a\\a2",
  ),
  "x4\+end",
);

echo "__start:\n";
array_walk_recursive($a, "outp");

function outp(&$a) {
   var_dump($a);
   $a = stripslashes($a);
}

echo "\n__result:\n";
var_dump($a);

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































Deleted tests/base16.

1
2
3
4
5
6
7
8
<?php
include "../ext/base64.php";

echo base16_encode("123");
echo "\n";
echo base16_decode("313233");

?>
<
<
<
<
<
<
<
<
















Deleted tests/bcmath.

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

include("../ext/bcmath.php");

bcscale(50);
echo "1/17=";
echo bcdiv("1", "17");
echo "\n";

echo "2^55%77777=";
echo bcpowmod(2, 55, 77777);
echo "\n";

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted tests/class_parents.

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

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

class a {}
class x extends a {}
class y extends x {}
class z extends a {}
class eve extends y {}

$y = new y;
$r = class_parents($y);
print_r($r);

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted tests/file_put_contents.

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

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

$FN = "/tmp/test_fpc";

echo 'file_put_contents("/tmp/test_fpc", "abc-test-text");'."\n";
file_put_contents($FN, "abc-test-text");

echo 'echo file_get_contents("/tmp/test_fpc");'."\n => ";
echo file_get_contents($FN);

unlink($FN);

?>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































Deleted tests/floatval.

1
2
3
4
5
6
7
8
floatval("1234.567abc") = <?php

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

$str = "1234.567abc";
echo floatval($str);

?>
<
<
<
<
<
<
<
<
















Deleted tests/fmod.

1
2
3
4
5
6
7
8
<?php

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

$r = fmod(5.7, 1.3);
echo "fmod(5.7, 1.3) = $r\n";

?>
<
<
<
<
<
<
<
<
















Deleted tests/fnmatch.

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

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

$text = "Some text goes here...";
echo '$text = "Some text goes here...";';
echo "\nfnmatch('go*', $text) = ". (fnmatch('go*', $text) ?1:0);
echo "\nfnmatch('*go', $text) = ". (fnmatch('*go', $text) ?1:0);
echo "\nfnmatch('*go*', $text) = ". (fnmatch('*go*', $text) ?1:0);
echo "\nfnmatch('*te?x*', $text) = ". (fnmatch('*te?x*', $text) ?1:0);
echo "\nfnmatch('*te?t*', $text) = ". (fnmatch('*te?t*', $text) ?1:0);
echo "\nfnmatch('So?m*', $text) = ". (fnmatch('So?m*', $text) ?1:0);
echo "\nfnmatch('So*m*', $text) = ". (fnmatch('*So*m*', $text) ?1:0);

?>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































Deleted tests/get_headers.

1
2
3
4
5
6
7
8
<?php

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

$r = get_headers("http://localhost/");
print_r($r);

?>
<
<
<
<
<
<
<
<
















Deleted tests/gettext.

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

include("../ext/gettext.php");

#-- load
echo "bindtextdomain(\"tar\");\n";
bindtextdomain("tar");
textdomain("tar");

#-- query
echo "_(\"stdin\") == \"";
echo _("stdin");
echo "\"\n";

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted tests/glob.

1
2
3
4
5
6
7
8
9
10
11
<?php

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

echo 'glob("../tests/*m*") = ';
$r = glob("../tests/*m*");
print_r($r);


?>

<
<
<
<
<
<
<
<
<
<
<






















Deleted tests/gzdecode.

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

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

$orig =
"ORIGINAL_TEXT.................................................................................................................................................................................................................................End";
$gz = gzencode($orig);
echo "strlen(\$orig) == ".strlen($orig)."\n";
echo "strlen(\$gz) == ".strlen($gz)."\n...\n";

$text = gzdecode($gz);
echo "gzdecode(\$gz) = \"$text\"\n\n";


?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted tests/headers_list.

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

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

header("Content-Type: text/x-display-on-console");
header("X-Server: upgradephp-test/2.75.01d");
echo "header(\"...\");\n\n";

echo "\$r = headers_list();\n\n";
error_reporting(E_ALL);
$r = headers_list();
print_r($r);

?>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































Deleted tests/html_entity_decode.

1
2
3
4
5
6
7
8
9
10
<?php

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

echo 'html_entity_decode("&lt;&amp;&gt;&auml;&szlig;") = ';
echo html_entity_decode("&lt;&amp;&gt;&auml;&szlig;");

?>


<
<
<
<
<
<
<
<
<
<




















Deleted tests/http_build_query.

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

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


?>
$data = array('foo', 'bar', "sub"=>array('b', 'c'), 'cow' => 'milk', 'php' =>'hypertext processor');
echo http_build_query($data, "num_");

<?php
$data = array('foo', 'bar', "sub"=>array('b', 'c'), 'cow' => 'milk', 'php' =>'hypertext processor');
echo http_build_query($data, "num_");
?>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted tests/is_a.

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

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

class y {}
class x extends y {}
$x = new x;

echo is_a($x, "x") ? "works" : "failed";
echo "\n";
echo is_a($x, "y") ? "works" : "failed";

?>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted 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" => "Hallφchen
",
  "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";

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































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

?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































Deleted tests/md5_file.

1
2
3
4
5
6
7
8
9
md5_file(__FILE__) = <?php

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

echo md5_file(__FILE__);

?>


<
<
<
<
<
<
<
<
<


















Deleted tests/mhash.

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

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

echo "HMAC-MD5 test cases (RFC2104/page 9):\n\n";

# 1
$k = str_pad("", 16, chr(0x0b));
$text = "Hi There";
$end = unpack("H32", mhash(MHASH_MD5, $text, $k));
echo "key =     0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b\n";
echo "data =    \"$text\"\n";
echo "digest =  0x$end[1]\n";
echo "should =  0x9294727a3638bb1c13f48ef8158bfc9d\n\n";

# 2
$k = "Jefe";
$text = "what do ya want for nothing?";
$end = unpack("H32", mhash(MHASH_MD5, $text, $k));
echo "key =     \"$k\"\n";
echo "data =    \"$text\"\n";
echo "digest =  0x$end[1]\n";
echo "should =  0x750c783e6ab0b503eaa86e310a5db738\n\n";



?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































Deleted tests/mime_content_type.

1
2
3
4
5
6
7
8
9
<?php

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

$t = mime_content_type(__FILE__);
echo "mime_content_type(__FILE__) = $t\n\n";

?>
<
<
<
<
<
<
<
<
<


















Deleted tests/scandir.

1
2
3
4
5
6
7
8
9
<?php

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

$r = scandir("..");
echo "..\n\n";
print_r($r);

?>
<
<
<
<
<
<
<
<
<


















Deleted tests/spl_classes.

1
2
3
4
5
6
7
8
9
<?php

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

echo "print_r(spl_classes());\n\n";
$r=spl_classes();
print_r($r);

?>
<
<
<
<
<
<
<
<
<


















Deleted tests/str_ireplace.

1
2
3
4
5
6
7
8
9
10
11
12
<?php

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

$text = "ABC_abc_DEF_def_AAaaAAaa_DDddEEee";
echo "\$text = \"$text\";\n";
echo 'str_ireplace("abc", "xxx", $text);'."\n\n";

$text = str_ireplace("abc", "xxx", $text);
echo "\$text = \"$text\";\n";

?>
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted tests/str_rot13.

1
2
3
4
5
6
7
8
9
str_rot13('upgrade.php v4') = "<?php

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

echo str_rot13('upgrade.php v4');

?>"


<
<
<
<
<
<
<
<
<


















Deleted tests/str_shuffle.

1
2
3
4
5
6
7
8
9
10
str_shuffle("ABCDEF") == "<?php

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

srand(17);
echo str_shuffle("ABCDEF");

?>"


<
<
<
<
<
<
<
<
<
<




















Deleted tests/str_split.

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

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


?>
$str = "Hello Friend";
$r = str_split($str, 3);
print_r($r);

<?php
$str = "Hello_Friend";
$r = str_split($str, 3);
print_r($r);
?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted tests/str_word_count.

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

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


$r = str_word_count("This is-a sample string.", 2);
echo 'str_word_count("This is-a sample string.", 2) = ';
print_r($r);


?>



<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted 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 tests/stripos.

1
2
3
4
5
6
7
8
9
10
11
<?php

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

$l = stripos("ABCDEFef", "e");
echo "stripos(\"ABCDEFef\", \"e\") == $l\n\n";

$r = strripos("ABCDefEF", "e");
echo "strripos(\"ABCDefEF\", \"e\") == $r\n\n";

?>
<
<
<
<
<
<
<
<
<
<
<






















Deleted tests/strpbrk.

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

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

?>
$text = 'This is a Simple text.';

echo strpbrk($text, 'mi');
<?php
$text = 'This is a Simple text.';
echo strpbrk($text, 'mi')."\n\n";

echo 'echo strpbrk($text, "S");'."\n";
echo strpbrk($text, "S")."\n\n";
?>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted tests/strripos.

1
2
3
4
5
6
7
8
9
10
<?php

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

echo 'strripos("aaaabc_DEFff_ABCccc", "a") == ';
echo strripos("aaaabc_DEFff_ABCccc", "a");

?>


<
<
<
<
<
<
<
<
<
<




















Deleted tests/substr_compare.

1
2
3
4
5
6
7
8
9
10
11
12
<?php

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


echo 'substr_compare("abcde", "bc", 1, 2) == '. substr_compare("abcde", "bc", 1, 2) . "   // 0\n";
echo 'substr_compare("abcde", "bcg", 1, 2) == '. substr_compare("abcde", "bcg", 1, 2). "   // 0\n"; 
echo 'substr_compare("abcde", "BC", 1, 2, true) == '. substr_compare("abcde", "BC", 1, 2, true) . "   // 0\n";
echo 'substr_compare("abcde", "bc", 1, 3) == '. substr_compare("abcde", "bc", 1, 3) ."   // 1\n";
echo 'substr_compare("abcde", "cd", 1, 2) == '. substr_compare("abcde", "cd", 1, 2) ."  // -1\n";
echo 'substr_compare("abcde", "abc", 5, 1) == '. substr_compare("abcde", "abc", 5, 1) . "   // warning\n";
?>
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted tests/uuencode.

1
2
3
4
5
6
7
8
9
10
11
<?php

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

$uu = convert_uuencode("ABCDEFGHIJ");
echo "\$uu = \"$uu\"\n\n";

$text = convert_uudecode($uu);
echo "\$text = \"$text\"\n\n";

?>
<
<
<
<
<
<
<
<
<
<
<






















Deleted tests/vprintf.

1
2
3
4
5
6
7
8
<?php

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

vprintf("%d, %d\n", array(17, 5));

?>

<
<
<
<
<
<
<
<
















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
<?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*users·sf·net>
 *
 */



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



|
|
|





|
|


|
|


|
|




>
>


|

|

<
|







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
<?php
/**
 * api:		php
 * title:	WentPHP5 / upgrade.php
 * description:	Emulates functions from new PHP versions on older interpreters.
 * version:	15
 * license:	Public Domain
 * url:		http://freshmeat.net/p/upgradephp
 * type:	functions
 * category:	library
 * priority:	auto
 * sort:	-255
 * provides:	upgrade-php, api:php5
 *
 *
 * By loading this library you get PHP version independence. It provides
 * downwards compatibility to older PHP interpreters by emulating missing
 * functions or constants using IDENTICAL NAMES. So this doesn't slow down
 * script execution on setups where the native functions already exist. It
 * is meant as quick drop-in solution. It spares you from rewriting code or
 * using cumbersome workarounds, instead of the more powerful v5 functions.
 * 
 * It cannot mirror PHP5s extended OO-semantics and functionality into PHP4
 * however. A few features are added here that weren't part of PHP yet. And
 * some other function collections are separated out into the ext/ directory.
 * It doesn't produce many custom error messages (YAGNI), and instead leaves
 * reporting to invoked functions or for execution on native PHP.
 * 
 * And further this is PUBLIC DOMAIN (no copyright, no license, no warranty)
 * so therefore compatible to ALL open source licenses. You could rip this
 * paragraph out to republish this instead only under more restrictive terms
 * or your favorite license (GNU LGPL/GPL, BSDL, MPL/CDDL, Artistic/PHPL, ..)
 *

 * Any contribution is appreciated. <milky*users#sf#net>
 *
 */



/**
 *                                   ------------------------------ CVS ---
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

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







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

/**
 *                                   ------------------------------ 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136


137
138
139
140
141
142
143
 * @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 = "";
      







|
|


|

|

>
>







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
 * @since unknown
 */
if (!defined("E_RECOVERABLE_ERROR")) { define("E_RECOVERABLE_ERROR", 4096); }



/**
 * Converts PHP variable or array into a "JSON" (JavaScript value expression
 * or "object notation") string.
 *
 * @compat
 *    Output seems identical to PECL versions. "Only" 20x slower than PECL version.
 * @bugs
 *    Doesn't take care with unicode too much - leaves UTF-8 sequences alone.
 *
 * @param  $var mixed  PHP variable/array/object
 * @return string      transformed into JSON equivalent
 */
if (!function_exists("json_encode")) {
   function json_encode($var, /*emu_args*/$obj=FALSE) {
   
      #-- prepare JSON string
      $json = "";
      
166
167
168
169
170
171
172

173
174
175
176
177
178
179
      #-- 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) {







>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
      #-- 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 . '"';
         //@COMPAT: for fully-fully-compliance   $var = preg_replace("/[\000-\037]/", "", $var);
      }

      #-- basic types
      elseif (is_bool($var)) {
         $json = $var ? "true" : "false";
      }
      elseif ($var === NULL) {
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
      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







|



<
|
>
|

>
>
|
>
>
>

>
>
>















>


>



>
>

>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>




>
>



|
>
>







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
      return($json);
   }
}



/**
 * Parses a JSON (JavaScript value expression) string into a PHP variable
 * (array or object).
 *
 * @compat

 *    Behaves similar to PECL version, but is less quiet on errors.
 *    Now even decodes unicode \uXXXX string escapes into UTF-8.
 *    "Only" 27 times slower than native function.
 * @bugs
 *    Might parse some misformed representations, when other implementations
 *    would scream error or explode.
 * @code
 *    This is state machine spaghetti code. Needs the extranous parameters to
 *    process subarrays, etc. When it recursively calls itself, $n is the
 *    current position, and $waitfor a string with possible end-tokens.
 *
 * @param   $json string   JSON encoded values
 * @param   $assoc bool    (optional) if outer shell should be decoded as object always
 * @return  mixed          parsed into PHP variable/array/object
 */
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];
               // simple C escapes
               if (isset($str_eq[$c])) {
                  $val .= $str_eq[$c];
               }

               // here we transform \uXXXX Unicode (always 4 nibbles) references to UTF-8
               elseif ($c == "u") {
                  // read just 16bit (therefore value can't be negative)
                  $hex = hexdec( substr($json, $n+1, 4) );
                  $n += 4;
                  // Unicode ranges
                  if ($hex < 0x80) {    // plain ASCII character
                     $val .= chr($hex);
                  }
                  elseif ($hex < 0x800) {   // 110xxxxx 10xxxxxx 
                     $val .= chr(0xC0 + $hex>>6) . chr(0x80 + $hex&63);
                  }
                  elseif ($hex <= 0xFFFF) { // 1110xxxx 10xxxxxx 10xxxxxx 
                     $val .= chr(0xE0 + $hex>>12) . chr(0x80 + ($hex>>6)&63) . chr(0x80 + $hex&63);
                  }
                  // other ranges, like 0x1FFFFF=0xF0, 0x3FFFFFF=0xF8 and 0x7FFFFFFF=0xFC do not apply
               }

               // no escape, just a redundant backslash
               //@COMPAT: we could throw an exception here
               else {
                  $val .= "\\" . $c;
               }
            }

            // end of string
            elseif ($c == '"') {
               $state = 0;
            }

            // yeeha! a single character found!!!!1!
            else/*if (ord($c) >= 32)*/ { //@COMPAT: specialchars check - but native json doesn't do it?
               $val .= $c;
            }
         }

         #-> end of sub-call (array/object)
         elseif ($waitfor && (strpos($waitfor, $c) !== false)) {
            return array($val, $n);  // return current value and state
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
            $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 = '"';







|







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
            $val[$i] = $v;
            if ($json[$n] == "}") { return array($val, $n); }
         }

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

            #-> string begin
            elseif ($c == '"') {
               $state = '"';
294
295
296
297
298
299
300
301
302
303
304









305
306
307
308
309
310
311
            #-> 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)) {







|


|
>
>
>
>
>
>
>
>
>







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
            #-> 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;
               if (strpos($val, ".")) {  // float
                  $val = (float)$val;
               }
               elseif ($val[0] == "0") {  // oct
                  $val = octdec($val);
               }
               else {
                  $val = (int)$val;
               }
               // exponent?
               if (isset($uu[2])) {
                  $val *= pow(10, (int)$uu[2]);
               }
            }

            #-> boolean or null
            elseif (preg_match("#^(true|false|null)\b#", substr($json, $n), $uu)) {
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
}




/**
 * @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");
   }
}









>

|













>
>
>
>
>
>
>
>
>
>







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
}




/**
 * @flag quirky, exec
 * @realmode
 *
 * Change owner of a symlink filename.
 *
 */
if (!function_exists("lchown")) {
   function lchown($fn, $user) {
      if (PHP_OS != "Linux") {
         return false;
      }
      $user = escapeshellcmd($user);
      $fn = escapeshellcmd($fn);
      exec("chown -h '$user' '$fn'", $uu, $state);
      return($state);
   }
}



/**
 * @flag quirky, exec
 * @realmode
 *
 * Change group of a symlink filename.
 *
 */
if (!function_exists("lchgrp")) {
   function lchgrp($fn, $group) {
      return lchown($fn, ":$group");
   }
}


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







>
|
>
>
















>

|




<
<
|

<

|
>
>
>
|
|

|
|

>




>
>
|
<
>
>







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
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 eventually &quot; 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 needs5
 *
 * Checks for existence of object property, should return TRUE even for NULL values.
 *
 * @compat


 *    no test for edge cases
 */

if (!function_exists("property_exists")) {
   function property_exists($obj, $propname) {
      if (is_object($obj)) {
         $props = get_object_vars($obj);
      }
      elseif (class_exists($obj)) {
         $props = get_class_vars($obj);
      }
      if (!@$props) {
         return false;
      }
      return @array_walk($props, "strtolower") && in_array(strtolower($propname), $props);
   }
}



/**
 * halt execution, until given timestamp

 *
 */
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;
      }
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649




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







|







699
700
701
702
703
704
705
706
707
708
709
710
711
712
713




/**
 *                                   --------------------------- FUTURE ---
 * @group FUTURE
 * @since future
 *
 * 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
657
658
659
660
661
662
663


664
665
666

667
668
669
670
671
672
673
 *    ... 
 *
 */







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

      #-- decode header
      $len = strlen($data);
      if ($len < 20) {
         return;







>
>
|
|
|
>







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
 *    ... 
 *
 */




/**
 * @since future
 *
 * 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) {

      #-- decode header
      $len = strlen($data);
      if ($len < 20) {
         return;
730
731
732
733
734
735
736
737


738
739


740
741
742
743
744
745
746


747
748
749
750




751
752
753
754
755
756
757
      else {
         return($data);
      }
   }
}


#-- get all already made headers(),


#   CANNOT be emulated, because output buffering functions
#   already swallow up any sent http header


if (!function_exists("ob_get_headers")) {
   function ob_get_headers() {
      return (array)NULL;
   }
}




#-- encodes required named XML entities, like htmlentities(),
#   but does not re-encode numeric &#xxxx; character references
#   - could screw up scripts which then implement this themselves
#   - doesn't fix bogus or invalid numeric entities




if (!function_exists("xmlentities")) {
   function xmlentities($str) {
      return strtr($str, array(
        "&#"=>"&#", "&"=>"&amp;", "'"=>"&apos;",
        "<"=>"&lt;", ">"=>"&gt;", "\""=>"&quot;", 
      ));
   }







|
>
>
|
|
>
>







>
>
|
|
|
|
>
>
>
>







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
      else {
         return($data);
      }
   }
}



/**
 * get all ob_ soaked headers(),
 * CANNOT be emulated, because output buffering functions
 * already swallow up any sent http header
 *
 */
if (!function_exists("ob_get_headers")) {
   function ob_get_headers() {
      return (array)NULL;
   }
}



/**
 * encodes required named XML entities, like htmlentities(),
 * but does not re-encode numeric &#xxxx; character references
 *  - could screw up scripts which then implement this themselves
 *  - doesn't fix bogus or invalid numeric entities
 *
 * @param string
 * @return string
 */
if (!function_exists("xmlentities")) {
   function xmlentities($str) {
      return strtr($str, array(
        "&#"=>"&#", "&"=>"&amp;", "'"=>"&apos;",
        "<"=>"&lt;", ">"=>"&gt;", "\""=>"&quot;", 
      ));
   }
809
810
811
812
813
814
815

816
817
818
819
820

821
822
823


824
825
826

827
828
829
830
831
832


833
834
835

836
837
838
839
840
841
842
843
844
845
846
847
848
849



850
851
852


853
854
855
856
857
858
859
 *
 * @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) {
   
      #-- simply lowercase args
      $haystack = strtolower($haystack);
      $needle = strtolower($needle);
      
      #-- search
      $pos = strpos($haystack, $needle, $offset);
      return($pos);
   }
}





#-- case-insensitive string search function
#   - but this one starts from the end of string (right to left)
#   - offset can be negative or positive


if (!function_exists("strripos")) {
   function strripos($haystack, $needle, $offset=NULL) {

      #-- lowercase incoming strings
      $haystack = strtolower($haystack);
      $needle = strtolower($needle);








>





>



>
>


|
>






>
>
|
|
|
>














>
>
>
|
|
|
>
>







886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
 *
 * @missing
 *    proc_nice
 *    dns_get_record
 *    date_sunrise - undoc.
 *    date_sunset - undoc.
 *    PHP_CONFIG_FILE_SCAN_DIR
 *    clone
 *
 * @unimplementable
 *    set_exception_handler
 *    restore_exception_handler
 *    debug_print_backtrace
 *    debug_backtrace
 *    class_implements
 *    proc_terminate
 *    proc_get_status
 *    range        - new param
 *    microtime    - new param
 *
 */
 
 


#-- 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) {
   
      #-- simply lowercase args
      $haystack = strtolower($haystack);
      $needle = strtolower($needle);
      
      #-- search
      $pos = strpos($haystack, $needle, $offset);
      return($pos);
   }
}




/**
 * case-insensitive string search function
 * - but this one starts from the end of string (right to left)
 * - offset can be negative or positive
 * 
 */
if (!function_exists("strripos")) {
   function strripos($haystack, $needle, $offset=NULL) {

      #-- lowercase incoming strings
      $haystack = strtolower($haystack);
      $needle = strtolower($needle);

873
874
875
876
877
878
879

880


881
882
883
884
885
886
887

      #-- result      
      return($pos);
   }
}



#-- case-insensitive version of str_replace


if (!function_exists("str_ireplace")) {
   function str_ireplace($search, $replace, $subject, $count=NULL) {

      #-- call ourselves recursively, if parameters are arrays/lists 
      if (is_array($search)) {
         $replace = array_values($replace);
         foreach (array_values($search) as $i=>$srch) {







>
|
>
>







963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980

      #-- result      
      return($pos);
   }
}


/**
 * case-insensitive version of str_replace
 * 
 */
if (!function_exists("str_ireplace")) {
   function str_ireplace($search, $replace, $subject, $count=NULL) {

      #-- call ourselves recursively, if parameters are arrays/lists 
      if (is_array($search)) {
         $replace = array_values($replace);
         foreach (array_values($search) as $i=>$srch) {
899
900
901
902
903
904
905

906


907
908
909
910
911
912
913

      #-- result
      return($subject);
   }
}



#-- performs a http HEAD request


if (!function_exists("get_headers")) {
   function get_headers($url, $parse=0) {
   
      #-- extract URL parts ($host, $port, $path, ...)
      $c = parse_url($url);
      extract($c);
      if (!isset($port)) { 







>
|
>
>







992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009

      #-- result
      return($subject);
   }
}


/**
 * performs a http HEAD request
 * 
 */
if (!function_exists("get_headers")) {
   function get_headers($url, $parse=0) {
   
      #-- extract URL parts ($host, $port, $path, ...)
      $c = parse_url($url);
      extract($c);
      if (!isset($port)) { 
961
962
963
964
965
966
967


968
969


970
971
972
973
974
975
976
977

978
979


980
981
982
983
984
985
986
987
988

989


990
991
992
993
994
995
996

997

998

999
1000
1001
1002
1003
1004
1005
      #-- close TCP connection and give result
      fclose($f);
      return($ls);
   }
}




#-- list of already/potentially sent HTTP responsee headers(),
#   CANNOT be implemented (except for Apache module maybe)


if (!function_exists("headers_list")) {
   function headers_list() {
      trigger_error("headers_list(): not supported by this PHP version", E_USER_WARNING);
      return (array)NULL;
   }
}



#-- write formatted string to stream/file,
#   arbitrary numer of arguments


if (!function_exists("fprintf")) {
   function fprintf(/*...*/) {
      $args = func_get_args();
      $stream = array_shift($args);
      return fwrite($stream, call_user_func_array("sprintf", $args));
   }
}



#-- write formatted string to stream, args array


if (!function_exists("vfprintf")) {
   function vfprintf($stream, $format, $args=NULL) {
      return fwrite($stream, vsprintf($format, $args));
   }
}



#-- splits a string in evenly sized chunks

#   and returns this as array

if (!function_exists("str_split")) {
   function str_split($str, $chunk=1) {
      $r = array();
      
      #-- return back as one chunk completely, if size chosen too low
      if ($chunk < 1) {
         $r[] = $str;







>
>
|
|
>
>








>
|
|
>
>









>
|
>
>







>
|
>
|
>







1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
      #-- close TCP connection and give result
      fclose($f);
      return($ls);
   }
}


/**
 * @stub
 * list of already/potentially sent HTTP responsee headers(),
 * CANNOT be implemented (except for Apache module maybe)
 * 
 */
if (!function_exists("headers_list")) {
   function headers_list() {
      trigger_error("headers_list(): not supported by this PHP version", E_USER_WARNING);
      return (array)NULL;
   }
}


/**
 * write formatted string to stream/file,
 * arbitrary numer of arguments
 * 
 */
if (!function_exists("fprintf")) {
   function fprintf(/*...*/) {
      $args = func_get_args();
      $stream = array_shift($args);
      return fwrite($stream, call_user_func_array("sprintf", $args));
   }
}


/**
 * write formatted string to stream, args array
 * 
 */
if (!function_exists("vfprintf")) {
   function vfprintf($stream, $format, $args=NULL) {
      return fwrite($stream, vsprintf($format, $args));
   }
}


/**
 * splits a string in evenly sized chunks
 * 
 * @return array
 */
if (!function_exists("str_split")) {
   function str_split($str, $chunk=1) {
      $r = array();
      
      #-- return back as one chunk completely, if size chosen too low
      if ($chunk < 1) {
         $r[] = $str;
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022







1023
1024
1025
1026
1027
1028
1029
         }
      }
      return($r);
   }
}



#-- constructs a QUERY_STRING (application/x-www-form-urlencoded format, non-raw)
#   from a nested array/hash with name=>value pairs
#   - only first two args are part of the original API - rest used for recursion







if (!function_exists("http_build_query")) {
   function http_build_query($data, $int_prefix="", $subarray_pfix="", $level=0) {
   
      #-- empty starting string
      $s = "";
      ($SEP = ini_get("arg_separator.output")) or ($SEP = "&");
      







>
|
|
|
>
>
>
>
>
>
>







1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
         }
      }
      return($r);
   }
}


/**
 * constructs a QUERY_STRING (application/x-www-form-urlencoded format, non-raw)
 * from a nested array/hash with name=>value pairs
 * - only first two args are part of the original API - rest used for recursion
 *
 * @param  mixed  $data           variable data for query string
 * @param  string $int_prefix     (optional)
 * @param  string $subarray_pfix  (optional)
 * @param integer $level  
 * @return mixed
 */
if (!function_exists("http_build_query")) {
   function http_build_query($data, $int_prefix="", $subarray_pfix="", $level=0) {
   
      #-- empty starting string
      $s = "";
      ($SEP = ini_get("arg_separator.output")) or ($SEP = "&");
      
1058
1059
1060
1061
1062
1063
1064

1065
1066




1067
1068
1069
1070
1071
1072
1073

      #-- return result / to previous array level and iteration
      return($s);
   }
}



#-- transform into 3to4 uuencode
#   - this is the bare encoding, not the uu file format




if (!function_exists("convert_uuencode")) {
   function convert_uuencode($data) {

      #-- init vars
      $out = "";
      $line = "";
      $len = strlen($data);







>
|
|
>
>
>
>







1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

      #-- return result / to previous array level and iteration
      return($s);
   }
}


/**
 * transform into 3to4 uuencode
 * - this is the bare encoding, not the uu file format
 * 
 * @param  string
 * @return string
 */
if (!function_exists("convert_uuencode")) {
   function convert_uuencode($data) {

      #-- init vars
      $out = "";
      $line = "";
      $len = strlen($data);
1102
1103
1104
1105
1106
1107
1108

1109




1110
1111
1112
1113
1114
1115
1116
      // uuencode(5) doesn't tell so, but spaces are replaced with the ` char in most implementations
      $out = strtr("$out \n", " ", "`");
      return($out);
   }
}



#-- decodes uuencoded() data again




if (!function_exists("convert_uudecode")) {
   function convert_uudecode($data) {

      #-- prepare
      $out = "";
      $data = strtr($data, "`", " ");
      







>
|
>
>
>
>







1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
      // uuencode(5) doesn't tell so, but spaces are replaced with the ` char in most implementations
      $out = strtr("$out \n", " ", "`");
      return($out);
   }
}


/**
 * decodes uuencoded() data again
 *
 * @param  string $data  
 * @return string
 */
if (!function_exists("convert_uudecode")) {
   function convert_uudecode($data) {

      #-- prepare
      $out = "";
      $data = strtr($data, "`", " ");
      
1150
1151
1152
1153
1154
1155
1156

1157
1158





1159
1160
1161
1162
1163
1164
1165
      }

      return($out);
   }
}



#-- return array of filenames in a given directory
#   (only works for local files)





if (!function_exists("scandir")) {
   function scandir($dirname, $desc=0) {
   
      #-- check for file:// protocol, others aren't handled
      if (strpos($dirname, "file://") === 0) {
         $dirname = substr($dirname, 7);
         if (strpos($dirname, "localh") === 0) {







>
|
|
>
>
>
>
>







1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
      }

      return($out);
   }
}


/**
 * return array of filenames in a given directory
 * (only works for local files)
 *
 * @param  string $dirname  
 * @param  bool   $desc  
 * @return array
 */
if (!function_exists("scandir")) {
   function scandir($dirname, $desc=0) {
   
      #-- check for file:// protocol, others aren't handled
      if (strpos($dirname, "file://") === 0) {
         $dirname = substr($dirname, 7);
         if (strpos($dirname, "localh") === 0) {
1187
1188
1189
1190
1191
1192
1193

1194





1195
1196
1197
1198
1199
1200
1201

      #-- failure
      return false;
   }
}



#-- like date(), but returns an integer for given one-letter format parameter





if (!function_exists("idate")) {
   function idate($formatchar, $timestamp=NULL) {
   
      #-- reject non-simple type parameters
      if (strlen($formatchar) != 1) {
         return false;
      }







>
|
>
>
>
>
>







1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340

      #-- failure
      return false;
   }
}


/**
 * like date(), but returns an integer for given one-letter format parameter
 *
 * @param  string  $formatchar
 * @param  integer $timestamp
 * @return integer
 */
if (!function_exists("idate")) {
   function idate($formatchar, $timestamp=NULL) {
   
      #-- reject non-simple type parameters
      if (strlen($formatchar) != 1) {
         return false;
      }
1209
1210
1211
1212
1213
1214
1215

1216


1217
1218
1219
1220
1221
1222
1223
1224
1225


1226
1227





1228
1229
1230
1231
1232
1233
1234
      $str = date($formatchar, $timestamp);
      return (int)$str;
   }
}




#-- combined sleep() and usleep() 


if (!function_exists("time_nanosleep")) {
   function time_nanosleep($sec, $nano) {
      sleep($sec);
      usleep($nano);
   }
}





#-- search first occourence of any of the given chars, returns rest of haystack
#   (char_list must be a string for compatibility with the real PHP func)





if (!function_exists("strpbrk")) {
   function strpbrk($haystack, $char_list) {
   
      #-- prepare
      $len = strlen($char_list);
      $min = strlen($haystack);
      







>
|
>
>









>
>
|
|
>
>
>
>
>







1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
      $str = date($formatchar, $timestamp);
      return (int)$str;
   }
}



/**
 * combined sleep() and usleep() 
 * 
 */
if (!function_exists("time_nanosleep")) {
   function time_nanosleep($sec, $nano) {
      sleep($sec);
      usleep($nano);
   }
}




/**
 * search first occourence of any of the given chars, returns rest of haystack
 * (char_list must be a string for compatibility with the real PHP func)
 *
 * @param  string $haystack  
 * @param  string $char_list  
 * @return integer
 */
if (!function_exists("strpbrk")) {
   function strpbrk($haystack, $char_list) {
   
      #-- prepare
      $len = strlen($char_list);
      $min = strlen($haystack);
      
1250
1251
1252
1253
1254
1255
1256

1257


1258
1259
1260
1261
1262
1263

1264
1265


1266
1267
1268
1269
1270
1271
1272
1273


1274
1275





1276
1277
1278
1279
1280
1281
1282
         return(false);
      }
   }
}




#-- logo image activation URL query strings (gaga feature)


if (!function_exists("php_real_logo_guid")) {
   function php_real_logo_guid() { return php_logo_guid(); }
   function php_egg_logo_guid() { return zend_logo_guid(); }
}



#-- no need to implement this
#   (there aren't interfaces in PHP4 anyhow)


if (!function_exists("get_declared_interfaces")) {
   function get_declared_interfaces() {
      trigger_error("get_declared_interfaces(): Current script won't run reliably with PHP4.", E_USER_WARNING);
      return( (array)NULL );
   }
}




#-- creates an array from lists of $keys and $values
#   (both should have same number of entries)





if (!function_exists("array_combine")) {
   function array_combine($keys, $values) {
   
      #-- convert input arrays into lists
      $keys = array_values($keys);
      $values = array_values($values);
      $r = array();







>
|
>
>






>
|
|
>
>








>
>
|
|
>
>
>
>
>







1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
         return(false);
      }
   }
}



/**
 * logo image activation URL query strings (gaga feature)
 * 
 */
if (!function_exists("php_real_logo_guid")) {
   function php_real_logo_guid() { return php_logo_guid(); }
   function php_egg_logo_guid() { return zend_logo_guid(); }
}


/**
 * no need to implement this
 * (there aren't interfaces in PHP4 anyhow)
 * 
 */
if (!function_exists("get_declared_interfaces")) {
   function get_declared_interfaces() {
      trigger_error("get_declared_interfaces(): Current script won't run reliably with PHP4.", E_USER_WARNING);
      return( (array)NULL );
   }
}



/**
 * creates an array from lists of $keys and $values
 * (both should have same number of entries)
 *
 * @param  array $keys  
 * @param  array $values  
 * @return array
 */
if (!function_exists("array_combine")) {
   function array_combine($keys, $values) {
   
      #-- convert input arrays into lists
      $keys = array_values($keys);
      $values = array_values($values);
      $r = array();
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300






1301
1302
1303
1304
1305
1306
1307
         }
      }
      return($r);
   }
}



#-- apply userfunction to each array element (descending recursively)
#   use it like:  array_walk_recursive($_POST, "stripslashes");
#   - $callback can be static function name or object/method, class/method






if (!function_exists("array_walk_recursive")) {
   function array_walk_recursive(&$input, $callback, $userdata=NULL) {
      #-- each entry
      foreach ($input as $key=>$value) {

         #-- recurse for sub-arrays
         if (is_array($value)) {







>
|
|
|
>
>
>
>
>
>







1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
         }
      }
      return($r);
   }
}


/**
 * apply userfunction to each array element (descending recursively)
 * use it like:  array_walk_recursive($_POST, "stripslashes");
 * - $callback can be static function name or object/method, class/method
 *
 * @param  array  $input  
 * @param  string $callback  
 * @param  array  $userdata  (optional)
 * @return array
 */
if (!function_exists("array_walk_recursive")) {
   function array_walk_recursive(&$input, $callback, $userdata=NULL) {
      #-- each entry
      foreach ($input as $key=>$value) {

         #-- recurse for sub-arrays
         if (is_array($value)) {
1315
1316
1317
1318
1319
1320
1321

1322








1323
1324
1325
1326
1327
1328
1329
      }

      // no return value
   }
}



#-- complicated wrapper around substr() and and strncmp()








if (!function_exists("substr_compare")) {
   function substr_compare($haystack, $needle, $offset=0, $len=0, $ci=0) {

      #-- check params   
      if ($len <= 0) {   // not well documented
         $len = strlen($needle);
         if (!$len) { return(0); }







>
|
>
>
>
>
>
>
>
>







1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
      }

      // no return value
   }
}


/**
 * complicated wrapper around substr() and and strncmp()
 *
 * @param  string  $haystack  
 * @param  string  $needle  
 * @param  integer $offset  
 * @param  integer $len  
 * @param  integer $ci  
 * @return mixed
 */
if (!function_exists("substr_compare")) {
   function substr_compare($haystack, $needle, $offset=0, $len=0, $ci=0) {

      #-- check params   
      if ($len <= 0) {   // not well documented
         $len = strlen($needle);
         if (!$len) { return(0); }
1346
1347
1348
1349
1350
1351
1352

1353
1354


1355
1356
1357
1358
1359
1360
1361
1362
1363

1364




1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382

1383


1384
1385
1386
1387
1388
1389
1390
1391

1392





1393
1394
1395
1396
1397
1398
1399

      #-- do
      return(strncmp($haystack, $needle, $len));
   }
}



#-- stub, returns empty list as usual;
#   you must load "ext/spl.php" beforehand to get this


if (!function_exists("spl_classes")) {
   function spl_classes() {
      trigger_error("spl_classes(): not built into this PHP version");
      return (array)NULL;
   }
}




#-- gets you list of class names the given objects class was derived from, slow




if (!function_exists("class_parents")) {
   function class_parents($obj) {
   
      #-- first get full list
      $all = get_declared_classes();
      $r = array();
      
      #-- filter out
      foreach ($all as $potential_parent) {
         if (is_subclass_of($obj, $potential_parent)) {
            $r[$potential_parent] = $potential_parent;
         }
      }
      return($r);
   }
}



#-- an alias


if (!function_exists("session_commit") && function_exists("session_write_close")) {
   function session_commit() {
      // simple
      session_write_close();
   }
}



#-- aliases





if (!function_exists("dns_check_record")) {
   function dns_check_record($host, $type=NULL) {
      // synonym to
      return checkdnsrr($host, $type);
   }
}
if (!function_exists("dns_get_mx")) {







>
|
|
>
>









>
|
>
>
>
>


















>
|
>
>








>
|
>
>
>
>
>







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
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594

      #-- do
      return(strncmp($haystack, $needle, $len));
   }
}


/**
 * stub, returns empty list as usual;
 * you must load "ext/spl.php" beforehand to get this
 * 
 */
if (!function_exists("spl_classes")) {
   function spl_classes() {
      trigger_error("spl_classes(): not built into this PHP version");
      return (array)NULL;
   }
}



/**
 * gets you list of class names the given objects class was derived from, slow
 *
 * @param  object $obj  
 * @return object
 */
if (!function_exists("class_parents")) {
   function class_parents($obj) {
   
      #-- first get full list
      $all = get_declared_classes();
      $r = array();
      
      #-- filter out
      foreach ($all as $potential_parent) {
         if (is_subclass_of($obj, $potential_parent)) {
            $r[$potential_parent] = $potential_parent;
         }
      }
      return($r);
   }
}


/**
 * an alias
 * 
 */
if (!function_exists("session_commit") && function_exists("session_write_close")) {
   function session_commit() {
      // simple
      session_write_close();
   }
}


/**
 * aliases
 *
 * @param  mixed $host  
 * @param  mixed $type  (optional)
 * @return mixed
 */
if (!function_exists("dns_check_record")) {
   function dns_check_record($host, $type=NULL) {
      // synonym to
      return checkdnsrr($host, $type);
   }
}
if (!function_exists("dns_get_mx")) {
1407
1408
1409
1410
1411
1412
1413

1414
1415









1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434

1435







1436
1437
1438
1439
1440
1441
1442






1443
1444
1445
1446







1447
1448
1449
1450
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
1480
1481
1482
1483
         $w = false;
      }
      return getmxrr($host, $mx, $w);
   }
}



#-- setrawcookie(),
#   can this be emulated 100% exactly?









if (!function_exists("setrawcookie")) {
   // we output everything directly as HTTP header(), PHP doesn't seem
   // to manage an internal cookie list anyhow
   function setrawcookie($name, $value=NULL, $expire=NULL, $path=NULL, $domain=NULL, $secure=0) {
      if (isset($value) && strpbrk($value, ",; \r\t\n\f\014\013")) {
         trigger_error("setrawcookie: value may not contain any of ',; \r\n' and some other control chars; thrown away", E_USER_WARNING);
      }
      else {
         $h = "Set-Cookie: $name=$value"
            . ($expire ? "; expires=" . gmstrftime("%a, %d-%b-%y %H:%M:%S %Z", $expire) : "")
            . ($path ? "; path=$path": "")
            . ($domain ? "; domain=$domain" : "")
            . ($secure ? "; secure" : "");
         header($h);
      }
   }
}



#-- write-at-once file access (counterpart to file_get_contents)







if (!function_exists("file_put_contents")) {
   function file_put_contents($filename, $data, $flags=0, $resource=NULL) {

      #-- prepare
      $mode = ($flags & FILE_APPEND ? "a" : "w" ) ."b";
      $incl = $flags & FILE_USE_INCLUDE_PATH;
      $length = strlen($data);







      #-- open for writing
      $f = fopen($filename, $mode, $incl);
      if ($f) {







         $written = fwrite($f, $data);
         fclose($f);
         
         #-- only report success, if completely saved
         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) {
         return(count($array));
      }
      else {
         $c = count($array);







>
|
|
>
>
>
>
>
>
>
>
>



















>
|
>
>
>
>
>
>
>







>
>
>
>
>
>




>
>
>
>
>
>
>










>
|
>
>





>






>



|


>
>
>
>
>
|
|
>
>
>
>
>







1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
         $w = false;
      }
      return getmxrr($host, $mx, $w);
   }
}


/**
 * setrawcookie(),
 * can this be emulated 100% exactly?
 *
 * @param  string $name 
 * @param  mixed  $value
 * @param  mixed  $expire
 * @param  mixed  $path
 * @param  mixed  $domain
 * @param integer $secure
 * @return string
 */
if (!function_exists("setrawcookie")) {
   // we output everything directly as HTTP header(), PHP doesn't seem
   // to manage an internal cookie list anyhow
   function setrawcookie($name, $value=NULL, $expire=NULL, $path=NULL, $domain=NULL, $secure=0) {
      if (isset($value) && strpbrk($value, ",; \r\t\n\f\014\013")) {
         trigger_error("setrawcookie: value may not contain any of ',; \r\n' and some other control chars; thrown away", E_USER_WARNING);
      }
      else {
         $h = "Set-Cookie: $name=$value"
            . ($expire ? "; expires=" . gmstrftime("%a, %d-%b-%y %H:%M:%S %Z", $expire) : "")
            . ($path ? "; path=$path": "")
            . ($domain ? "; domain=$domain" : "")
            . ($secure ? "; secure" : "");
         header($h);
      }
   }
}


/**
 * write-at-once file access (counterpart to file_get_contents)
 *
 * @param  integer $filename
 * @param  mixed   $data  
 * @param  integer $flags 
 * @param  mixed   $resource
 * @return integer
 */
if (!function_exists("file_put_contents")) {
   function file_put_contents($filename, $data, $flags=0, $resource=NULL) {

      #-- prepare
      $mode = ($flags & FILE_APPEND ? "a" : "w" ) ."b";
      $incl = $flags & FILE_USE_INCLUDE_PATH;
      $length = strlen($data);
//      $resource && trigger_error("EMULATED file_put_contents does not support \$resource parameter.", E_USER_ERROR);
      
      #-- data
      if (is_array($data) || is_object($data)) {
         $data = implode("", (array)$data);
      }

      #-- open for writing
      $f = fopen($filename, $mode, $incl);
      if ($f) {
      
         // locking
         if (($flags & LOCK_EX) && !flock($f, LOCK_EX)) {
            return fclose($f) && false;
         }

         // write
         $written = fwrite($f, $data);
         fclose($f);
         
         #-- only report success, if completely saved
         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); }    // use count_recursive()



/**
 * @since never
 * @nonstandard
 * 
 * we introduce a new function, because we cannot emulate the
 * newly introduced second parameter to count()
 * 
 * @param  array $array 
 * @param  integer $mode
 * @return integer
 */
if (!function_exists("count_recursive")) {
   function count_recursive($array, $mode=1) {
      if (!$mode) {
         return(count($array));
      }
      else {
         $c = count($array);
1565
1566
1567
1568
1569
1570
1571

1572





1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589






1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
 *
 * @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
      $f = fopen($filename, "rb", $use_include_path);
      if (!$f) { return; }

      #-- read max 2MB
      $content = fread($f, 1<<21);
      fclose($f);
      return($content);
   }
}




#-- 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] != ".")) {
            return(false);    // abort early
         }
      }

      #-- case-insensitivity
      $rxci = "";
      if ($flags & FNM_CASEFOLD) {







>
|
>
>
>
>
>
















>
|
>
>
>
>
>
>











|



|







1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
 *
 * @unimplementable
 *    money_format
 *
 */


/**
 * simplified file read-at-once function
 *
 * @param  string  $filename  
 * @param  integer $use_include_path  (optional)
 * @return string
 */
if (!function_exists("file_get_contents")) {
   function file_get_contents($filename, $use_include_path=1) {

      #-- open file, let fopen() report error
      $f = fopen($filename, "rb", $use_include_path);
      if (!$f) { return; }

      #-- read max 2MB
      $content = fread($f, 1<<21);
      fclose($f);
      return($content);
   }
}



/**
 * shell-like filename matching (* and ? globbing characters)
 *
 * @param  string $pattern  glob-pattern with *s and ?s
 * @param  string $fn       filename to match it against (without path)
 * @param integer $flags    (optional)
 * @return bool
 */
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, $fn, $flags=0x0000) {
      
      #-- 'hidden' files
      if ($flags & FNM_PERIOD) {
         if (($fn[0] == ".") && ($pattern[0] != ".")) {
            return(false);    // abort early
         }
      }

      #-- case-insensitivity
      $rxci = "";
      if ($flags & FNM_CASEFOLD) {
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647

1648





1649
1650
1651
1652
1653
1654
1655
         if (count($cmp) >= 50) {
            $cmp = array();   // free
         }
         $cmp["$pattern+$flags"] = $rx;
      }
      
      #-- compare
      return(preg_match($rx, $str));
   }
}



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







|




>
|
>
>
>
>
>







1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
         if (count($cmp) >= 50) {
            $cmp = array();   // free
         }
         $cmp["$pattern+$flags"] = $rx;
      }
      
      #-- compare
      return(preg_match($rx, $fn));
   }
}


/**
 * file search and name matching (with shell patterns)
 *
 * @param  string  $pattern   search pattern and path ../* string
 * @param  integer $flags (optional)
 * @return array
 */
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); }
1752
1753
1754
1755
1756
1757
1758


1759


1760
1761
1762
1763
1764
1765
1766

1767


1768
1769
1770
1771
1772
1773
1774
#print_r($ls);
#echo "<=\n";
      return($ls);
   }
} //@FIX: fully comment, remove debugging code (- as soon as it works ;)




#-- redundant alias for isset()


if (!function_exists("array_key_exists")) {
   function array_key_exists($key, $search) {
      return isset($search[$key]);
   }
}



#-- who could need that?


if (!function_exists("array_intersect_assoc")) {
   function array_intersect_assoc( /*array, array, array...*/ ) {

      #-- parameters, prepare
      $in = func_get_args();
      $cmax = count($in);
      $whatsleftover = array();







>
>
|
>
>







>
|
>
>







2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
#print_r($ls);
#echo "<=\n";
      return($ls);
   }
} //@FIX: fully comment, remove debugging code (- as soon as it works ;)



/**
 * redundant alias for isset()
 * 
 */
if (!function_exists("array_key_exists")) {
   function array_key_exists($key, $search) {
      return isset($search[$key]);
   }
}


/**
 * who could need that?
 * 
 */
if (!function_exists("array_intersect_assoc")) {
   function array_intersect_assoc( /*array, array, array...*/ ) {

      #-- parameters, prepare
      $in = func_get_args();
      $cmax = count($in);
      $whatsleftover = array();
1787
1788
1789
1790
1791
1792
1793

1794


1795
1796
1797
1798
1799
1800
1801
         $whatsleftover[$i] = $v;
      }
      return $whatsleftover;
   }
}



#-- the opposite of the above


if (!function_exists("array_diff_assoc")) {
   function array_diff_assoc( /*array, array, array...*/ ) {

      #-- params
      $in = func_get_args();
      $diff = array();
      







>
|
>
>







2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
         $whatsleftover[$i] = $v;
      }
      return $whatsleftover;
   }
}


/**
 * the opposite of the above
 * 
 */
if (!function_exists("array_diff_assoc")) {
   function array_diff_assoc( /*array, array, array...*/ ) {

      #-- params
      $in = func_get_args();
      $diff = array();
      
1811
1812
1813
1814
1815
1816
1817

1818


1819
1820
1821
1822
1823
1824
1825
1826
1827

1828


1829
1830
1831
1832
1833
1834
1835
         $diff[$i] = $v;
      }
      return $diff;
   }
}



#-- opposite of htmlentities


if (!function_exists("html_entity_decode")) {
   function html_entity_decode($string, $quote_style=ENT_COMPAT, $charset="ISO-8859-1") {
      //@FIX: we fall short on anything other than Latin-1
      $y = array_flip(get_html_translation_table(HTML_ENTITIES, $quote_style));
      return strtr($string, $y);
   }
}



#-- extracts single words from a string


if (!function_exists("str_word_count")) {
   function str_word_count($string, $result=0) {
   
      #-- let someone else do the work
      preg_match_all('/([\w](?:[-\'\w]?[\w]+)*)/', $string, $uu);

      #-- return full word list







>
|
>
>









>
|
>
>







2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
         $diff[$i] = $v;
      }
      return $diff;
   }
}


/**
 * opposite of htmlentities
 * 
 */
if (!function_exists("html_entity_decode")) {
   function html_entity_decode($string, $quote_style=ENT_COMPAT, $charset="ISO-8859-1") {
      //@FIX: we fall short on anything other than Latin-1
      $y = array_flip(get_html_translation_table(HTML_ENTITIES, $quote_style));
      return strtr($string, $y);
   }
}


/**
 * extracts single words from a string
 * 
 */
if (!function_exists("str_word_count")) {
   function str_word_count($string, $result=0) {
   
      #-- let someone else do the work
      preg_match_all('/([\w](?:[-\'\w]?[\w]+)*)/', $string, $uu);

      #-- return full word list
1853
1854
1855
1856
1857
1858
1859

1860
1861


1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881

1882


1883
1884
1885
1886
1887
1888
1889
      else {
         return(count($uu[1]));
      }
   }
}



#-- creates a permutation of the given strings characters
#   (let's hope the random number generator was alread initialized)


if (!function_exists("str_shuffle")) {
   function str_shuffle($str) {
      $r = "";

      #-- cut string down with every iteration
      while (strlen($str)) {
         $n = strlen($str) - 1;
         if ($n) {
            $n = rand(0, $n);   // glibcs` rand is ok since 2.1 at least
         }
         
         #-- cut out elected char, add to result string
         $r .= $str{$n};
         $str = substr($str, 0, $n) . substr($str, $n + 1);
      }
      return($r);
   }
}



#-- simple shorthands


if (!function_exists("get_include_path")) {
   function get_include_path() {
      return(get_cfg_var("include_path"));
   }
   function set_include_path($new) {
      return ini_set("include_path", $new);
   }







>
|
|
>
>




















>
|
>
>







2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
      else {
         return(count($uu[1]));
      }
   }
}


/**
 * creates a permutation of the given strings characters
 * (let's hope the random number generator was alread initialized)
 * 
 */
if (!function_exists("str_shuffle")) {
   function str_shuffle($str) {
      $r = "";

      #-- cut string down with every iteration
      while (strlen($str)) {
         $n = strlen($str) - 1;
         if ($n) {
            $n = rand(0, $n);   // glibcs` rand is ok since 2.1 at least
         }
         
         #-- cut out elected char, add to result string
         $r .= $str{$n};
         $str = substr($str, 0, $n) . substr($str, $n + 1);
      }
      return($r);
   }
}


/**
 * simple shorthands
 * 
 */
if (!function_exists("get_include_path")) {
   function get_include_path() {
      return(get_cfg_var("include_path"));
   }
   function set_include_path($new) {
      return ini_set("include_path", $new);
   }
1904
1905
1906
1907
1908
1909
1910

1911
























1912
1913
1914

1915



1916




1917
1918
1919
1920
1921
1922
1923
1924
1925
1926







1927
1928
1929
1930
1931
1932
1933
if (!defined("PHP_PREFIX") && isset($_ENV["_"])) { define("PHP_PREFIX", substr($_ENV["_"], 0, strpos($_ENV["_"], "bin/"))); }







#------------------------------------------------------------------ 4.2 ---
























# almost complete!?



#-- shy away from this one - it was broken in all real PHP4.2 versions, and



#   this function emulation script won't change that




if (!function_exists("str_rot13")) {
   function str_rot13($str) {
      static $from = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      static $to = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm";
      return strtr($str, $from, $to);
   }
}


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







>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
|
>
>
>
|
>
>
>
>









<
>
>
>
>
>
>
>







2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240

2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
if (!defined("PHP_PREFIX") && isset($_ENV["_"])) { define("PHP_PREFIX", substr($_ENV["_"], 0, strpos($_ENV["_"], "bin/"))); }






/**
 *                                   ------------------------------ 4.2 ---
 * @group 4_2
 * @since 4.2
 *
 *
 *  Functions added in PHP 4.2 interpreters.
 *
 *
 * @emulated
 *   str_rot13
 *   array_change_key_case
 *   array_fill
 *   array_chunk
 *   md5_file
 *   is_a
 *   fmod
 *   floatval
 *   is_infinite
 *   is_nan
 *   is_finite
 *   var_export
 *   strcoll
 * @missing
 *   ...
 *
 *   almost complete!?
 *
 *
 */


/**
 * shy away from this function - it was broken in all PHP4.2 releases,
 * and our emulation here won't change that
 *
 * @param  string $str  
 * @return string
 */
if (!function_exists("str_rot13")) {
   function str_rot13($str) {
      static $from = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      static $to = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm";
      return strtr($str, $from, $to);
   }
}



/**
 * changes case of textual index keys
 *
 * @param  array $array  
 * @param  int   $case
 * @return array
 */
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
1944
1945
1946
1947
1948
1949
1950

1951


1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969

1970


1971
1972
1973
1974
1975
1976
1977
         // non-recursive      
      }
      return($array);
   }
}



#-- create fixed-length array made up of $value data


if (!function_exists("array_fill")) {
   function array_fill($start_index, $num, $value) {

      #-- params
      $r = array();
      $i = $start_index;
      $end = $num + $start_index;
      
      #-- append
      for (; $i < $end; $i++)
      {
         $r[$i] = $value;
      }
      return($r);
   }
}



#-- split an array into evenly sized parts


if (!function_exists("array_chunk")) {
   function array_chunk($input, $size, $preserve_keys=false) {
   
      #-- array for chunked output
      $r = array();
      $n = -1;  // chunk index
      







>
|
>
>


















>
|
>
>







2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
         // non-recursive      
      }
      return($array);
   }
}


/**
 * create fixed-length array made up of $value data
 * 
 */
if (!function_exists("array_fill")) {
   function array_fill($start_index, $num, $value) {

      #-- params
      $r = array();
      $i = $start_index;
      $end = $num + $start_index;
      
      #-- append
      for (; $i < $end; $i++)
      {
         $r[$i] = $value;
      }
      return($r);
   }
}


/**
 * split an array into evenly sized parts
 * 
 */
if (!function_exists("array_chunk")) {
   function array_chunk($input, $size, $preserve_keys=false) {
   
      #-- array for chunked output
      $r = array();
      $n = -1;  // chunk index
      
1993
1994
1995
1996
1997
1998
1999

2000


2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017

2018


2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031

2032


2033
2034
2035
2036
2037
2038
2039
2040
2041
2042

2043




2044
2045
2046
2047
2048
2049
2050
2051

2052


2053
2054
2055
2056
2057
2058
2059
         }
      }
      return($r);
   }
}



#-- convenience wrapper


if (!function_exists("md5_file")) {
   function md5_file($filename, $raw_output=false) {

      #-- read file, apply hash function
      $data = file_get_contents($filename, "rb");
      $r = md5($data);
      $data = NULL;
         
      #-- transform? and return
      if ($raw_output) {
         $r = pack("H*", $r);
      }
      return $r;
   }
}



#-- object type checking


if (!function_exists("is_a")) {
   function is_a($obj, $classname) {
   
      #-- lowercase everything for comparison
      $classnaqme = strtolower($classname);
      $obj_class =  strtolower(get_class($obj));
      
      #-- two possible checks
      return ($obj_class == $classname) or is_subclass_of($obj, $classname);
   }
}



#-- floating point modulo


if (!function_exists("fmod")) {
   function fmod($x, $y) {
      $r = $x / $y;
      $r -= (int)$r;
      $r *= $y;
      return($r);
   }
}



#-- makes float variable from string




if (!function_exists("floatval")) {
   function floatval($str) {
      $str = ltrim($str);
      return (float)$str;
   }
}



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







>
|
>
>

















>
|
>
>













>
|
>
>










>
|
>
>
>
>








>
|
>
>







2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
         }
      }
      return($r);
   }
}


/**
 * convenience wrapper
 * 
 */
if (!function_exists("md5_file")) {
   function md5_file($filename, $raw_output=false) {

      #-- read file, apply hash function
      $data = file_get_contents($filename, "rb");
      $r = md5($data);
      $data = NULL;
         
      #-- transform? and return
      if ($raw_output) {
         $r = pack("H*", $r);
      }
      return $r;
   }
}


/**
 * object type checking
 * 
 */
if (!function_exists("is_a")) {
   function is_a($obj, $classname) {
   
      #-- lowercase everything for comparison
      $classnaqme = strtolower($classname);
      $obj_class =  strtolower(get_class($obj));
      
      #-- two possible checks
      return ($obj_class == $classname) or is_subclass_of($obj, $classname);
   }
}


/**
 * floating point modulo
 * 
 */
if (!function_exists("fmod")) {
   function fmod($x, $y) {
      $r = $x / $y;
      $r -= (int)$r;
      $r *= $y;
      return($r);
   }
}


/**
 * makes float variable from string
 *
 * @param  string
 * @return float
 */
if (!function_exists("floatval")) {
   function floatval($str) {
      $str = ltrim($str);
      return (float)$str;
   }
}


/**
 * 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
2068
2069
2070
2071
2072
2073
2074

2075


2076








2077
2078
2079
2080
2081
2082
2083
   function is_finite($f) {
      $s = (string)$f;
      return(  !strpos($s, "N")  );
   }
}



#-- throws value-instantiation PHP-code for given variable


#   (a bit different from the standard, was intentional for its orig use)








if (!function_exists("var_export")) {
   function var_export($var, $return=false, $indent="", $output="") {

      #-- output as in-class variable definitions
      if (is_object($var)) {
         $output = "class " . get_class($var) . " {\n";
         foreach (((array)$var) as $id=>$var) {







>
|
>
>
|
>
>
>
>
>
>
>
>







2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
   function is_finite($f) {
      $s = (string)$f;
      return(  !strpos($s, "N")  );
   }
}


/**
 * throws value-instantiation PHP-code for given variable
 *
 * @compat
 *    output differentiates from native PHP version,
 *    but functions identically
 *
 * @param  mixed $var  
 * @param  mixed $return  (optional) false
 * @param  string $indent  (optional) ""
 * @param  string $output  (optional) ""
 * @return mixed
 */
if (!function_exists("var_export")) {
   function var_export($var, $return=false, $indent="", $output="") {

      #-- output as in-class variable definitions
      if (is_object($var)) {
         $output = "class " . get_class($var) . " {\n";
         foreach (((array)$var) as $id=>$var) {
2118
2119
2120
2121
2122
2123
2124




2125
2126





2127
2128
2129
2130
2131
2132
2133
2134
2135
2136

2137



























2138
2139
2140


2141
2142
2143
2144
2145
2146
2147


2148
2149
2150
2151
2152
2153
2154
2155
2156
2157

2158





2159
2160
2161
2162
2163
2164
2165

2166





2167
2168
2169
2170
2171
2172
2173
2174



2175





2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186

2187
2188
2189
2190
2191
2192
2193
2194
      else {
         print($output);
      }
   }
}






#-- strcmp() variant that respects locale setting,
#   existed since PHP 4.0.5, but under Win32 first since 4.3.2





if (!function_exists("strcoll")) {
   function strcoll($str1, $str2) {
      return strcmp($str1, $str2);
   }
}






#------------------------------------------------------------------ 4.1 ---



























# nl_langinfo - unimpl?
# getmygid
# version_compare


#
# See also "ext/math41.php" for some more (rarely used mathematical funcs).




#-- aliases (an earlier fallen attempt to unify PHP function names)


if (!function_exists("diskfreespace")) {
   function diskfreespace() {
      return disk_free_sapce();
   }
   function disktotalspace() {
      return disk_total_sapce();
   }
}



#-- variable count of arguments (in array list) printf variant





if (!function_exists("vprintf")) {
   function vprintf($format, $args=NULL) {
      call_user_func_array("fprintf", get_func_args());
   }
}



#-- same as above, but doesn't output directly and returns formatted string





if (!function_exists("vsprintf")) {
   function vsprintf($format, $args=NULL) {
      $args = array_merge(array($format), array_values((array)$args));
      return call_user_func_array("sprintf", $args);
   }
}





#-- can be used to simulate a register_globals=on environment





if (!function_exists("import_request_variables")) {
   function import_request_variables($types="GPC", $pfix="") {
      
      #-- associate abbreviations to global var names
      $alias = array(
         "G" => "_GET",
         "P" => "_POST",
         "C" => "_COOKIE",
         "S" => "_SERVER",   // non-standard
         "E" => "_ENV",      // non-standard
      );

      #-- alias long names (PHP < 4.0.6)
      if (!isset($_REQUEST)) {
         $_GET = & $HTTP_GET_VARS;
         $_POST = & $HTTP_POST_VARS;
         $_COOKIE = & $HTTP_COOKIE_VARS;
      }
      
      #-- copy







>
>
>
>
|
<
>
>
>
>
>










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



|
|
>
>










>
|
>
>
>
>
>







>
|
>
>
>
>
>








>
>
>
|
>
>
>
>
>











>
|







2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484

2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534

2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
      else {
         print($output);
      }
   }
}


/**
 * @stub
 * @since existed since PHP 4.0.5, but under Win32 first since 4.3.2
 * 
 * strcmp() variant that respects locale setting,

 *
 * @param  string $str1  
 * @param  string $str2  
 * @return string
 */
if (!function_exists("strcoll")) {
   function strcoll($str1, $str2) {
      return strcmp($str1, $str2);
   }
}





/**
 *                                   ------------------------------ 4.1 ---
 * @group 4_1
 * @since 4.1
 *
 *
 * See also "ext/math41.php" for some more (rarely used mathematical funcs).
 *
 *
 * @emulated
 *   diskfreespace
 *   disktotalspace
 *   vprintf
 *   vsprintf
 *   import_request_variables
 *   hypot
 *   log1p
 *   expm1
 *   sinh
 *   cosh
 *   tanh
 *   asinh
 *   acosh
 *   atanh
 *   mhash
 *   mhash_count
 *   mhash_get_hash_name
 *   mhash_get_block_size
 * @missing
 *   nl_langinfo - unimpl?
 *   getmygid
 *   version_compare
 *
 */





/**
 * aliases (an earlier fallen attempt to unify PHP function names)
 * 
 */
if (!function_exists("diskfreespace")) {
   function diskfreespace() {
      return disk_free_sapce();
   }
   function disktotalspace() {
      return disk_total_sapce();
   }
}


/**
 * variable count of arguments (in array list) printf variant
 *
 * @param  string $format  
 * @param  mixed  $args
 * @output
 */
if (!function_exists("vprintf")) {
   function vprintf($format, $args=NULL) {
      call_user_func_array("fprintf", get_func_args());
   }
}


/**
 * same as above, but doesn't output directly and returns formatted string
 *
 * @param  string $format
 * @param  mixed  $args
 * @return string
 */
if (!function_exists("vsprintf")) {
   function vsprintf($format, $args=NULL) {
      $args = array_merge(array($format), array_values((array)$args));
      return call_user_func_array("sprintf", $args);
   }
}


/**
 * @extended
 *
 * can be used to simulate a register_globals=on environment
 *
 * @param  string $types   order of GET,POST,COOKIE variables
 * @param  string $pfix    prefix for imported variable names
 * @global $GLOBALS
 */
if (!function_exists("import_request_variables")) {
   function import_request_variables($types="GPC", $pfix="") {
      
      #-- associate abbreviations to global var names
      $alias = array(
         "G" => "_GET",
         "P" => "_POST",
         "C" => "_COOKIE",
         "S" => "_SERVER",   // non-standard
         "E" => "_ENV",      // non-standard
      );

      #-- alias long names (PHP < 4.0.6)    //@FIXME: does that belong here?
      if (!isset($_REQUEST)) {
         $_GET = & $HTTP_GET_VARS;
         $_POST = & $HTTP_POST_VARS;
         $_COOKIE = & $HTTP_COOKIE_VARS;
      }
      
      #-- copy
2251
2252
2253
2254
2255
2256
2257



2258






2259
2260
2261
2262
2263
2264
2265
   }
   function atanh($x) {
      return(  log1p( 2*$x / (1-$x) ) / 2  );
   }
}





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







>
>
>
|
>
>
>
>
>
>







2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
   }
   function atanh($x) {
      return(  log1p( 2*$x / (1-$x) ) / 2  );
   }
}




/**
 * HMAC from RFC2104, but see also PHP_Compat or Crypt_HMAC
 *
 * @param  string $hashtype  which encoding functions to use
 * @param  string $text      plaintext to hash
 * @param  string $key       key data
 * @return string            hash
 */
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); }
2317
2318
2319
2320
2321
2322
2323
2324

2325






2326



2327

2328
2329
2330
2331
2332












2333
2334

2335


2336
2337
2338
   function mhash_get_block_size($i) {
      return(64);
   }
}



#-- other stuff

/*






  removed funcs??



      [18] => leak

*/



#-- pre-4.1 -- end












// no need to implement anything below that, because such old versions
// will be incompatbile anyhow (- none of the newer superglobals known),

// but see also "ext/old"




?>







|
>
|
>
>
>
>
>
>
|
>
>
>
|
>
|



|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
|
>
>



2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
   function mhash_get_block_size($i) {
      return(64);
   }
}





/**
 *
 * @group REMOVED_STUFF
 * @since unknown
 * @until unknown
 *
 *
 * @emulated
 *    ...
 *
 * @missing
 *    leak
 *
 */





/**
 *
 * group PRE_4_1
 * since 4.0
 * since 3.0
 *
 *
 * @emulated
 *    ...
 *
 *
 * No need to implement anything below that, because such old versions
 * will be incompatbile anyhow (- none of the newer superglobals known).
 *
 * but see also "ext/old"
 *
 */


?>