/** * superGlobals library * * Transparently injects into superglobal or global variable with keeping all functionality of regular * array, but extending it with type casting and URI parsing. * * Usage: * * superGlobal::db($instance); * * Set DB instance for all DB-related operations. * * superGlobal::memcached($instance) * * Set Memcache instance to enable built-in cache * * superGlobal::inject($array|$string); * * Inject superGlobal functionality into global or superglobal variable. * If additional parameters passed with registerParam or registerSQLParam overlaps already existing * parameters in array, initial value will be stored in parameter array, which is accessible as * $array['array:param']. * * If passed variable contains string, it will be stored as URI for future parsing by registerParam or * registerSQLParam methods. * * superGlobal::registerParam('name', 'callback'); * superGlobal::registerParam('name', array(values)); * * Inject into $_GET (if was not injected previously), then parse URI parameters into all of injected global arrays * and only $_GET superglobal array, so if URI string parameter (REQUEST_URI for $_GET or manually provided for * other arrays) contains parameter from values array provided or provided callback function will return something * different from false, this piece will be stored in resulting array with name key. * * superGlobal::registerParam('type:name', 'callback'); * superGlobal::registerParam('type:name', array(values)); * * Same as previous example, except URI parameter will be additionally casted into provided type. * * superGlobal::registerSQLParam('name', 'table', 'field'); * superGlobal::registerSQLParam('type:name', 'table', 'field'); * * List of possible values for parameter will be fetched from SQL table 'table' from field 'field'. * (DB abstraction instance should be provided and getCol method should be implemented) * * superGlobal::registerParam('name', 'callback', $array); * superGlobal::registerSQLParam('name', 'table', 'field', $array); * * Register param into only one array. Also allows to inject parameters into superglobal arrays different * from $_GET. * * After injecting it provides several casting methods for all of array variables, which should be defined in * requesting variable name and separated from it by semicolon: * * Fetch variable as boolean (returns boolean): * $_SUPERGLOBAL['bool:key'] * * Fetch variable as integer (returns integer): * $_SUPERGLOBAL['int:key'] * * Fetch variable as float (returns float): * $_SUPERGLOBAL['float:key'] * * Fetch variable as regular string (returns string): * $_SUPERGLOBAL['string:key'] * * Fetch variable as array (returns array): * $_SUPERGLOBAL['array:key'] * * Fetch variable as IP address (IPv6 or IPv4) (returns string): * $_SUPERGLOBAL['ip:key'] * * Fetch variable as IP address (IPv4 or IPv6), only from public networks (returns string): * $_SUPERGLOBAL['ippub:key'] * * Fetch variable as IP address (only IPv4) (returns string): * $_SUPERGLOBAL['ipv4:key'] * * Fetch variable as IP address (only IPv6) (returns string): * $_SUPERGLOBAL['ipv6:key'] * * Fetch variable as regular expression (returns string): * $_SUPERGLOBAL['regexp:key'] * * Fetch variable as correct URL (returns string): * $_SUPERGLOBAL['url:key'] * * Fetch variable as URL encoded string (returns string): * $_SUPERGLOBAL['encode:key'] * * Fetch variable as HTML escaped string (returns string): * $_SUPERGLOBAL['escape:key'] * * Fetch variable as regular object (returns object): * $_SUPERGLOBAL['object:key'] * * Fetch variable as SQL escaped string (returns string): * $_SUPERGLOBAL['sql:key'] * * It is possible to pass function name callback as casting method, for example, next will return trimmed * value of $_SUPERGLOBAL['key']. * $_SUPERGLOBAL['trim:key'] * * Also, it is possible to pass multiple casting methods, which is useful for array processing, next will return an * array with all matching values for $_SUPERGLOBAL['key'] casted to float and then cos() function applied. * $_SUPERGLOBAL['array:float:cos:key'] * * May throw exceptions (Exception $e) with codes: * 1: Trying to directly create an instance of class * 100: DB driver is not set or method missing * 200: There is no filter.so installed * 300: Callback or casting (if enabled) exception * 400: Trying to register variable that is not global * 500: Incorrect use of registerParam or registerSQLParam functions * 600: Memcache exception * * License * * This source file is subject to the new BSD license that is bundled * with this package in the file license.txt. * It is also available through the world-wide-web at this URL: * http://ics.net.ua/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@ics.net.ua so we can send you a copy immediately. * * @package superGlobals * @author Max S. Yarchevsky max@ics.net.ua * @license http://ics.net.ua/license/new-bsd New BSD License * @version 1.169 */ /** * Helper class to inject into superglobal. * Provides value casting and URL string parsing. * Should not be called directly. * * @uses ArrayAccess * @uses Iterator * @uses Countable * @package superGlobals * @author Max S. Yarchevsky max@ics.net.ua * @license http://ics.net.ua/license/new-bsd New BSD License * @version 1.169 */ class requestCaster extends superGlobal implements ArrayAccess, Iterator, Countable { /** * Storage of params found from URL or passed from request * * @var array */ private $storage; /** * Array of possible param values * * @var array */ private $values; /** * If param need additional casting, callback function or type should be stored here * * @var array */ private $castCallbacks; /** * Data types and regular expressions for variable casting * * @var array */ private static $castMethods; /** * Unparsed values that left after last iteration * * @var array */ private $unParsed; /** * General class contructor. Should not be called directly. * * @param array $params Array data to merge into instance * @param string $URI Uniform resource identifier string to parse values from * @return boolean|void */ public function __construct(array &$params, $URI = false) { // Define casting methods if (!is_array(self::$castMethods)) { self::$castMethods = array( // Possible variable types for filtering 'varTypes' => array( // Boolean type. Can be false|true|1|0 'bool' => array( 'filter' => FILTER_VALIDATE_BOOLEAN, 'options' => FILTER_NULL_ON_FAILURE, 'cast' => 'bool' ), // Integer type 'int' => array( 'filter' => FILTER_SANITIZE_NUMBER_INT, 'options' => FILTER_NULL_ON_FAILURE, 'cast' => 'int' ), // Float type 'float' => array( 'filter' => FILTER_SANITIZE_NUMBER_FLOAT, 'options' => FILTER_NULL_ON_FAILURE + FILTER_FLAG_ALLOW_FRACTION + FILTER_FLAG_ALLOW_SCIENTIFIC, 'cast' => 'float' ), // Regular string 'string' => array( 'filter' => FILTER_SANITIZE_STRING, 'options' => FILTER_NULL_ON_FAILURE, 'cast' => 'string' ), // Regular array 'array' => array( 'cast' => 'array' ), // IP address (IPv4 or IPv6) 'ip' => array( 'filter' => FILTER_VALIDATE_IP, 'options' => FILTER_NULL_ON_FAILURE, 'cast' => 'string' ), // IP address (IPv4 or IPv6), only from public networks 'ippub' => array( 'filter' => FILTER_VALIDATE_IP, 'options' => FILTER_NULL_ON_FAILURE + FILTER_FLAG_NO_PRIV_RANGE, 'cast' => 'string' ), // IP address (only IPv4) 'ipv4' => array( 'filter' => FILTER_VALIDATE_IP, 'options' => FILTER_NULL_ON_FAILURE + FILTER_FLAG_IPV4, 'cast' => 'string' ), // IP address (only IPv6) 'ipv6' => array( 'filter' => FILTER_VALIDATE_IP, 'options' => FILTER_NULL_ON_FAILURE + FILTER_FLAG_IPV6, 'cast' => 'string' ), // Regular expression 'regexp' => array( 'filter' => FILTER_VALIDATE_REGEXP, 'options' => FILTER_NULL_ON_FAILURE, 'cast' => 'string' ), // Uniform resource locator 'url' => array( 'filter' => FILTER_SANITIZE_URL, 'options' => FILTER_NULL_ON_FAILURE, 'cast' => 'string' ), // URL encoded string 'encode' => array( 'filter' => FILTER_SANITIZE_ENCODED, 'options' => FILTER_NULL_ON_FAILURE + FILTER_FLAG_ENCODE_LOW + FILTER_FLAG_ENCODE_HIGH, 'cast' => 'string' ), // HTML escaped string 'escape' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'options' => FILTER_NULL_ON_FAILURE + FILTER_FLAG_STRIP_LOW, 'cast' => 'string' ), // Regular object 'object' => array( 'cast' => 'object' ) ), // Built-in cast functions 'callback' => array( 'sql' => 'castEscape' ) ); } // If no params got for initial launch we'll use empty array for init $this->storage = is_array($params) ? $params : array(); $this->unParsed = ($URI) ? explode("/", substr(parse_url($URI,PHP_URL_PATH), 1)) : array(); // Prepare params got from array foreach ($this->storage as $k => $v) { $this->values[$k] = array(); $this->storage[$k] = array('value' => $v); } // Init system arrays $this->castCallbacks = array(); $params = &$this; } /** * Checks if value need to be casted before return * * @param string reference $param Asked superglobal key reference * @return void */ private function checkCast(&$param) { if (strpos($param,':') != false) { $cast = explode(':',$param); $param = array_pop($cast); $this->castCallbacks[$param] = $cast; } } /** * Returns string escaped for DB driver * * @param string $value String to escape * @return string Escaped string */ private function castEscape($value) { // Check DB initialized if (!parent::$mdb || !method_exists(parent::$mdb,'escape')) { if (parent::$throwExceptionOnCast) { throw new Exception('DB driver is not set or escape method missing, cannot escape as SQL correctly', 100); } return mysql_escape_string($value); } // Get DB driver instance from parent return parent::$mdb->escape($value); } /** * Throw an exception if cast failed * * @param mixed $value Casted value * @return mixed Casted value */ private function checkCastValue($value, $exception) { if (null === $value && parent::$throwExceptionOnCast) { throw new Exception($exception, 300); } return $value; } /** * Returns filter options for casting method * * @param string $method Filter method * @return int Filter parameters */ private function getCastOptions($method) { return isset(self::$castMethods['varTypes'][$method]['options']) ? self::$castMethods['varTypes'][$method]['options'] : FILTER_FLAG_NONE; } /** * Value casting by type or function callback * * @param mixed $value Parameter value * @param string|array $callback Cast type or function callback * @return mixed Casting result */ private function castValue($value, $callback) { // If we have additional parameters passed for callback as array we should separate them from main filter if (is_array($callback)) { $shifted = array_shift($callback); $additionalCast = count($callback) > 0 ? $callback : false; $callback = $shifted; } else { $additionalCast = false; } // Generate memcached key and check for parsed value for it $memKey = array($value,$callback,$additionalCast); if ($cached = $this->memcache($memKey)) { return $cached; } // If we only need to cast type if (array_key_exists($callback, self::$castMethods['varTypes'])) { // If type casting failed return null, else return casted variable if (isset(self::$castMethods['varTypes'][$callback]['filter'])) { // Check for filters available if (!function_exists('filter_list')) { throw new Exception('There are no filters available because filter.so is missing', 200); } $value = filter_var( $value, self::$castMethods['varTypes'][$callback]['filter'], $this->getCastOptions($callback) ); } // Check for cast needed if (isset(self::$castMethods['varTypes'][$callback]['cast']) && !empty($value)) { $value = settype($value,self::$castMethods['varTypes'][$callback]['cast']) ? $value : null; } // Additional nulling of empty if (empty($value)) { $value = null; } // If we have additional casting parameters if ($additionalCast) { if (is_array($value)) { // If we have array foreach ($additionalCast as $castMethod) { /*/ Use faster way of casting if (array_key_exists($castMethod, self::$castMethods['varTypes'])) { $value = filter_var_array( $value, self::$castMethods['varTypes'][$castMethod]['filter'] + $this->getCastOptions($castMethod) ); var_dump($value); } else {*/ // Use recursion. Slow but it works anyway. // Some versions of PHP (for ex., current stable debian 5.2.0.8) do not support int as second parameter // for filter_var_array. Even more, it do not support arrays with numeric keys as input for filtering. // I can create associative array for storage (absolutely useless), but i think there is an idiotic way to // also copy such array with all values set to array, which should contain filter method and filter options // separated from each other. foreach ($value as &$v) { $v = $this->castValue($v, $castMethod); } } } else { // Prevent passing null into callback functions if (null !== $value) { // Maybe we'll need to use casting twice. I'm not sure, so i'll include here some piece of recursion foreach ($additionalCast as $castMethod) { $value = $this->castValue($value, $castMethod); } } } } // Cache value processing result $this->memcache($memKey, $value); return $this->checkCastValue($value, 'Value casting to '.$callback.' data type failed'); } // Also we should try built-in cast functions // We do not cache it when used alone because in some situations callback result may // differ for same value. // Please note, called with variable casting it will be cached. if ( array_key_exists($callback, self::$castMethods['callback']) && method_exists($this, self::$castMethods['callback'][$callback]) ) { $method = self::$castMethods['callback'][$callback]; return $this->checkCastValue($this->$method($value), 'Value casting by '.$callback.' built-in cast failed'); } // Else, if we need to make a callback // We do not cache it when used alone because in some situations callback result may // differ for same value. // Please note, called with variable casting it will be cached. if (function_exists($callback)) { return $this->checkCastValue($callback($value), 'Value casting by "'.$callback.'" function failed'); } throw new Exception('Value casting callback function "'.$callback.'" do not exist', 300); return $value; } /** * Add new URL parameter from DB column * * @param string $param Url parameter key * @param string $table Table to fetch from * @param string $field Field containing possible values for parameter * @return void|false */ public function addSQLParam($param, $table, $field) { // Check for casting request $this->checkCast($param); // Keep previously passed parameter into values array if (array_key_exists($param,$this->storage)) { $this->storage[$param] = array('array' => array($this->storage[$param]['value'])); } if ($cached = $this->memcache(array($param, $table, $field))) { $this->values[$param] = $cached; return; } // Check DB initialized and methods implemented if (!parent::$mdb || (!method_exists(parent::$mdb,'getCol') && !method_exists(parent::$mdb,'getOne'))) { throw new Exception('DB driver is not set or getCol method missing, cannot add parameter from DB', 100); return false; } // Select method if (method_exists(parent::$mdb,'getCol')) { $values = parent::$mdb->getCol('select DISTINCT '.$field.' from '.$table); } else { $values = explode( ',', parent::$mdb->getOne('select GROUP_CONCAT( DISTINCT '.$field.' SEPARATOR ",") from '.$table)); } $this->memcache(array($param, $table, $field), $values); // Get DB driver instance from parent $this->values[$param] = $values; } /** * Add new URL parameter as array of values or callback function * * @param string $param Url parameter key * @param mixed $value Array of possible values or string containing callback function name */ public function addParam($param, $value) { // Check for casting request $this->checkCast($param); // Keep previously passed parameter into values array if (array_key_exists($param,$this->storage)) { $this->storage[$param] = array('array' => array($this->storage[$param]['value'])); } $this->values[$param] = $value; } /** * Returns matching value for key, adding it into array of found values. * * @param string $key Url parameter key * @return string */ private function parseValue($key) { // Check for key existance if (!array_key_exists($key, $this->values) && !array_key_exists($key, $this->storage)) { return false; } // Check for callback $callback = (!is_array($this->values[$key])) ? $this->values[$key] : false; // Check for previously found key if (array_key_exists($key, $this->storage) && isset($this->storage[$key]['value'])) { return $this->storage[$key]['value']; } // Init array of passed values if (!isset($this->storage[$key]['array'])) { $this->storage[$key]['array'] = array(); } // If we have item in cache if ($cached = $this->memcache(array($this->unParsed, $callback))) { $this->storage[$key] = $cached; } else { // Iterate params and find if param is defined foreach ($this->unParsed as $k => $v) { // Are qe using callback or an array ? $condition = ($callback) ? $this->castValue($v, $callback) : in_array($v, $this->values[$key]); // We found it if ($condition) { // Cast value if callback present, else just store $this->storage[$key]['value'] = array_key_exists($key,$this->castCallbacks) ? $this->castValue($v,$this->castCallbacks[$key]) : $v; // Add value into array of passed values, should be distinct if (!in_array($this->storage[$key]['value'], $this->storage[$key]['array'])); { $this->storage[$key]['array'][] = $this->storage[$key]['value']; } } } } // Do not return from cycle to prevent multiple params for one key. We get only last one. return isset($this->storage[$key]['value']) ? $this->storage[$key]['value'] : null; } /** * Does offset exist ? * * @param string|int $key * @return bool */ public function offsetExists($key) { return (bool)$this->parseValue($key); } /** * Retrieve by offset * * @param string|int $key * @return mixed */ public function offsetGet($key) { // Check for runtime casting $cast = false; if (strpos($key,':') != false) { $cast = explode(':',$key); $key = array_pop($cast); } // Get value $value = $this->parseValue($key); // If array casting passed, but we do not hold an array as value, we need to return array of all input for key if ($cast[0] == 'array' && !is_array($value)) { $value = $this->storage[$key]['array']; } return $cast ? $this->castValue($value, $cast) : $this->parseValue($key); } /** * Set value by offset * * @param string $key * @param mixed $value * @return void */ public function offsetSet($key, $value) { $this->storage[$key]['value'] = $value; } /** * Unset value by offset * * @param string $key * @return void */ public function offsetUnset($key) { unset($key); } /** * How many items are present * * @return int */ public function count() { return count($this->values); } /** * Get current value * * @return array */ public function current() { $current = key($this->values); return $this->parseValue($current); } /** * Get next item * * @return void */ public function next() { next($this->values); } /** * Get current key * * @return string|int */ public function key() { return key($this->values); } /** * Rewind to first value in collection * * @return void */ public function rewind() { reset($this->values); } /** * Is item valid ? * * @return bool */ public function valid() { return (bool) $this->current(); } /** * Serialize current state * * @return array */ public function __sleep() { return array('params', 'storage', 'unParsed', 'castCallbacks', 'castMethods'); } /** * Store value into memcache by key or get value for key * * @param string|array $key Key for object in memcached * @param string[optional] $value Value to set for key * @return mixed Value from memcached server or boolean of request result */ private function memcache($key, $value = false) { // If we have memcache instance if(parent::$memcached) { // Prevent whitespaces or non-string keys $key = md5(serialize($key)); // Set value if passed if($value) { return parent::$memcached->set($key, $value, 0, parent::$memcacheTimeout); } // Try to get value return parent::$memcached->get($key); } return false; } /** * Magic method, used here to generate URI representation of parameters * * @return string URI string */ public function __toString() { $return = array(); $returnstr = array(); // Iterate self to get all of params foreach ($this as $k => $v) { if (empty($this->values[$k])) // If it is not registered variable process it as usual $_GET { $return[] = $k.'='.$v; } else // If we already found it we can return it as a part of URI { foreach ($this->storage[$k]['array'] as $v) { // Don't duplicate if (!in_array($v,$returnstr)) { $returnstr[] = $v; } } } } return implode('/',$returnstr).(!empty($return) ? '?'.implode('&',$return) : ''); } } /** * Worker class for transparent managing of superglobal arrays * * @uses requestCaster * @package superGlobals * @author Max S. Yarchevsky max@ics.net.ua * @license http://ics.net.ua/license/new-bsd New BSD License * @version 1.169 */ class superGlobal { /** * Singleton instance of self * * @var object */ private static $instance; /** * DB abstraction instance. * * @var object */ protected static $mdb = false; /** * Should we throw an exception on value cast failure or just return null ? * * @var boolean */ protected static $throwExceptionOnCast = false; /** * Timeout for memcached cache * * @var int */ protected static $memcacheTimeout = 300; /** * Memcache instance. * * @var object */ protected static $memcached = false; /** * Instances of superglobal replacers * * @var array */ protected static $superglobals = array(); /** * Creates singleton for class * * @return object */ private static function singleton() { // Still did not initialized ? if (!is_object(self::$instance)) { self::$instance = new superGlobal(); self::$instance->injectInto('_GET'); } return self::$instance; } /** * Inits class if you do not want to use additional parameters * * @return void */ public static function start() { self::singleton(); } /** * Sets DB abstraction instance for all of superglobals * * @param object $DB DB abstraction instance * @return void */ public static function db(&$DB) { self::$mdb = &$DB; } /** * Sets Memcache instance for all of superglobals * * @param object $memcache Memcache instance * @param int $timeout Memcache keep timeout * @return void */ public static function memcached(&$memcache, $timeout = 300) { self::$memcached = &$memcache; self::$memcacheTimeout = $timeout; } /** * Inject requestCaster into variable (only for internal calls) * Useful because sometimes we use instance of class to call it * * @param string $variable Array name to inject * @return void */ private function injectInto($variable) { $globs = array( '_GET' => $_GET, '_POST' => $_POST, '_COOKIE' => $_COOKIE, '_SERVER' => $_SERVER, '_REQUEST' => $_REQUEST, ); if (isset($_SESSION)) { $globs['_SESSION'] = &$_SESSION; } // Is a superglobal if(array_key_exists($variable,$globs)) { // Check if we already injected variable // If we did there is no need to create new object if(!array_key_exists($variable,self::$superglobals)) { // Parse URL only into _GET self::$superglobals[$variable] = ($variable == '_GET') ? // Create instance of requestCaster new requestCaster($globs[$variable], $_SERVER['REQUEST_URI']) : new requestCaster($globs[$variable]); } // We need to do so because superglobals should be accessed directly (bug ?) switch ($variable) { case '_GET': $_GET = &self::$superglobals[$variable]; break; case '_POST': $_POST = &self::$superglobals[$variable]; break; case '_COOKIE': $_COOKIE = &self::$superglobals[$variable]; break; case '_SERVER': $_SERVER = &self::$superglobals[$variable]; break; case '_SESSION': $_SESSION = &self::$superglobals[$variable]; break; case '_REQUEST': $_REQUEST = &self::$superglobals[$variable]; break; } // Exit from function return; } // Variable is not superglobal, so we should check if it is at least global global $$variable; // Check for consistency if (!isset($$variable) || (!is_array($$variable) && !is_string($$variable))) { throw new Exception( 'Only global or superglobal variable may be passed as a place to inject requestCaster into it', 400); } // Check if we already injected variable // If we did there is no need to create new object if(!array_key_exists($variable,self::$superglobals)) { // We need to pass string contents of variable as URI, if given self::$superglobals[$variable] = is_array($$variable) ? // Create requestCaster instance new requestCaster($$variable) : new requestCaster(array(), $$variable); } // Inject into it $$variable = &self::$superglobals[$variable]; } /** * Inject requestCaster into variable * * @param string $superglobal Superglobal name */ public static function inject($superglobal) { self::$instance->injectInto($superglobal); } /** * General class contructor * * @return boolean|void */ public function __construct() { // Maybe we'll try to create class manually.. But we should not. if (is_object(self::$instance)) { throw new Exception('You can\'t directly create instance of class requestCaster', 1); } } /** * Add new URL parameter from DB column * * @param string $param Url parameter key * @param string $table Table to fetch from * @param string $field Field containing possible values for parameter * @param string[optional] $array Global array variable name to register into * @return void */ public static function registerSQLParam($param, $table, $field, $array = false) { self::singleton()->register('sql', $param, array('table' => $table, 'field' => $field), $array); } /** * Add new URL parameter as array of values or callback function * * @param string $param Url parameter key * @param mixed $value Array of possible values or string containing callback function name * @param string[optional] $array Global array variable name to register into * @return void */ public static function registerParam($param, $value, $array = false) { self::singleton()->register('array', $param, array('value' => $value), $array); } /** * Add new URL parameter from array or DB * * @param string $type Type of registering. Can be 'db' or 'array' * @param string $param Url parameter key * @param array $options Options for registering. Should contain 'value' array or 'table' and 'field' strings * @param string[optional] $array Global array variable name to register into */ private function register($type, $param, $options, $array = false) { // It's useless to register params into these arrays. Believe me. $forbiddenArrays = array('_POST', '_COOKIE', '_SERVER', '_SESSION', '_REQUEST'); // Make sure that we have worker instance self::singleton(); // If we need to register parameter into known array if ($array) { // Try to inject into array if it is not present if (!array_key_exists($array,self::$superglobals)) { self::singleton()->injectInto($array); } // We need to check for array presence again if (!isset(self::$superglobals[$array])) { throw new Exception( 'Requested array '.$array.' do not exists, so parameter '.$param.' cannot be registered', 400); return; } // Proxy to requestCaster functions of given array, depending on parameter type if ($type == 'sql' && isset($options['table']) && isset($options['field'])) { self::$superglobals[$array]->addSQLParam($param, $options['table'], $options['field']); return; } if ($type == 'array' && isset($options['value']) && is_array($options['value'])) { self::$superglobals[$array]->addParam($param, $options['value']); return; } // We did not got nor correct sql nor correct array options set throw new Exception('Incorrect use of superGlobal::register* functions set', 500); return; } // Register parameter into each of global arrays foreach (array_keys(self::$superglobals) as $k) { // If array is not in forbidden list if(!in_array($k,$forbiddenArrays)) { // Proxy to requestCaster functions of given array, depending on parameter type if ($type == 'sql' && isset($options['table']) && isset($options['field'])) { self::$superglobals[$k]->addSQLParam($param, $options['table'], $options['field']); return; } if ($type == 'array' && isset($options['value']) && isset($options['value'])) { self::$superglobals[$k]->addParam($param, $options['value']); return; } // We did not got nor correct sql nor correct array options set throw new Exception('Incorrect use of superGlobal::register* function set', 500); return; } } } /** * Enable or disable exceptions on casting errors * * @param boolean[optional] $enable Use false to disable such exceptions back * @return void */ public static function enableCastExceptions($enable = true) { self::$throwExceptionOnCast = $enable; } }