Login   Register  
PHP Classes
elePHPant
Icontem

File: requestcleaner.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Gabriel Harrison  >  Form Data Cleaner  >  requestcleaner.php  >  Download  
File: requestcleaner.php
Role: Class source
Content type: text/plain
Description: Commented class source
Class: Form Data Cleaner
Sanitise GET and POST values based on type rules
Author: By
Last change: Small bug fix for incorrect return value. Thanks to Joelle Tegwen for telling me about it.
Date: 7 years ago
Size: 14,190 bytes
 

Contents

Class file image Download
<?php

/*************************************
CLASS: requestCleaner
This class will clean up POST and GET data based on a given data types for each keyword.

	Version 1.0, Created 07/09/2006
	Author: Gabriel Harrison <gabriel@gabrielharrison.co.uk> 
	Owner: Corus Northern Engineering Services UK
	License: Free for non-commercial use.

	FUNCTION: CleanRequest($varsGET=array(), $varsPOST=array(), $varsBOTH=array())
	
		All inputs are multidimentional hash in the form 'var' => 'type'
		where var is the name of a $_GET key for varsGET, a $_POST key for varsPOST or either for varsBOTH
		
		Types keywords understood by the function are:
		
			boolean (or bool)
			integer (or int)
			float (double)
			string
			array 
			
		If an array type is given and the submitted data is an array the function will us recursion 
		to check all elements of an array. 
		
		The function returns a array of escaped and typecast data based on either $_POST or $_GET depending 
		on the value of $_SERVER['REQUEST_METHOD']. BY default it will also overwrite $_POST or $_GET and 
		$_REQUEST so these can be used and assumed to be OK.
		
		Example:
			$rCleaner = new requestCleaner();
				$rCleaner->CleanRequest(
				array('primary' => 'int'), // Allowable $_GET variables
				array('event_value' => 'float', // Allowable $_POST variables
					'event_time'=>'string', 
					'event_category'=>'int', 
					'area'=>'int', 
					'subarea'=>'int', 
					'event_name'=>'string', 
					'event_status_id'=>'int', 
					'emp_id'=>'int', 
					'action_by'=>'int', 
					'hrs_hours'=>'float', 
					'event_priority_id'=>'int', 
					'event_summary'=>'string', 
					'event_text'=>'string', 
					'parent_event_id'=>'int', 
					'nextid'=>'string', 
					'evnum'=>'int',
					'sort' => array(
						'field' => 'string'
						'desc' => 'int'
					}
					'MM_insert'=>'string'
				),
				array('event_project_id'=>'int') // Allowable $_GET and $_POST variables
			);
			
		The var key can also be * to denote a wildcard. If * is used and any unknown $_GET or $_POST key will 
		be check against this. This should be used as little as possible but was added for if you want to get
		an array but don't know all the possible keys.
		
			Example: ...php?person['name']=age where you don't know what	the name or age are going to be but you 
			do know their types. The data declaration for this example would be 'person' => array('*' => 'int').
			
		Only one wildcard can be defined in any array(). 
		
	Arrays with the Clean, Dirty and Unknown data can be access directly after CleanRequest has been called.
		
		E.g. $clean = $myRequest->clean; $dirty = $myRequest->dirty; $unknown = $myRequest->unknown;
			
	FUNCTION: isUnknown()
		Returns true or false for if there were and $_POST or $_GET keys passed than were not defined.
		This could be used to check for malicious POST or GET requests.
		
	CLASS DEFAULT OPTIONS:
		
		The following values can be set for when a variable is an empty string or an invalid bool, int or float.
		The defaults are shown here.
		
			blankBool => false
			invalidBool => false  // ie non-numeric
			blankInt => 0
			invalidInt => 0
			blankFloat => 0.0
			invalidFloat => 0.0
			blankString => ''
			blankArray => array()
			
		These can be modified using getter and setter functions. 
		The set functions all take one attribute which is the value.
		
		The full list is:
		
			setInvalidBool( true | false ) 
			setInvalidInt( int ) 
			setInvalidFloat( float ) 
			setBlankBool( true | false ) 
			setBlankInt( int ) 
			setBlankFloat( int ) 
			setBlankString( mixed var ) 
			setBlankArray( mixed var ) 
			
			getInvalidBool() 
			getInvalidInt() 
			getInvalidFloat() 
			getBlankBool() 
			getBlankInt() 
			getBlankFloat() 
			getBlankString() 
			getBlankArray()
			
	CLASS CONFIGURATION OPTIONS
	
		There are several configuration options that control the functioning of the Clean function.

			escapeStrings => RC_STRINGS_SIMPLE
				Controls if and how strings are escaped during cleaning. There are four constants to control this:
					RC_STRINGS_NONE - Just make sur the string is typecast correctly
					RC_STRINGS_SIMPLE - Add slashes only
					RC_STRINGS_MYSQL - call mysql_escape_string plus escape _ and %
					RC_STRINGS_HTML - call htmlspecialchars
			
			removeUnknown => true
				The 'dirty' variables are stored internally in the class and if removeUnknown is true it does not 
				store variables it doesn't have typecasting info for.
			
			overwriteGET => true
			overwritePOST => true
			overwriteREQUEST => true
				The three overwrite settings control if the Clean function overwrites $_GET, $_POST and $_REQUEST
			
			createMissing => true
				If this is set to true any variable types that are given to the class but not present 
				in $_GET or $_POST will be created and set to the default values.
				
		The following functions can be used to controll these settings:

			setEscapeStrings( RC_STRINGS_NONE | RC_STRINGS_SIMPLE | RC_STRINGS_MYSQL | RC_STRINGS_HTML ) 
			setOverwriteGET( true | false ) 
			setOverwritePOST( true | false ) 
			setOverwriteREQUEST( true | false ) 
			setCreateMissing( true | false ) 
			
			getEscapeStrings() 
			getRemoveUnknown() 
			getOverwriteGET() 
			getOverwritePOST() 
			getOverwriteREQUEST() 
			getCreateMissing() 

*************************************/

define('RC_STRINGS_NONE', 0);
define('RC_STRINGS_SIMPLE', 1);
define('RC_STRINGS_MYSQL', 2);
define('RC_STRINGS_HTML', 3);

class requestCleaner {

	//Private
	var $dirty = array();
	var $clean = array();
	var $unknown = array();
	var $defaults = array(
		'blankBool' => false,
		'invalidBool' => false,  // ie non-numeric
		'blankInt' => 0,
		'invalidInt' => 0,
		'blankFloat' => 0.0,
		'invalidFloat' => 0.0,
		'blankString' => '',
		'blankArray' => array());
		
	var $config = array(
	  'escapeStrings' => RC_STRINGS_SIMPLE,
		'removeUnknown' => true,
		'overwriteGET' => true,
		'overwritePOST' => true,
		'overwriteREQUEST' => true,
		'createMissing' => true
		); //GET POST REQUEST
		
	function isUnknown() {
		if(count($this->unknown)>0) return true;
		else return false;
	}
	
	function setInvalidBool($var) {
		$this->defaults['invalidBool']=$var;
		return true;
	}
	function setInvalidInt($var) {
		$this->defaults['invalidInt']=$var;
		return true;
	}
	function setInvalidFloat($var) {
		$this->defaults['invalidFloat']=$var;
		return true;
	}
	function setBlankBool($var) {
		$this->defaults['blankBool']=$var;
		return true;
	}
	function setBlankInt($var) {
		$this->defaults['blankInt']=$var;
		return true;
	}
	function setBlankFloat($var) {
		$this->defaults['blankFloat']=$var;
		return true;
	}
	function setBlankString($var) {
		$this->defaults['blankString']=$var;
		return true;
	}
	function setBlankArray($var) {
		$this->defaults['blankArray']=$var;
		return true;
	}

	function getInvalidBool() {
		return $this->defaults['invalidBool'];
	}
	function getInvalidInt() {
		return $this->defaults['invalidInt'];
	}
	function getInvalidFloat() {
		return $this->defaults['invalidFloat'];
	}
	function getBlankBool() {
		return $this->defaults['blankBool'];
	}
	function getBlankInt() {
		return $this->defaults['blankInt'];
	}
	function getBlankFloat() {
		return $this->defaults['blankFloat'];
	}
	function getBlankString() {
		return $this->defaults['blankString'];
	}
	function getBlankArray() {
		return $this->defaults['blankArray'];
	}
		
	function setEscapeStrings($var) {
		$this->config['escapeStrings']=$var;
		return true;
	}
	function setRemoveUnknown($var) {
		if($var===true) $this->config['removeUnknown']=true;
		else $this->config['removeUnknown']=false;
		return true;
	}
	function setOverwriteGET($var) {
		if($var===true) $this->config['overwriteGET']=true;
		else $this->config['overwriteGET']=false;
		return true;
	}
	function setOverwritePOST($var) {
		if($var===true) $this->config['overwritePOST']=true;
		else $this->config['overwritePOST']=false;
		return true;
	}
	function setOverwriteREQUEST($var) {
		if($var===true) $this->config['overwriteREQUEST']=true;
		else $this->config['overwriteREQUEST']=false;
		return true;
	}
	function setCreateMissing($var) {
		if($var===true) $this->config['createMissing']=true;
		else $this->config['createMissing']=false;
		return true;
	}

	function getEscapeStrings() {
		return $this->config['escapeStrings'];
	}
	function getRemoveUnknown() {
		return $this->config['removeUnknown'];
	}
	function getOverwriteGET() {
		return $this->config['overwriteGET'];
	}
	function getOverwritePOST() {
		return $this->config['overwritePOST'];
	}
	function getOverwriteREQUEST() {
		return $this->config['overwriteREQUEST'];
	}
	function getCreateMissing() {
		return $this->config['createMissing'];
	}
	
	function CleanRequest($varsGET=array(), $varsPOST=array(), $varsBOTH=array()) {
		$overwrite=false;
		
		if($this->config['overwriteGET'] || $this->config['overwritePOST'] || $this->config['overwriteREQUEST']) $overwrite = true;
		if($_SERVER['REQUEST_METHOD'] == 'GET') {
			$dirty = $_GET;
			$vars=array_merge_recursive($varsBOTH, $varsGET);
		} elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
			$dirty = $_POST;
			$vars=array_merge_recursive($varsBOTH, $varsPOST);
		}

		foreach($_COOKIE as $key => $value) {
			if(isset($dirty[$key])) {
				unset($dirty[$key]);
			}
		}
		
		list($this->clean, $this->dirty, $this->unknown) = $this->_Cleaner($vars, $dirty);
		if($this->config['createMissing']) {
			foreach($vars as $key => $val) {
				if(!isset($this->clean[$key])) {
					switch($val) {
						case 'boolean':
						case 'bool':
							$this->clean[$key] = $this->defaults['blankBool'];
							break;
						case 'integer':
						case 'int':
							$this->clean[$key] = $this->defaults['blankInt'];
							break;
						case 'float':
						case 'double':
							$this->clean[$key] = $this->defaults['blankFloat'];
							break;
						case 'string':
							$this->clean[$key] = $this->defaults['blankString'];
							break;
						case 'array':
							$this->clean[$key] = $this->defaults['blankArray'];
							break;
						default:
							//Error
							break;
					}
				}
			}
		}
		
		if($overwrite) {
			if($_SERVER['REQUEST_METHOD'] == 'GET' && $this->config['overwriteGET']) $_GET = $this->clean;
			elseif($_SERVER['REQUEST_METHOD'] == 'POST' && $this->config['overwritePOST']) $_POST = $this->clean;
			if($this->config['overwriteREQUEST']) $_REQUEST = $this->clean;
		}
		
		return $this->clean;
	}

	function _EscapeString($str, $method = false) {
		if(!$method) $method = $this->config['escapeStrings'];
		if($method == RC_STRINGS_SIMPLE) return addslashes((string) $str);
		elseif($method == RC_STRINGS_MYSQL) return addcslashes(mysql_escape_string((string) $str),'%_');
		elseif($method == RC_STRINGS_HTML) return htmlspecialchars((string) $str, ENT_QUOTES);
		else return (string) $str;
	}

	function _Cleaner($vars=array(), $dirty = array()) {
		//Declare Variables
		$clean = array();
		$unknown = array();
		$sw = '';
		$var = false;
		$star = false;
		$result = false;
		
		if(!is_array($dirty)) return false;
		
		foreach($dirty as $key => $val) {
		
			$star = false;
			if(isset($vars[$key])) $var = $vars[$key];
			elseif(isset($vars['*'])) {
				$var = $vars['*'];
				$star = true;
			} else $var = false;
			
			if($var !== false) { // Process Known Dirty var
				
				if(is_array($var)) $sw= 'array';
				else $sw = $var;
				
				switch($sw) {
					case 'boolean':
					case 'bool':
						if(is_string($val)) {
							if($val === '') {  // Set to default blank boolean value
								$clean[$key] = $this->defaults['blankBool'];
							} else {
								if(strval($val) == strval((int)($val)) || strval($val) == strval((float)($val))) {
									$clean[$key] = (bool) $val;
								} else {
									$clean[$key] = $this->defaults['invalidBool'];
								}
							}
						} else {
							$clean[$key] = (bool) $val;
						}

						break;
					case 'integer':
					case 'int':
						if(is_string($val)) {
							if($val === '') { 
								$clean[$key] = $this->defaults['blankInt'];
							} else {
								if(strval($val) == strval((int)($val))) {
									$clean[$key] = (int) $val;
								} else {
									$clean[$key] = $this->defaults['invalidInt'];
								}
							}
						} else {
							$clean[$key] = (int) $val;
						}
						break;
					case 'float':
					case 'double':
						if(is_string($val)) {
							if($val === '') { 
								$clean[$key] = $this->defaults['blankFloat'];
							} else {
								if(strval($val) == strval((float)($val))) {
									$clean[$key] = (float) $val;
								} else {
									$clean[$key] = $this->defaults['invalidFloat'];
								}
							}
						} else {
							$clean[$key] = (float) $val;
						}
						break;
					case 'string':
						if($val === '') { 
							$clean[$key] = $this->defaults['blankString'];
						} else {
							$clean[$key] = $this->_EscapeString($val);
						}
						break;
					case 'array':
						if($star) {
							$results = $this->_Cleaner($vars['*'], $val);
						} else {
							$results = $this->_Cleaner($vars[$key], $val);
						}
						
						if($results !== false) {
							if(!empty($results[0])) $clean[$key] = $results[0];
							if(!empty($results[1])) $dirty[$key] = $results[1];
							if(!empty($results[2])) $unknown[$key] = $results[2];
						} else {
							$unknown[$key] = $val;
						}
						
						break;
					default:
						//Error
						break;
				}
			} else { // Process Unknown Dirty var
				$unknown[$key] = $val;
			}
		}
		
		if($this->config['removeUnknown']) {
			foreach($unknown as $key => $val) {
				if(isset($dirty[$key])) {
					unset($dirty[$key]);
				}
			}
		}

		return array(0 => $clean, 1 => $dirty, 2 => $unknown);
	}
}

?>