Revision: 5075
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at February 9, 2008 05:54 by localhorst
Initial Code
<?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 ---
* @group CVS
* @since CVS
*
* planned, but as of yet unimplemented functions
* - some of these might appear in 6.0 or ParrotPHP
*
* @emulated
* sys_get_temp_dir
*
*/
/**
* returns path of the system directory for temporary files
*
*/
if (!function_exists("sys_get_temp_dir")) {
function sys_get_temp_dir() {
# check possible alternatives
($temp = ini_get("temp_dir"))
or
($temp = $_SERVER["TEMP"])
or
($temp = $_SERVER["TMP"])
or
($temp = "/tmp");
# fin
return($temp);
}
}
/**
* ------------------------------ 5.2 ---
* @group 5_2
* @since 5.2
*
* Additions of PHP 5.2.0
* - some listed here, might have appeared earlier or in release candidates
*
* @emulated
* json_encode
* json_decode
* error_get_last
* preg_last_error
* lchown
* lchgrp
* E_RECOVERABLE_ERROR
* M_SQRTPI
* M_LNPI
* M_EULER
* M_SQRT3
*
* @missing
* sys_getloadavg
* inet_ntop
* inet_pton
* array_fill_keys
* array_intersect_key
* array_intersect_ukey
* array_diff_key
* array_diff_ukey
* array_product
* pdo_drivers
* ftp_ssl_connect
* XmlReader
* XmlWriter
* PDO*
*
* @unimplementable
* stream_*
*
*/
/**
* @since unknown
*/
if (!defined("E_RECOVERABLE_ERROR")) { define("E_RECOVERABLE_ERROR", 4096); }
/**
* Converts PHP variable or array into "JSON" (a JavaScript value expression
* or "object notation").
*
* @compat
* output seems identical to PECL versions
* @bugs
* doesn't take care with unicode too much
*
*/
if (!function_exists("json_encode")) {
function json_encode($var, /*emu_args*/$obj=FALSE) {
#-- prepare JSON string
$json = "";
#-- add array entries
if (is_array($var) || ($obj=is_object($var))) {
#-- check if array is associative
if (!$obj) foreach ((array)$var as $i=>$v) {
if (!is_int($i)) {
$obj = 1;
break;
}
}
#-- concat invidual entries
foreach ((array)$var as $i=>$v) {
$json .= ($json ? "," : "") // comma separators
. ($obj ? ("\"$i\":") : "") // assoc prefix
. (json_encode($v)); // value
}
#-- enclose into braces or brackets
$json = $obj ? "{".$json."}" : "[".$json."]";
}
#-- strings need some care
elseif (is_string($var)) {
if (!utf8_decode($var)) {
$var = utf8_encode($var);
}
$var = str_replace(array("\"", "\\", "/", "\b", "\f", "\n", "\r", "\t"), array("\\\"", "\\\\", "\\/", "\\b", "\\f", "\\n", "\\r", "\\t"), $var);
$json = '"' . $var . '"';
}
#-- basic types
elseif (is_bool($var)) {
$json = $var ? "true" : "false";
}
elseif ($var === NULL) {
$json = "null";
}
elseif (is_int($var) || is_float($var)) {
$json = "$var";
}
#-- something went wrong
else {
trigger_error("json_encode: don't know what a '" .gettype($var). "' is.", E_USER_ERROR);
}
#-- done
return($json);
}
}
/**
* Parses JSON (JavaScript value expression) into PHP variable
* (array or object).
*
* @compat
* behaves similiar to PECL version
* but is less quiet on errors
* might ignore some misformed representations
* @bugs
* doesn't decode unicode \uXXXX string escapes
*
*/
if (!function_exists("json_decode")) {
function json_decode($json, $assoc=FALSE, /*emu_args*/$n=0,$state=0,$waitfor=0) {
#-- result var
$val = NULL;
static $lang_eq = array("true" => TRUE, "false" => FALSE, "null" => NULL);
static $str_eq = array("n"=>"\012", "r"=>"\015", "\\"=>"\\", '"'=>'"', "f"=>"\f", "b"=>"\b", "t"=>"\t", "/"=>"/");
#-- flat char-wise parsing
for (/*n*/; $n<strlen($json); /*n*/) {
$c = $json[$n];
#-= in-string
if ($state==='"') {
if ($c == '\\') {
$c = $json[++$n];
if (isset($str_eq[$c])) {
$val .= $str_eq[$c];
}
elseif ($c == "u") {
$val .= "\\u";
}
else {
$val .= "\\" . $c;
}
}
elseif ($c == '"') {
$state = 0;
}
else {
$val .= $c;
}
}
#-> end of sub-call (array/object)
elseif ($waitfor && (strpos($waitfor, $c) !== false)) {
return array($val, $n); // return current value and state
}
#-= in-array
elseif ($state===']') {
list($v, $n) = json_decode($json, 0, $n, 0, ",]");
$val[] = $v;
if ($json[$n] == "]") { return array($val, $n); }
}
#-= in-object
elseif ($state==='}') {
list($i, $n) = json_decode($json, 0, $n, 0, ":"); // this allowed non-string indicies
list($v, $n) = json_decode($json, 0, $n+1, 0, ",}");
$val[$i] = $v;
if ($json[$n] == "}") { return array($val, $n); }
}
#-- looking for next item (0)
else {
#-> whitesapce
if (preg_match("/\s/", $c)) {
// skip
}
#-> string begin
elseif ($c == '"') {
$state = '"';
}
#-> object
elseif ($c == "{") {
list($val, $n) = json_decode($json, $assoc, $n+1, '}', "}");
if ($val && $n && !$assoc) {
$obj = new stdClass();
foreach ($val as $i=>$v) {
$obj->{$i} = $v;
}
$val = $obj;
unset($obj);
}
}
#-> array
elseif ($c == "[") {
list($val, $n) = json_decode($json, $assoc, $n+1, ']', "]");
}
#-> comment
elseif (($c == "/") && ($json[$n+1]=="*")) {
// just find end, skip over
($n = strpos($json, "*/", $n+1)) or ($n = strlen($json));
}
#-> numbers
elseif (preg_match("#^(-?\d+(?:\.\d+)?)(?:[eE](-?\d+))?#", substr($json, $n), $uu)) {
$val = $uu[1];
$n += strlen($uu[0]) - 1;
$val = strpos($val, ".") ? (float)$val : (int)$val;
if (isset($uu[2])) {
$val *= pow(10, (int)$uu[2]);
}
}
#-> boolean or null
elseif (preg_match("#^(true|false|null)\b#", substr($json, $n), $uu)) {
$val = $lang_eq[$uu[1]];
$n += strlen($uu[1]) - 1;
}
#-- parsing error
else {
// PHPs native json_decode() breaks here usually and QUIETLY
trigger_error("json_decode: error parsing '$c' at position $n", E_USER_WARNING);
return $waitfor ? array(NULL, 1<<30) : NULL;
}
}//state
#-- next char
if ($n === NULL) { return NULL; }
$n++;
}//for
#-- final result
return ($val);
}
}
/**
* @stub
* @cannot-reimplement
*
*/
if (!function_exists("preg_last_error")) {
if (!defined("PREG_NO_ERROR")) { define("PREG_NO_ERROR", 0); }
if (!defined("PREG_INTERNAL_ERROR")) { define("PREG_INTERNAL_ERROR", 1); }
if (!defined("PREG_BACKTRACK_LIMIT_ERROR")) { define("PREG_BACKTRACK_LIMIT_ERROR", 2); }
if (!defined("PREG_RECURSION_LIMIT_ERROR")) { define("PREG_RECURSION_LIMIT_ERROR", 3); }
if (!defined("PREG_BAD_UTF8_ERROR")) { define("PREG_BAD_UTF8_ERROR", 4); }
function preg_last_error() {
return PREG_NO_ERROR;
}
}
/**
* @stub
*
* Returns associative array with last error message.
*
*/
if (!function_exists("error_get_last")) {
function error_get_last() {
return array(
"type" => 0,
"message" => $GLOBALS[php_errormsg],
"file" => "unknonw",
"line" => 0,
);
}
}
/**
* @flag quirky, exec
*
* Change owner/group of a symlink filename.
*
*/
if (!function_exists("lchown")) {
function lchown($fn, $user) {
if (PHP_OS != "Linux") {
return false;
}
$user = escapeshellcmd($user);
$fn = escapeshellcmd($fn);
exec("chown -h '$user' '$fn'", $uu, $state);
return($state);
}
}
if (!function_exists("lchgrp")) {
function lchgrp($fn, $group) {
return lchown($fn, ":$group");
}
}
/**
* ------------------------------ 5.1 ---
* @group 5_1
* @since 5.1
*
* Additions in PHP 5.1
* - most functions here appeared in -rc1 already
* - and were backported to 4.4 series?
*
* @emulated
* property_exists
* time_sleep_until
* fputcsv
* strptime
* ENT_COMPAT
* ENT_QUOTES
* ENT_NOQUOTES
* htmlspecialchars_decode
* PHP_INT_SIZE
* PHP_INT_MAX
* M_SQRTPI
* M_LNPI
* M_EULER
* M_SQRT3
*
* @missing
* strptime
*
* @unimplementable
* ...
*
*/
/**
* Constants for future 64-bit integer support.
*
*/
if (!defined("PHP_INT_SIZE")) { define("PHP_INT_SIZE", 4); }
if (!defined("PHP_INT_MAX")) { define("PHP_INT_MAX", 2147483647); }
/**
* @flag bugfix
* @see #33895
*
* Missing constants in 5.1, originally appeared in 4.0.
*/
if (!defined("M_SQRTPI")) { define("M_SQRTPI", 1.7724538509055); }
if (!defined("M_LNPI")) { define("M_LNPI", 1.1447298858494); }
if (!defined("M_EULER")) { define("M_EULER", 0.57721566490153); }
if (!defined("M_SQRT3")) { define("M_SQRT3", 1.7320508075689); }
#-- removes entities < > & and " 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("<", ">", ($s ? """ : "&.-;"), ($d ? "'" : "&.-;"), "&"),
array("<", ">", "'", "\"", "&"),
$string
);
}
}
/**
* @flag quirky, needs5
*
* Checks for existence of object property, should return TRUE even for NULL values.
*
* @compat
* uses (array) conversion to test, but that might not always work
* @bugs
* probably can't handle static classes well
*/
# doesn't return true for NULL values, can't handle public/private
if (!function_exists("property_exists")) {
function property_exists($obj, $prop) {
if (!is_object($obj) && class_exists($obj)) {
$obj = new $obj();
}
if (is_object($obj)) {
return isset($obj->{$prop}) || in_array($prop, array_keys((array)$obj));
}
}
}
#-- halt execution, until given timestamp
// I wonder who always comes up with such useless function ideas
if (!function_exists("time_sleep_until")) {
function time_sleep_until($t) {
$delay = $t - time();
if ($delay < 0) {
trigger_error("time_sleep_until: timestamp in the past", E_USER_WARNING);
return false;
}
else {
sleep((int)$delay);
usleep(($delay - floor($delay)) * 1000000);
return true;
}
}
}
/**
* @untested
*
* Writes an array as CSV text line into opened filehandle.
*
*/
if (!function_exists("fputcsv")) {
function fputcsv($fp, $fields, $delim=",", $encl='"') {
$line = "";
foreach ((array)$fields as $str) {
$line .= ($line ? $delim : "")
. $encl
. str_replace(array('\\', $encl), array('\\\\'. '\\'.$encl), $str)
. $encl;
}
fwrite($fp, $line."\n");
}
}
/**
* @stub
* @untested
* @flag basic
*
* @compat
* only implements a few basic regular expression lookups
* no idea how to handle all of it
*/
if (!function_exists("strptime")) {
function strptime($str, $format) {
static $expand = array(
"%D" => "%m/%d/%y",
"%T" => "%H:%M:%S",
);
static $map_r = array(
"%S"=>"tm_sec",
"%M"=>"tm_min",
"%H"=>"tm_hour",
"%d"=>"tm_mday",
"%m"=>"tm_mon",
"%Y"=>"tm_year",
"%y"=>"tm_year",
"%W"=>"tm_wday",
"%D"=>"tm_yday",
"%u"=>"unparsed",
);
static $names = array(
"Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6,
"Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12,
"Sun" => 0, "Mon" => 1, "Tue" => 2, "Wed" => 3, "Thu" => 4, "Fri" => 5, "Sat" => 6,
);
#-- transform $format into extraction regex
$format = str_replace(array_keys($expand), array_values($expand), $format);
$preg = preg_replace("/(%\w)/", "(\w+)", preg_quote($format));
#-- record the positions of all STRFCMD-placeholders
preg_match_all("/(%\w)/", $format, $positions);
$positions = $positions[1];
#-- get individual values
if (preg_match("#$preg#", "$str", $extracted)) {
#-- get values
foreach ($positions as $pos=>$strfc) {
$v = $extracted[$pos + 1];
#-- add
if ($n = $map_r[$strfc]) {
$vals[$n] = ($v > 0) ? (int)$v : $v;
}
else {
$vals["unparsed"] .= $v . " ";
}
}
#-- fixup some entries
$vals["tm_wday"] = $names[ substr($vals["tm_wday"], 0, 3) ];
if ($vals["tm_year"] >= 1900) {
$tm_year -= 1900;
}
elseif ($vals["tm_year"] > 0) {
$vals["tm_year"] += 100;
}
if ($vals["tm_mon"]) {
$vals["tm_mon"] -= 1;
}
else {
$vals["tm_mon"] = $names[ substr($vals["tm_mon"], 0, 3) ] - 1;
}
#-- calculate wday
// ... (mktime)
}
return isset($vals) ? $vals : false;
}
}
/**
* --------------------------- FUTURE ---
* @group FUTURE
* @since unknown
*
* Following functions aren't implemented in current PHP versions allthough
* they are logical and required counterparts to existing features or exist
* in the according external library.
*
* @emulated
* gzdecode
* ob_get_headers
* xmlentities
*
* @missing
* ...
*
* @unimplementable
* ...
*
*/
#-- inflates a string enriched with gzip headers
# (this is the logical counterpart to gzencode(), but don't tell anyone!)
if (!function_exists("gzdecode")) {
function gzdecode($data, $maxlen=NULL) {
#-- decode header
$len = strlen($data);
if ($len < 20) {
return;
}
$head = substr($data, 0, 10);
$head = unpack("n1id/C1cm/C1flg/V1mtime/C1xfl/C1os", $head);
list($ID, $CM, $FLG, $MTIME, $XFL, $OS) = array_values($head);
$FTEXT = 1<<0;
$FHCRC = 1<<1;
$FEXTRA = 1<<2;
$FNAME = 1<<3;
$FCOMMENT = 1<<4;
$head = unpack("V1crc/V1isize", substr($data, $len-8, 8));
list($CRC32, $ISIZE) = array_values($head);
#-- check gzip stream identifier
if ($ID != 0x1f8b) {
trigger_error("gzdecode: not in gzip format", E_USER_WARNING);
return;
}
#-- check for deflate algorithm
if ($CM != 8) {
trigger_error("gzdecode: cannot decode anything but deflated streams", E_USER_WARNING);
return;
}
#-- start of data, skip bonus fields
$s = 10;
if ($FLG & $FEXTRA) {
$s += $XFL;
}
if ($FLG & $FNAME) {
$s = strpos($data, "\000", $s) + 1;
}
if ($FLG & $FCOMMENT) {
$s = strpos($data, "\000", $s) + 1;
}
if ($FLG & $FHCRC) {
$s += 2; // cannot check
}
#-- get data, uncompress
$data = substr($data, $s, $len-$s);
if ($maxlen) {
$data = gzinflate($data, $maxlen);
return($data); // no checks(?!)
}
else {
$data = gzinflate($data);
}
#-- check+fin
$chk = crc32($data);
if ($CRC32 != $chk) {
trigger_error("gzdecode: checksum failed (real$chk != comp$CRC32)", E_USER_WARNING);
}
elseif ($ISIZE != strlen($data)) {
trigger_error("gzdecode: stream size mismatch", E_USER_WARNING);
}
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(
"&#"=>"&#", "&"=>"&", "'"=>"'",
"<"=>"<", ">"=>">", "\""=>""",
));
}
}
/**
* ------------------------------ 5.0 ---
* @group 5_0
* @since 5.0
*
* PHP 5.0 introduces the Zend Engine 2 with new object-orientation features
* which cannot be reimplemented/defined for PHP4. The additional procedures
* and functions however can.
*
* @emulated
* stripos
* strripos
* str_ireplace
* get_headers
* headers_list
* fprintf
* vfprintf
* str_split
* http_build_query
* convert_uuencode
* convert_uudecode
* scandir
* idate
* time_nanosleep
* strpbrk
* get_declared_interfaces
* array_combine
* array_walk_recursive
* substr_compare
* spl_classes
* class_parents
* session_commit
* dns_check_record
* dns_get_mx
* setrawcookie
* file_put_contents
* COUNT_NORMAL
* COUNT_RECURSIVE
* count_recursive
* FILE_USE_INCLUDE_PATH
* FILE_IGNORE_NEW_LINES
* FILE_SKIP_EMPTY_LINES
* FILE_APPEND
* FILE_NO_DEFAULT_CONTEXT
* E_STRICT
*
* @missing
* proc_nice
* dns_get_record
* date_sunrise - undoc.
* date_sunset - undoc.
* PHP_CONFIG_FILE_SCAN_DIR
*
* @unimplementable
* set_exception_handler
* restore_exception_handler
* debug_print_backtrace
* class_implements
* proc_terminate
* proc_get_status
*
*/
#-- constant: end of line
if (!defined("PHP_EOL")) { define("PHP_EOL", ( (DIRECTORY_SEPARATOR == "\\") ? "\015\012" : (strncmp(PHP_OS, "D", 1) ? "\012" : "\015") ) ); } # "D" for Darwin
#-- case-insensitive string search function,
# - finds position of first occourence of a string c-i
# - parameters identical to strpos()
if (!function_exists("stripos")) {
function stripos($haystack, $needle, $offset=NULL) {
#-- 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);
#-- [-]$offset tells to ignore a few string bytes,
# we simply cut a bit from the right
if (isset($offset) && ($offset < 0)) {
$haystack = substr($haystack, 0, strlen($haystack) - 1);
}
#-- let PHP do it
$pos = strrpos($haystack, $needle);
#-- [+]$offset => ignore left haystack bytes
if (isset($offset) && ($offset > 0) && ($pos > $offset)) {
$pos = false;
}
#-- 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) {
$subject = str_ireplace($srch, $replace[$i], $subject);
}
}
#-- sluice replacement strings through the Perl-regex module
# (faster than doing it by hand)
else {
$replace = addcslashes($replace, "$\\");
$search = "{" . preg_quote($search) . "}i";
$subject = preg_replace($search, $replace, $subject);
}
#-- 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)) {
$port = 80;
}
#-- try to open TCP connection
$f = fsockopen($host, $port, $errno, $errstr, $timeout=15);
if (!$f) {
return;
}
#-- send request header
socket_set_blocking($f, true);
fwrite($f, "HEAD $path HTTP/1.0\015\012"
. "Host: $host\015\012"
. "Connection: close\015\012"
. "Accept: */*, xml/*\015\012"
. "User-Agent: ".trim(ini_get("user_agent"))."\015\012"
. "\015\012");
#-- read incoming lines
$ls = array();
while ( !feof($f) && ($line = trim(fgets($f, 1<<16))) ) {
#-- read header names to make result an hash (names in array index)
if ($parse) {
if ($l = strpos($line, ":")) {
$name = substr($line, 0, $l);
$value = trim(substr($line, $l + 1));
#-- merge headers
if (isset($ls[$name])) {
$ls[$name] .= ", $value";
}
else {
$ls[$name] = $value;
}
}
#-- HTTP response status header as result[0]
else {
$ls[] = $line;
}
}
#-- unparsed header list (numeric indices)
else {
$ls[] = $line;
}
}
#-- 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;
}
#-- add substrings to result array until subject strings end reached
else {
$len = strlen($str);
for ($n=0; $n<$len; $n+=$chunk) {
$r[] = substr($str, $n, $chunk);
}
}
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 = "&");
#-- traverse hash/array/list entries
foreach ($data as $index=>$value) {
#-- add sub_prefix for subarrays (happens for recursed innovocation)
if ($subarray_pfix) {
if ($level) {
$index = "[" . $index . "]";
}
$index = $subarray_pfix . $index;
}
#-- add user-specified prefix for integer-indices
elseif (is_int($index) && strlen($int_prefix)) {
$index = $int_prefix . $index;
}
#-- recurse for sub-arrays
if (is_array($value)) {
$s .= http_build_query($value, "", $index, $level + 1);
}
else { // or just literal URL parameter
$s .= $SEP . $index . "=" . urlencode($value);
}
}
#-- remove redundant "&" from first round (-not checked above to simplifiy loop)
if (!$subarray_pfix) {
$s = substr($s, strlen($SEP));
}
#-- 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);
# $data .= "\252\252\252"; // PHP and uuencode(1) use some special garbage??, looks like "\000"* and "`\n`" simply appended
#-- canvass source string
for ($n=0; $n<$len; ) {
#-- make 24-bit integer from first three bytes
$x = (ord($data[$n++]) << 16)
+ (ord($data[$n++]) << 8)
+ (ord($data[$n++]) << 0);
#-- disperse that into 4 ascii characters
$line .= chr( 32 + (($x >> 18) & 0x3f) )
. chr( 32 + (($x >> 12) & 0x3f) )
. chr( 32 + (($x >> 6) & 0x3f) )
. chr( 32 + (($x >> 0) & 0x3f) );
#-- cut lines, inject count prefix before each
if (($n % 45) == 0) {
$out .= chr(32 + 45) . "$line\n";
$line = "";
}
}
#-- throw last line, +length prefix
if ($trail = ($len % 45)) {
$out .= chr(32 + $trail) . "$line\n";
}
// 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, "`", " ");
#-- go through lines
foreach(explode("\n", ltrim($data)) as $line) {
if (!strlen($line)) {
break; // end reached
}
#-- current line length prefix
unset($num);
$num = ord($line{0}) - 32;
if (($num <= 0) || ($num > 62)) { // 62 is the maximum line length
break; // according to uuencode(5), so we stop here too
}
$line = substr($line, 1);
#-- prepare to decode 4-char chunks
$add = "";
for ($n=0; strlen($add)<$num; ) {
#-- merge 24 bit integer from the 4 ascii characters (6 bit each)
$x = ((ord($line[$n++]) - 32) << 18)
+ ((ord($line[$n++]) - 32) << 12) // were saner with "& 0x3f"
+ ((ord($line[$n++]) - 32) << 6)
+ ((ord($line[$n++]) - 32) << 0);
#-- reconstruct the 3 original data chars
$add .= chr( ($x >> 16) & 0xff )
. chr( ($x >> 8) & 0xff )
. chr( ($x >> 0) & 0xff );
}
#-- cut any trailing garbage (last two decoded chars may be wrong)
$out .= substr($add, 0, $num);
$line = "";
}
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) {
$dirname = substr($dirname, strpos($dirname, "/"));
}
}
#-- directory reading handle
if ($dh = opendir($dirname)) {
$ls = array();
while ($fn = readdir($dh)) {
$ls[] = $fn; // add to array
}
closedir($dh);
#-- sort filenames
if ($desc) {
rsort($ls);
}
else {
sort($ls);
}
return $ls;
}
#-- 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;
}
#-- get current time, if not given
if (!isset($timestamp)) {
$timestamp = time();
}
#-- get and turn into integer
$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);
#-- check with every symbol from $char_list
for ($n = 0; $n < $len; $n++) {
$l = strpos($haystack, $char_list{$n});
#-- get left-most occourence
if (($l !== false) && ($l < $min)) {
$min = $l;
}
}
#-- result
if ($min) {
return(substr($haystack, $min));
}
else {
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();
#-- one from each
foreach ($values as $i=>$val) {
if ($key = $keys[$i]) {
$r[$key] = $val;
}
else {
$r[] = $val; // useless, PHP would have long aborted here
}
}
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)) {
array_walk_recursive($input[$key], $callback, $userdata);
}
#-- $callback handles scalars
else {
call_user_func_array($callback, array(&$input[$key], $key, $userdata) );
}
}
// 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); }
}
#-- length exception
if ($len + $offset >= strlen($haystack)) {
trigger_error("substr_compare: given length exceeds main_str", E_USER_WARNING);
return(false);
}
#-- cut
if ($offset) {
$haystack = substr($haystack, $offset, $len);
}
#-- case-insensitivity
if ($ci) {
$haystack = strtolower($haystack);
$needle = strtolower($needle);
}
#-- 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")) {
function dns_get_mx($host, $mx) {
$args = func_get_args();
// simple alias - except the optional, but referenced third parameter
if ($args[2]) {
$w = & $args[2];
}
else {
$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 ',;
' 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);
foreach ($array as $sub) {
if (is_array($sub)) {
$c += count_recursive($sub);
}
}
return($c);
}
}
}
/**
* ------------------------------ 4.4 ---
* @group 4_4
* @since 4.4
*
* PHP 4.4 is a bugfix and backporting version created after PHP 5. It went
* mostly unchanged, but changes a few language semantics (e.g. references).
*
* @emulated
* PHP_INT_SIZE
* PHP_INT_MAX
* SORT_LOCALE_STRING
*
*/
if (!defined("PHP_INT_SIZE")) { define("PHP_INT_SIZE", 4); }
if (!defined("PHP_INT_MAX")) { define("PHP_INT_MAX", 2147483647); }
if (!defined("SORT_LOCALE_STRING")) { define("SORT_LOCALE_STRING", 5); }
/**
* ------------------------------ 4.3 ---
* @group 4_3
* @since 4.3
*
* Additions in 4.3 version of PHP interpreter.
*
* @emulated
* file_get_contents
* array_key_exists
* array_intersect_assoc
* array_diff_assoc
* html_entity_decode
* str_word_count
* str_shuffle
* get_include_path
* set_include_path
* restore_include_path
* fnmatch
* FNM_PATHNAME
* FNM_NOESCAPE
* FNM_PERIOD
* FNM_LEADING_DIR
* FNM_CASEFOLD
* FNM_EXTMATCH
* glob
* GLOB_MARK
* GLOB_NOSORT
* GLOB_NOCHECK
* GLOB_NOESCAPE
* GLOB_BRACE
* GLOB_ONLYDIR
* GLOB_NOCASE
* GLOB_DOTS
* __FUNCTION__
* PATH_SEPARATOR
* PHP_SHLIB_SUFFIX
* PHP_SAPI
* PHP_PREFIX
*
* @missing
* sha1_file
* sha1 - too much code, and has been reimplemented elsewhere
*
* @unimplementable
* money_format
*
*/
#-- simplified file read-at-once function
if (!function_exists("file_get_contents")) {
function file_get_contents($filename, $use_include_path=1) {
#-- open file, let fopen() report error
$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) {
$rxci = "i";
}
#-- handline of pathname separators (/)
$wild = ".";
if ($flags & FNM_PATHNAME) {
$wild = "[^/".DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR."]";
}
#-- check for cached regular expressions
static $cmp = array();
if (isset($cmp["$pattern+$flags"])) {
$rx = $cmp["$pattern+$flags"];
}
#-- convert filename globs into regex
else {
$rx = preg_quote($pattern);
$rx = strtr($rx, array(
"\\*"=>"$wild*?", "\\?"=>"$wild", "\\["=>"[", "\\]"=>"]",
));
$rx = "{^" . $rx . "$}" . $rxci;
#-- cache
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); }
if (!defined("GLOB_BRACE")) { define("GLOB_BRACE", 1<<4); }
if (!defined("GLOB_ONLYDIR")) { define("GLOB_ONLYDIR", 1<<5); }
if (!defined("GLOB_NOCASE")) { define("GLOB_NOCASE", 1<<6); }
if (!defined("GLOB_DOTS")) { define("GLOB_DOTS", 1<<7); }
// unlikely to work under Win(?), without replacing the explode() with
// a preg_split() incorporating the native DIRECTORY_SEPARATOR as well
#-- implementation
function glob($pattern, $flags=0x0000) {
$ls = array();
$rxci = ($flags & GLOB_NOCASE) ? "i" : "";
#echo "\n=> glob($pattern)...\n";
#-- transform glob pattern into regular expression
# (similar to fnmatch() but still different enough to require a second func)
if ($pattern) {
#-- look at each directory/fn spec part separately
$parts2 = explode("/", $pattern);
$pat = preg_quote($pattern);
$pat = strtr($pat, array("\\*"=>".*?", "\\?"=>".?"));
if ($flags ^ GLOB_NOESCAPE) {
// uh, oh, ouuch - the above is unclean enough...
}
if ($flags ^ GLOB_BRACE) {
$pat = preg_replace("/\{(.+?)\}/e", 'strtr("[$1]", ",", "")', $pat);
}
$parts = explode("/", $pat);
#echo "parts == ".implode(" // ", $parts) . "\n";
$lasti = count($parts) - 1;
$dn = "";
foreach ($parts as $i=>$p) {
#-- basedir included (yet no pattern matching necessary)
if (!strpos($p, "*?") && (strpos($p, ".?")===false)) {
$dn .= $parts2[$i] . ($i!=$lasti ? "/" : "");
#echo "skip:$i, cause no pattern matching char found -> only a basedir spec\n";
continue;
}
#-- start reading dir + match filenames against current pattern
if ($dh = opendir($dn ?$dn:'.')) {
$with_dot = ($p[1]==".") || ($flags & GLOB_DOTS);
#echo "part:$i:$p\n";
#echo "reading dir \"$dn\"\n";
while ($fn = readdir($dh)) {
if (preg_match("\007^$p$\007$rxci", $fn)) {
#-- skip over 'hidden' files
if (($fn[0] == ".") && !$with_dot) {
continue;
}
#-- add filename only if last glob/pattern part
if ($i==$lasti) {
if (is_dir("$dn$fn")) {
if ($flags & GLOB_ONLYDIR) {
continue;
}
if ($flags & GLOB_MARK) {
$fn .= "/";
}
}
#echo "adding '$fn' for dn=$dn to list\n";
$ls[] = "$dn$fn";
}
#-- initiate a subsearch, merge result list in
elseif (is_dir("$dn$fn")) {
// add reamaining search patterns to current basedir
$remaind = implode("/", array_slice($parts2, $i+1));
$ls = array_merge($ls, glob("$dn$fn/$remaind", $flags));
}
}
}
closedir($dh);
#-- prevent scanning a 2nd part/dir in same glob() instance:
break;
}
#-- given dirname doesn't exist
else {
return($ls);
}
}// foreach $parts
}
#-- return result list
if (!$ls && ($flags & GLOB_NOCHECK)) {
$ls[] = $pattern;
}
if ($flags ^ GLOB_NOSORT) {
sort($ls);
}
#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();
#-- walk through each array pair
# (take first as checklist)
foreach ($in[0] as $i => $v) {
for ($c = 1; $c < $cmax; $c++) {
#-- remove entry, as soon as it isn't present
# in one of the other arrays
if (!isset($in[$c][$i]) || (@$in[$c][$i] !== $v)) {
continue 2;
}
}
#-- it was found in all other arrays
$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();
#-- compare each array with primary/first
foreach ($in[0] as $i=>$v) {
for ($c=1; $c<count($in); $c++) {
#-- skip as soon as it matches with entry in another array
if (isset($in[$c][$i]) && ($in[$c][$i] == $v)) {
continue 2;
}
}
#-- else
$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
if ($result == 1) {
return($uu[1]);
}
#-- array() of $pos=>$word entries
elseif ($result >= 2) {
$r = array();
$l = 0;
foreach ($uu[1] as $word) {
$l = strpos($string, $word, $l);
$r[$l] = $word;
$l += strlen($word); // speed up next search
}
return($r);
}
#-- only count
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);
}
function restore_include_path() {
ini_restore("include_path");
}
}
#-- constants for 4.3
if (!defined("PATH_SEPARATOR")) { define("PATH_SEPARATOR", ((DIRECTORY_SEPARATOR=='\\') ? ';' :':')); }
if (!defined("PHP_SHLIB_SUFFIX")) { define("PHP_SHLIB_SUFFIX", ((DIRECTORY_SEPARATOR=='\\') ? 'dll' :'so')); }
if (!defined("PHP_SAPI")) { define("PHP_SAPI", php_sapi_name()); }
if (!defined("__FUNCTION__")) { define("__FUNCTION__", NULL); } // empty string would signalize main()
#-- not identical to what PHP reports (it seems to `which` for itself)
if (!defined("PHP_PREFIX") && isset($_ENV["_"])) { define("PHP_PREFIX", substr($_ENV["_"], 0, strpos($_ENV["_"], "bin/"))); }
#------------------------------------------------------------------ 4.2 ---
# 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
function array_change_key_case($array, $case=CASE_LOWER) {
#-- loop through
foreach ($array as $i=>$v) {
#-- do anything for strings only
if (is_string($i)) {
unset($array[$i]);
$i = ($case==CASE_LOWER) ? strtolower($i) : strtoupper($i);
$array[$i] = $v;
}
// 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
#-- enum input array blocks
foreach ($input as $i=>$v) {
#-- new chunk
if (($n < 0) || (count($r[$n]) == $size)) {
$n++;
$r[$n] = array();
}
#-- add input value into current [$n] chunk
if ($preserve_keys) {
$r[$n][$i] = $v;
}
else {
$r[$n][] = $v;
}
}
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
function is_infinite($f) {
$s = (string)$f;
return( ($s=="INF") || ($s=="-INF") );
}
function is_nan($f) {
$s = (string)$f;
return( $s=="NAN" );
}
function is_finite($f) {
$s = (string)$f;
return( !strpos($s, "N") );
}
}
#-- 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) {
$output .= " var \$$id = " . var_export($var, true) . ";\n";
}
$output .= "}";
}
#-- array constructor
elseif (is_array($var)) {
foreach ($var as $id=>$next) {
if ($output) $output .= ",\n";
else $output = "array(\n";
$output .= $indent . ' '
. (is_numeric($id) ? $id : '"'.addslashes($id).'"')
. ' => ' . var_export($next, true, "$indent ");
}
if (empty($output)) $output = "array(";
$output .= "\n{$indent})";
#if ($indent == "") $output .= ";";
}
#-- literals
elseif (is_numeric($var)) {
$output = "$var";
}
elseif (is_bool($var)) {
$output = $var ? "true" : "false";
}
else {
$output = "'" . preg_replace("/([\\\\\'])/", '\\\\$1', $var) . "'";
}
#-- done
if ($return) {
return($output);
}
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
for ($i=0; $i<strlen($types); $i++) {
if ($FROM = $alias[strtoupper($c)]) {
foreach ($$FROM as $key=>$val) {
if (!isset($GLOBALS[$pfix.$key])) {
$GLOBALS[$pfix . $key] = $val;
}
}
}
}
// done
}
}
// a few mathematical functions follow
// (wether we should really emulate them is a different question)
#-- me has no idea what this function means
if (!function_exists("hypot")) {
function hypot($num1, $num2) {
return sqrt($num1*$num1 + $num2*$num2); // as per PHP manual ;)
}
}
#-- more accurate logarithm func, but we cannot simulate it
# (too much work, too slow in PHP)
if (!function_exists("log1p")) {
function log1p($x) {
return( log(1+$x) );
}
#-- same story for:
function expm1($x) {
return( exp($x)-1 );
}
}
#-- as per PHP manual
if (!function_exists("sinh")) {
function sinh($f) {
return( (exp($f) - exp(-$f)) / 2 );
}
function cosh($f) {
return( (exp($f) + exp(-$f)) / 2 );
}
function tanh($f) {
return( sinh($f) / cosh($f) ); // ok, that one makes sense again :)
}
}
#-- these look a bit more complicated
if (!function_exists("asinh")) {
function asinh($x) {
return( log($x + sqrt($x*$x+1)) );
}
function acosh($x) {
return( log($x + sqrt($x*$x-1)) );
}
function atanh($x) {
return( log1p( 2*$x / (1-$x) ) / 2 );
}
}
#-- HMAC from RFC2104, but see also PHP_Compat and Crypt_HMAC
if (!function_exists("mhash")) {
#-- constants
if (!defined("MHASH_CRC32")) { define("MHASH_CRC32", 0); }
if (!defined("MHASH_MD5")) { define("MHASH_MD5", 1); } // RFC1321
if (!defined("MHASH_SHA1")) { define("MHASH_SHA1", 2); } // RFC3174
if (!defined("MHASH_TIGER")) { define("MHASH_TIGER", 7); }
if (!defined("MHASH_MD4")) { define("MHASH_MD4", 16); } // RFC1320
if (!defined("MHASH_SHA256")) { define("MHASH_SHA256", 17); }
if (!defined("MHASH_ADLER32")) { define("MHASH_ADLER32", 18); }
#-- implementation
function mhash($hashtype, $text, $key) {
#-- hash function
if (!($func = mhash_get_hash_name($hashtype)) || !function_exists($func)) {
return trigger_error("mhash: cannot use hash algorithm #$hashtype/$func", E_USER_ERROR);
}
if (!$key) {
trigger_error("mhash: called without key", E_USER_WARNING);
}
#-- params
$bsize = mhash_get_block_size($hashtype); // fixed size, 64
#-- pad key
if (strlen($key) > $bsize) { // hash key, when it's too long
$key = $func($key);
$key = pack("H*", $key); // binarify
}
$key = str_pad($key, $bsize, "\0"); // fill up with NULs (1)
#-- prepare inner and outer padding stream
$ipad = str_pad("", $bsize, "6"); // %36
$opad = str_pad("", $bsize, "\\"); // %5C
#-- call hash func // php can XOR strings for us
$dgst = pack("H*", $func( ($key ^ $ipad) . $text )); // (2,3,4)
$dgst = pack("H*", $func( ($key ^ $opad) . $dgst )); // (5,6,7)
return($dgst);
}
#-- return which hash functions are implemented
function mhash_count() {
return(MHASH_SHA1);
}
#-- map numeric identifier to hash function name
function mhash_get_hash_name($i) {
static $hash_funcs = array(
MHASH_CRC32 => "crc32", // would need dechex()ing in main func?
MHASH_MD5 => "md5",
MHASH_SHA1 => "sha1",
);
return(strtoupper($hash_funcs[$i]));
}
#-- static value
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"
?>
Initial URL
http://www.google.com/codesearch?hl=de&q=+json_encode+show:LhmoV3E-2fk:X3Z72SIYcBg:BIe4as29lCU&sa=N&cd=20&ct=rc&cs_p=http://fresh.t-systems-sfr.com/unix/src/privat2/upgradephp-14.tgz&cs_f=upgradephp-14/upgrade.php
Initial Description
Initial Title
emulate PHP 5 for backwards compatibility
Initial Tags
Initial Language
PHP