PHP Compatibility
Views:
This is my one-size-fits-all, drop-in, php compatibility layer. Missing nice functions from newer versions of PHP? Having headaches accounting for where your code will be deployed? Include this and forget all about it.
Some pieces of code has been taken or adapted from other places, like the generous people that leave comments on the php manual.
Please note that the filter extension compatibility functions are incomplete and should not be used. Use it as a starting point for your own code or delete it. Just don't try and use it as it is. Also, as the code was basically lifted from the php source code, then ported, it probably means this file must use the php license. I am not a lawyer.
Code in this file depends on PHP Error Handling and PHP Patterns
<?php
/**
* @package ninja
* @copyright Kieran Whitbread 2005-2010
* @license http://opensource.org/licenses/php.php PHP License
*/
/* Supposedly, these constants aren't defined in all versions of PHP
* so just to be on the safe side...
*/
if (!defined('FNM_PATHNAME'))
{
define('FNM_PATHNAME', 1);
}
if (!defined('FNM_FILE_NAME'))
{
define('FNM_FILE_NAME', FNM_PATHNAME);
}
if (!defined('FNM_NOESCAPE'))
{
define('FNM_NOESCAPE', 2);
}
if (!defined('FNM_PERIOD'))
{
define('FNM_PERIOD', 4);
}
if (!defined('FNM_LEADING_DIR'))
{
define('FNM_LEADING_DIR', 8);
}
if (!defined('FNM_CASEFOLD'))
{
define('FNM_CASEFOLD', 16);
}
/////////////////
// For PHP 5.1 //
/////////////////
if (!function_exists('property_exists'))
{
function property_exists($class, $property)
{
$vars = array();
if (class_exists($class))
{
$vars = get_class_vars($class);
}
elseif (is_object($class))
{
$vars = get_object_vars($class);
}
else
{
NinjaError::trigger("First parameter must either be an object or the name of an existing class", E_USER_WARNING, 1);
return null;
}
if (!is_string($property))
{
NinjaError::trigger(ucwords(gettype($property))." to string conversion", E_USER_NOTICE, 1);
$property = (string)$property;
}
return array_key_exists($property, $vars);
}
}
///////////////////
// For PHP 5.1.1 //
///////////////////
if (version_compare(PHP_VERSION, '5.1.1', '<'))
{
define('DATE_ATOM', "Y-m-d\TH:i:sP");
define('DATE_COOKIE', "l, d-M-y H:i:s T");
define('DATE_ISO8601', "Y-m-d\TH:i:sO");
define('DATE_RFC822', "Y-m-d\TH:i:sO");
define('DATE_RFC850', "l, d-M-y H:i:s T");
define('DATE_RFC1036', "D, d M y H:i:s O");
define('DATE_RFC1123', "D, d M Y H:i:s O");
define('DATE_RFC2822', "D, d M Y H:i:s O");
define('DATE_RFC3339', "Y-m-d\TH:i:sP");
define('DATE_RSS', "D, d M Y H:i:s O");
define('DATE_W3C', "Y-m-d\TH:i:sP");
}
///////////////////
// For PHP 5.1.2 //
///////////////////
if (version_compare(PHP_VERSION, '5.1.2', '<'))
{
define('SUNFUNCS_RET_TIMESTAMP', 0);
define('SUNFUNCS_RET_STRING', 1);
define('SUNFUNCS_RET_DOUBLE', 2);
}
/////////////////
// For PHP 5.2 //
/////////////////
if (!defined('E_RECOVERABLE_ERROR'))
{
define('E_RECOVERABLE_ERROR', 4096);
}
if (!function_exists('array_fill_keys'))
{
function array_fill_keys($target, $value = '')
{
if(is_array($target))
{
foreach($target as $key => $val)
{
$filledArray[$val] = is_array($value) ? $value[$key] : $value;
}
}
return $filledArray;
}
}
if (!function_exists('image_type_to_extension'))
{
function image_type_to_extension($type, $dot = true)
{
$e = array (
1 => 'gif',
'jpeg',
'png',
'swf',
'psd',
'bmp',
'tiff',
'tiff',
'jpc',
'jp2',
'jpf',
'jb2',
'swc',
'aiff',
'wbmp',
'xbm'
);
// We are expecting an integer.
$type = (int)$type;
if (!$type)
{
NinjaError::trigger("image_type_to_extension() expects parameter 1 to be long", E_USER_WARNING, 1);
return null;
}
if (!isset($e[$type]))
{
return false;
}
return ($dot ? '.' : '') . $e[$type];
}
}
if (!function_exists('image_type_to_mime_type'))
{
function image_type_to_mime_type($type)
{
$m = array (1 => 'image/gif',
'image/jpeg',
'image/png',
'application/x-shockwave-flash',
'image/psd',
'image/bmp',
'image/tiff',
'image/tiff',
'application/octet-stream',
'image/jp2',
'application/octet-stream',
'application/octet-stream',
'application/x-shockwave-flash',
'image/iff',
'image/vnd.wap.wbmp',
'image/xbm'
);
// We are expecting an integer.
$type = (int)$type;
if (!$type)
{
return 'application/octet-stream';
}
if (!isset($m[$type]))
{
return 'application/octet-stream';
}
return $m[$type];
}
}
///////////////////
// For PHP 5.2.1 //
///////////////////
if (!function_exists('sys_get_temp_dir'))
{
function sys_get_temp_dir()
{
if (!empty($_ENV['TMP'])) return realpath($_ENV['TMP']);
if (!empty($_ENV['TMPDIR'])) return realpath($_ENV['TMPDIR']);
if (!empty($_ENV['TEMP'])) return realpath($_ENV['TEMP']);
$tempfile = tempnam(uniqid(rand(), true), '');
if (file_exists($tempfile))
{
unlink($tempfile);
return realpath(dirname($tempfile));
}
}
}
/////////////////
// For PHP 5.3 //
/////////////////
if (!defined('E_DEPRECATED'))
{
define('E_DEPRECATED', 8192);
}
if (!defined('E_USER_DEPRECATED'))
{
define('E_USER_DEPRECATED', 16384);
}
if (!extension_loaded('filter'))
{
/* The Filter Extension
*
* This is an implementation of the Filter Extension API in userspace as well as the
* php functions exposed by the extension. The aim is not to create 100% compatible
* implementation but to make all of the key and common functionality the same.
*
* Safety is the primary concern, followed by making the behaviour exactly the same.
*
* We are _NOT_ going to support magic quotes and aren't planning to support call backs.
* Also we will not be supporting any php ini or automatic features (that isn't possible
* to do).
* Only the UTF8 charset is supported
* Only supporting 32 bit integers
*/
define('INPUT_POST', 0); // POST variables.
define('INPUT_GET', 1); // GET variables.
define('INPUT_COOKIE', 2); // COOKIE variables.
define('INPUT_ENV', 4); // ENV variables.
define('INPUT_SERVER', 5); // SERVER variables.
define('INPUT_SESSION', 6); // SESSION variables. (not implemented yet)
define('INPUT_REQUEST', 99); // REQUEST variables. (not implemented yet)
define('FILTER_FLAG_NONE', 0); // No flags.
define('FILTER_REQUIRE_SCALAR', 33554432); // Flag used to require scalar as input
define('FILTER_REQUIRE_ARRAY', 16777216); // Require an array as input.
define('FILTER_FORCE_ARRAY', 67108864); // Always returns an array.
define('FILTER_NULL_ON_FAILURE', 134217728); // Use NULL instead of FALSE on failure.
define('FILTER_VALIDATE_INT', 257); // ID of "int" filter.
define('FILTER_VALIDATE_BOOLEAN', 258); // ID of "boolean" filter.
define('FILTER_VALIDATE_FLOAT', 259); // ID of "float" filter.
define('FILTER_VALIDATE_REGEXP', 272); // ID of "validate_regexp" filter.
define('FILTER_VALIDATE_URL', 273); // /ID of "validate_url" filter.
define('FILTER_VALIDATE_EMAIL', 274); // ID of "validate_email" filter.
define('FILTER_VALIDATE_IP', 275); // ID of "validate_ip" filter.
define('FILTER_DEFAULT', 516); // ID of default ("string") filter.
define('FILTER_UNSAFE_RAW', 516); // ID of "unsafe_raw" filter.
define('FILTER_SANITIZE_STRING', 513); // ID of "string" filter.
define('FILTER_SANITIZE_STRIPPED', 513); // ID of "stripped" filter.
define('FILTER_SANITIZE_ENCODED', 514); // ID of "encoded" filter.
define('FILTER_SANITIZE_SPECIAL_CHARS', 515); // ID of "special_chars" filter.
define('FILTER_SANITIZE_EMAIL', 517); // ID of "email" filter.
define('FILTER_SANITIZE_URL', 518); // ID of "url" filter.
define('FILTER_SANITIZE_NUMBER_INT', 519); // ID of "number_int" filter.
define('FILTER_SANITIZE_NUMBER_FLOAT', 520); // ID of "number_float" filter.
define('FILTER_SANITIZE_MAGIC_QUOTES', 521); // ID of "magic_quotes" filter.
define('FILTER_CALLBACK', 1024); // ID of "callback" filter.
define('FILTER_FLAG_ALLOW_OCTAL', 1); // Allow octal notation (0[0-7]+) in "int" filter.
define('FILTER_FLAG_ALLOW_HEX', 2); // Allow hex notation (0x[0-9a-fA-F]+) in "int" filter.
define('FILTER_FLAG_STRIP_LOW', 4); // Strip characters with ASCII value less than 32.
define('FILTER_FLAG_STRIP_HIGH', 8); // Strip characters with ASCII value greater than 127.
define('FILTER_FLAG_ENCODE_LOW', 16); // Encode characters with ASCII value less than 32.
define('FILTER_FLAG_ENCODE_HIGH', 32); // Encode characters with ASCII value greater than 127.
define('FILTER_FLAG_ENCODE_AMP', 64); // Encode &.
define('FILTER_FLAG_NO_ENCODE_QUOTES', 128); // Don't encode ' and ".
define('FILTER_FLAG_EMPTY_STRING_NULL', 256); // (No use for now.)
define('FILTER_FLAG_ALLOW_FRACTION', 4096); // Allow fractional part in "number_float" filter.
define('FILTER_FLAG_ALLOW_THOUSAND', 8192); // Allow thousand separator (,) in "number_float" filter.
define('FILTER_FLAG_ALLOW_SCIENTIFIC', 16384); // Allow scientific notation (e, E) in "number_float" filter.
define('FILTER_FLAG_SCHEME_REQUIRED', 65536); // Require scheme in "validate_url" filter.
define('FILTER_FLAG_HOST_REQUIRED', 131072); // Require host in "validate_url" filter.
define('FILTER_FLAG_PATH_REQUIRED', 262144); // Require path in "validate_url" filter.
define('FILTER_FLAG_QUERY_REQUIRED', 524288); // Require query in "validate_url" filter.
define('FILTER_FLAG_IPV4', 1048576); // Allow only IPv4 address in "validate_ip" filter.
define('FILTER_FLAG_IPV6', 2097152); // Allow only IPv6 address in "validate_ip" filter.
define('FILTER_FLAG_NO_RES_RANGE', 4194304); // Deny reserved addresses in "validate_ip" filter.
define('FILTER_FLAG_NO_PRIV_RANGE', 8388608); // Deny private addresses in "validate_ip" filter.
function php_filter_failure($failure = false)
{
return is_null($failure) || (preg_match(NINJA_PREG_UINT, $failure) && ($failure & FILTER_NULL_ON_FAILURE) === FILTER_NULL_ON_FAILURE) ? null : false;
}
function php_filter_parse_int($value, $failure = false)
{
// Looks numeric signed int first digit 1 to 9 32 bit signed number (no good for 64 bit OS)
if (is_numeric($value) && preg_match(HUM_PREG_INT, $value) && $value >= -2147483647 && $value <= 2147483647)
{
return (int) $value;
}
return php_filter_failure($failure);
}
function php_filter_parse_octal($value, $failure = false)
{
if (decoct(octdec($value)) == $value)
{
return $value;
}
return php_filter_failure($failure);
}
function php_filter_parse_hex($value, $failure = false)
{
// Filter extension only supports checking hex as strings starting '0x'
if (is_string($value) && preg_match('/^0[xX][0-9a-f]+/', $value))
{
// We're going to test with the ctype extension, which _doesn't_ support hex starting 0x
// God! Roll on SPL Types! ;-)
$tmpValue = preg_replace('/0[xX]/', '', $value);
if (ctype_xdigit($tmpValue))
{
return $value;
}
}
return php_filter_failure($failure);
}
function php_filter_int($value, $flags = null, $options = array(), $failure = false)
{
if (is_string($value) || is_numeric($value))
{
$value = trim((string)$value);
}
if (!is_string($value) || !strlen($value))
{
return php_filter_failure($failure);
}
$allowOctal = (!is_null($flags) && is_numeric($flags) && ($flags & FILTER_FLAG_ALLOW_OCTAL));
$allowHex = (!is_null($flags) && is_numeric($flags) && ($flags & FILTER_FLAG_ALLOW_HEX));
$minRange = null;
$maxRange = null;
$allowHex = false;
$allowOctal = false;
$hexVal = null;
$octVal = null;
$intVal = null;
$flags = 0;
if ($options)
{
if (isset($options['min_range']) && preg_match(HUM_PREG_INT, $optins['min_range']))
{
$minRange = $options['min_range'];
}
if (isset($options['max_range']) && preg_match(HUM_PREG_INT, $optins['max_range']))
{
$maxRange = $options['max_range'];
}
}
// FIXME: Parse flags!!!
if (strlen($value))
{
if ($allowHex)
{
$hexVal = php_filter_parse_hex($value, $failure);
if (strlen($hexVal))
{
$hexVal = hexdec($hexVal);
}
}
elseif ($allowOctal)
{
$octVal = php_filter_parse_octal($value, $failure);
if (strlen($octVal))
{
$octVal = octdec($octVal);
}
}
$intVal = php_filter_parse_int($value, $failure);
}
if (strlen($intVal) && (!is_null($minRange) && ($intVal < $minRange)) || (!is_null($maxRange) && ($intVal > $maxRange)))
{
return php_filter_failure($failure);
}
elseif (strlen($hexVal) && (!is_null($minRange) && ($hexVal < $minRange)) || (!is_null($maxRange) && ($hexVal > $maxRange)))
{
return php_filter_failure($failure);
}
elseif (strlen($octVal) && (!is_null($minRange) && ($octVal < $minRange)) || (!is_null($maxRange) && ($octVal > $maxRange)))
{
return php_filter_failure($failure);
}
elseif (strlen($intVal) || strlen($hexVal) || strlen($octVal))
{
return (int)$value;
}
return php_filter_failure($failure);
}
function php_filter_boolean($value, $failure = false)
{
if (is_numeric($value) || is_string($value))
{
$value = trim((string) $value);
}
if (!is_string($value) || !strlen($value))
{
return php_filter_failure($failure);
}
$value = strtolower($value);
switch ($value)
{
case "true":
case "yes":
case "on":
case 1:
case "1": return true;
break;
case "false":
case "no":
case "off":
case 0:
case "0": return false;
break;
default: return php_filter_failure($failure);
}
}
function php_filter_float($value, $failure = false)
{
// FIXME: Parse flags!!!
$dec_sep = '.';
$tsd_sep = "',.";
$allowThousandsSep = null;
$flags = 0;
if (is_numeric($value) || is_string($value))
{
$value = trim((string)$value);
}
if (!is_string($value) || !strlen($value))
{
return php_filter_failure($failure);
}
// Get a simple check out of the way first
if ($value == (string)(float)$value)
{
return (float)$value;
}
if ($flags & FILTER_FLAG_ALLOW_THOUSAND)
{
// Look for and strip out ' , and . but keep the last . as the decimal point
// Must modify original value so that it can be cast to a float
$parts = explode('.', $value);
$partsCount = count($parts);
if ($partsCount > 2)
{
$parts[$partsCount - 2] = $parts[$partsCount - 2].$parts[$partCount - 1];
unset($parts[$partsCount - 1]);
$value = implode('', $parts);
}
else
{
$value = str_replace(array('\'', ','), '', $value);
}
}
if (preg_match(HUM_PREG_FLOAT, $value))
{
return (float)$value;
}
return php_filter_failure($failure);
}
function php_filter_validate_regexp($value, $flags = null, $options = array(), $failure = false)
{
// Basic sanity checking on the data
if (is_string($value))
{
$value = trim((string)$value);
}
if (!is_string($value) || !strlen($value))
{
return php_filter_failure($failure);
}
$regex = is_array($options) && isset($options['regex']) ? $options['regex'] : false;
if ($regex === false)
{
NinjaError::trigger("filter_var() regex option missing", E_USER_ERROR, 1);
return php_filter_failure($failure);
}
if (preg_match($regex, $value))
{
return $value;
}
return php_filter_failure($failure);
}
function php_filter_validate_url($value, $flags = null, $options = array(), $failure = false)
{
// Basic sanity checking on the data
if (is_string($value))
{
$value = trim((string)$value);
}
if (!is_string($value) || !strlen($value))
{
return php_filter_failure($failure);
}
$allowedChars = HUM_LOWALPHA.HUM_HIALPHA.HUM_DIGIT.HUM_SAFE.HUM_EXTRA.HUM_NATIONAL.HUM_PUNCTUATION.HUM_RESERVED;
if ($value != preg_replace('/[^'.$allowedChars.']', '', $value))
{
return php_filter_failure($failure);
}
$url = parse_url($value);
if (is_null($url))
{
return php_filter_failure($failure);
}
if (is_null($url['scheme']) ||
/* some schemas allow the host to be empty */
(is_null($url['host']) && ($url['scheme'] != 'mailto' && $url['scheme'] != 'news' && $url['scheme'] != 'file'))
||
(($flags & FILTER_FLAG_PATH_REQUIRED) && is_null($url['path'])) || (($flags & FILTER_FLAG_QUERY_REQUIRED) && is_null($url['query'])))
{
return php_filter_failure($failure);
}
return $value;
}
function php_filter_validate_email($value, $flags = null, $options = array(), $failure = false)
{
// This looks easy but wait until you see the regex!
if (is_string($value) && strlen($value))
{
if (preg_match(HUM_PREG_EMAIL, $value))
{
return $value;
}
}
return php_filter_failure($failure);
}
function php_filter_validate_ip($value, $flags = null, $options = array(), $failure = false)
{
/* validates an ipv4 or ipv6 IP, based on the flag (4, 6, or both) add a
* flag to throw out reserved ranges; multicast ranges... etc. If both
* allow_ipv4 and allow_ipv6 flags flag are used, then the first dot or
* colon determine the format */
// Basic sanity checking on the data
if (is_string($value))
{
$value = trim((string)$value);
}
if (!is_string($value) || !strlen($value))
{
return php_filter_failure($failure);
}
// IPv6 address and looking for Ipv4 address only
if (($flags & FILTER_FLAG_IPV4) && !($flags & FILTER_FLAG_IPV6) && !strpos($value, '.'))
{
return php_filter_failure($failure);
}
// Ipv4 address and looking for IPv6 address only
elseif (($flags & FILTER_FLAG_IPV6) && !($flags & FILTER_FLAG_IPV4) && !strpos($value, ':'))
{
return php_filter_failure($failure);
}
// It's a valid IPv4 Address
elseif ($value == long2ip(ip2long($value)))
{
$ip = explode('.', $value);
if ($flags & FILTER_FLAG_NO_PRIV_RANGE)
{
if (($ip[0] == 10) || ($ip[0] == 172 && ($ip[1] >= 16 && $ip[1] <= 31)) || ($ip[0] == 192 && $ip[1] == 168))
{
return php_filter_failure($failure);
}
}
if ($flags & FILTER_FLAG_NO_RES_RANGE)
{
if (($ip[0] == 0) || ($ip[0] == 169 && $ip[1] == 254) || ($ip[0] == 192 && $ip[1] == 0 && $ip[2] == 2) || ($ip[0] >= 224 && $ip[0] <= 255))
{
return php_filter_failure($failure);
}
}
return $value;
}
// It seems to be a IPv6 address, lets look more closly
elseif (strpos($value, ':'))
{
// Looks like Ipv4 embedded in IPv6
if (strstr($value, '.'))
{
$ipv4 = null;
if(strstr($value, '0:'))
{
$ipv4 = str_replace('0:0:0:0:0:0:', '', $value);
}
elseif(strstr($value, '::'))
{
$ipv4 = str_replace('::', '', $value);
}
if ($ipv4 && $ipv4 == long2ip(ip2long($ipv4)))
{
return $value;
}
}
// $value might be a full IPv6 Address, lets examine it
else
{
$ipv6 = explode(':',$value);
if (is_array($ipv6) && count($ipv6))
{
$compressed = false;
foreach ($ipv6 as $hex)
{
if (!strlen($hex) && !$compressed)
{
// one compressed segment of zeros allowed
// (any series of consective zero values can be expressed as '::'
// and exploding on ':' means we will see it as an empty string)
$compressed = true;
continue;
}
elseif (!ctype_xdigit($hex))
{
// This segment should be hex but isn't
return php_filter_failure($failure);
}
}
// if we made it this far the address looks good.
return $value;
}
}
}
return php_filter_failure($failure);
}
function filter_list()
{
static $filters = 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',
);
return $filters;
}
function filter_id($name)
{
static $filters = array(
'int' => 257,
'boolean' => 258,
'float' => 259,
'validate_regexp' => 272,
'validate_url' => 273,
'validate_email' => 274,
'validate_ip' => 275,
'string' => 513,
'stripped' => 513,
'encoded' => 514,
'special_chars' => 515,
'unsafe_raw' => 516,
'email' => 517,
'url' => 518,
'number_int' => 519,
'number_float' => 520,
'magic_quotes' => 521,
'callback' => 1024,
);
if (!is_string($name) || !array_key_exists($name, $filters)) return null;
return $filters[$name];
}
/**
* Checks if variable of specified type exists (compatible with the filter extension)
*
* @return Bool Returns true on success or false on failure
* @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV
* @param string $variable_name Name of a variable to check
* @author Kieran Whitbread
**/
function filter_has_var($type, $variable_name)
{
switch ($type)
{
case INPUT_POST: $var = $_POST; break;
case INPUT_GET: $var = $_GET; break;
case INPUT_COOKIE: $var = $_COOKIE; break;
case INPUT_ENV: $var = $_ENV; break;
case INPUT_SERVER: $var = $_SERVER; break;
case INPUT_SESSION: $var = false;
$warning = 'INPUT_SESSION';
break;
case INPUT_REQUEST: $var = false;
$warning = 'INPUT_REQUEST';
break;
default: $var = false;
break;
}
if (isset($warning))
{
NinjaError::trigger("filter_has_var(): $warning is not yet implemented", E_USER_WARNING, 1);
}
return $var !== false && isset($var[$variable_name]);
}
/**
* Gets external variables and optionally filters them (compatible with the filter extension)
*
* @return mixed
* @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV
* @param string $variable_name Name of a variable to check
* @author Kieran Whitbread
**/
function filter_input_array($type, $definition)
{
// FIXME: Lots to implement here, just follow the description of how this works in the PHP docs and make multiple calls
// to filter_var();
/*
switch ($type)
{
case INPUT_POST: $var = $_POST; break;
case INPUT_GET: $var = $_GET; break;
case INPUT_COOKIE: $var = $_COOKIE; break;
case INPUT_ENV: $var = $_ENV; break;
case INPUT_SERVER: $var = $_SERVER; break;
case INPUT_SESSION: $var = false;
$warning = 'INPUT_SESSION';
break;
case INPUT_REQUEST: $var = false;
$warning = 'INPUT_REQUEST';
break;
default: $var = false;
break;
}
if (isset($warning)) trigger_error("filter_input_array(): $warning is not yet implemented", E_USER_WARNING);
return $var !== false && isset($var[$variable_name]);*/
}
/**
* Filters a variable with a specified filter (compatible with the filter extension)
*
* @return mixed Returns the filtered data, or FALSE if the filter fails.
* @param mixed $variable Value to filter.
* @param int $filter ID of a filter to use. Defaults to FILTER_SANITIZE_STRING.
* @param mixed $options Associative array of options or bitwise disjunction of flags. If filter accepts options, flags can be provided in "flags" field of array. The "callback" filter is not supported in this version
* @author Kieran Whitbread
**/
function filter_var($variable, $filter = FILTER_SANITIZE_STRING, $options = array())
{
NinjaError::trigger("filter_var() not implemented", E_USER_ERROR, 1);
$flags = is_numeric($options) ? (int) $options : (
is_array($options) && isset($options['flags']) && is_numeric($options['flags']) ? (int) $options['flags'] : 0
);
$failure = $flags & FILTER_NULL_ON_FAILURE ? null : false;
$value = null; // FIXME: Pull value out of variable
if ($flags & FILTER_REQUIRE_SCALAR && !is_scalar($value))
{
return php_filter_failure($failure);
}
if ($flags & FILTER_REQUIRE_ARRAY && !is_array($value))
{
return php_filter_failure($failure);
}
// FIXME: Detect if variable is an array and loop appropriately.
// FIXME: Parse filter parameter and run one of the above functions.
// If the user wants an array, but $variable is not an array we must wrap it in an array.
if ($flags & FILTER_FORCE_ARRAY && !is_array($variable))
{
$value = array($value);
}
return $value;
}
}
