[php5] formchecker : validation de saisies utilisateur

Soyez le premier à donner votre avis sur cette source.

Vue 8 896 fois - Téléchargée 875 fois

Description

Ceci est un code permettant de valider, au travers de différents masques expliqués dans le code, des saisies utilisateur (ou autre, à vrai dire).
Je me suis vaguement basé sur l'extension FILTERS de PHP, qui n'est pas disponible sur tous les serveurs, ni totalement finalisée.

Vous trouverez dans le ZIP une petite documentation, et le code est largement commenté.

Source / Exemple :


<?php
/**

  • FormChecker package
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20070104
*
  • /
/**
  • Messages classes
  • must be named this way : formCheckerMessagesXXX
  • where XXX is the alpha 3 country code
  • /
/**
  • class formCheckerMessagesENG
  • English localization of the messages
*
  • /
class formCheckerMessagesENG { const EMAIL_INVALID = 'The email address is invalid'; const URL_INVALID = 'The URL is invalid'; const REGEXP_FOUND_NOT_MATCH = 'Input {__INPUT__} does not match given regexp pattern'; const USER_FUNC_RETURNED_FALSE = 'User function {__FUNC__} returned false for {__INPUT__}'; const INPUT_EMPTY = 'You must fill in your {__INPUT__}'; const INPUT_NOT_IN_MIN_LENGTH = 'Your {__INPUT__} must et least have {__MIN_LENGTH__} characters'; const INPUT_NOT_IN_MAX_LENGTH = 'Your {__INPUT__} must at most have {__MAX_LENGTH__} characters'; const INPUT_NOT_IN_STRICT_LENGTH = 'Your {__INPUT__} must have {__STRICT_LENGTH__} characters'; const INPUT_STARTS_WITH = 'Your {__INPUT__} must start with {__START__}'; const INPUT_DONOT_START_WITH = 'Your {__INPUT__} must not start with {__START__}'; const INPUT_FORBIDDEN = 'these input are forbidden : {__FORBIDDEN__}'; const NUMERIC_NOT_NUMERIC = 'Your {__NUMERIC__} must be numeric'; const NUMERIC_NOT_IN_MIN_RANGE = 'Your {__NUMERIC__} must be greater than {__MIN_RANGE__}'; const NUMERIC_NOT_IN_MAX_RANGE = 'Your {__NUMERIC__} must be lesser than {__MAX_RANGE__}'; } /**
  • class formCheckerMessagesFRA
  • French localization of the messages
*
  • /
class formCheckerMessagesFRA { const EMAIL_INVALID = 'L\'adresse email saisie est invalide'; const URL_INVALID = 'L\'URL est invalide'; const REGEXP_FOUND_NOT_MATCH = 'Le motif d\'expression régulière n\'a pas été trouvé dans {__INPUT__}'; const USER_FUNC_RETURNED_FALSE = 'La fonction utilisateur {__FUNC__} a retourné false pour {__INPUT__}'; const INPUT_EMPTY = 'Vous devez saisir votre {__INPUT__}'; const INPUT_NOT_IN_MIN_LENGTH = 'Votre {__INPUT__} doit contenir au moins {__MIN_LENGTH__} caractères'; const INPUT_NOT_IN_MAX_LENGTH = 'Votre {__INPUT__} doit contenir au plus {__MAX_LENGTH__} caractères'; const INPUT_NOT_IN_STRICT_LENGTH = 'Votre {__INPUT__} doit être composé de {__STRICT_LENGTH__} caractères'; const INPUT_STARTS_WITH = 'Votre {__INPUT__} doit commencer par {__START__}'; const INPUT_DONOT_START_WITH = 'Votre {__INPUT__} ne doit pas commencer par {__START__}'; const INPUT_FORBIDDEN = 'Ces entrées sont interdites : {__FORBIDDEN__}'; const NUMERIC_NOT_NUMERIC = 'Votre {__NUMERIC__} doit être composé de chiffres'; const NUMERIC_NOT_IN_MIN_RANGE = 'Votre {__NUMERIC__} doit être supérieur à {__MIN_RANGE__}'; const NUMERIC_NOT_IN_MAX_RANGE = 'Votre {__NUMERIC__} doit être inférieur à {__MAX_RANGE__}'; } /**
  • class formCheckerException extends Exception
  • Specialized exceptions class
*
  • /
class formCheckerException extends Exception { const CLASS_NOT_EXISTS = 'Invalid pattern'; const CLASS_LOC_NOT_EXISTS = 'Invalid localization class'; const FILTER_MUST_BE_INT = 'Filter must be an integer'; const FILTER_NOT_ARRAY = 'Filter must be an array'; const NO_REGEXP = 'Regexp filter needs a regexp option'; const BAD_REGEXP = 'Bad regexp pattern'; const NO_USER_FUNC = 'No user function filter given'; const USER_FUNC_PARAMS_NO_ARRAY = 'User function parameters filter must be an array'; const SANITIZE_NO_USER_FUNC = 'No user function given to the sanitizer'; const SANITIZE_USER_FUNC_NOT_EXISTS = 'User function given to the sanitizer has not been found'; const SANITIZE_USER_FUNC_PARAMS_NOT_ARRAY = 'User function parameters given to the sanitizer must be an array'; } /**
  • class formCheckerMessages
  • The factory chosing correct messages localization class
*
  • /
class formCheckerMessages { /**
  • public static function factory
  • factory building the correct localized formCheckerMessages class through a ReflectionClass object
*
  • @param string $loc : country alpha 3 code
  • @return ReflectionClass object
  • /
public static function factory ($loc) { if (false === class_exists ('formCheckerMessages'.$loc)) { throw new formCheckerException (formCheckerException::CLASS_LOC_NOT_EXISTS); } $sClass = 'formCheckerMessages'.$loc; return new ReflectionClass ($sClass); } } /**
  • abstract class validateGen
  • the parent of all validateZZZ classes
  • defines common methods and properties
*
  • /
abstract class validateGen { /**
  • protected sName
  • user defined name given to the input (used for the messages)
*
  • @var string
  • /
protected $sName = null; /**
  • protected static sLocClass
  • used to store a ReflectionClass object pointing on the messages localization class
*
  • @var ReflectionClass
  • /
protected static $sLocClass = null; /**
  • private static sLoc
  • used to store current localization code and check if there is any change
*
  • @var string
  • /
private static $sLoc = null; /**
  • private function isEmpty
  • test if a given input is empty or not
*
  • @param string $mString : the input
  • @param boolean $bMandatory : is the input mandatory or not (if not, it can be empty)
  • @return boolean true if not empty, false if empty AND mandatory, -1 if empty AND NOT mandatory
  • /
private function isEmpty ($mString, $bMandatory) { if (empty ($mString)) { if (true === $bMandatory) { throw new formCheckerException (str_replace ('{__INPUT__}', $this -> sName, self::$sLocClass -> getConstant('INPUT_EMPTY'))); } return -1; } return true; } /**
  • protected static function isInt
  • checks if the given parameter is an integer
*
  • @param int $iNum
  • @return boolean tue if $iNum is an integer (throw an exception if not)
  • /
protected static function isInt ($iNum) { if (!is_int ($iNum)) { throw new formCheckerException (formCheckerException::FILTER_MUST_BE_INT); } return true; } /**
  • private function assign
  • just assigns properties and instanciate the ReflectionClass via the formCheckerMessages::factory () method
*
  • @param string $sName : name given to the input
  • @param string $loc : country alpha 3 code
  • /
private function assign ($sName, $loc) { $this -> sName = $sName; if ($loc !== self::$sLoc) { self::$sLoc = $loc; self::$sLocClass = formCheckerMessages::factory ($loc); } } /**
  • protected static function validateMinLength
  • checks if the input length matches the minimum required length
*
  • @param string $mString : the input
  • @param string $sName : user defined name for the data
  • @param int $iMinLength : minimum length
  • @return boolean true if the input length is greater or equal to the minimum length, false if not
  • /
protected static function validateMinLength($mString, $sName, $iMinLength) { if (true === self::isInt ($iMinLength)) { if (strlen ($mString) < $iMinLength) { throw new formCheckerException (str_replace (array ('{__INPUT__}', '{__MIN_LENGTH__}'), array ($sName, $iMinLength), self::$sLocClass -> getConstant ('INPUT_NOT_IN_MIN_LENGTH'))); } return true; } return false; } /**
  • protected static function validateMaxLength
  • checks if the input length matches the maximum required length
*
  • @param string $mString : the input
  • @param string $sName : user defined name for the data
  • @param int $iMaxLength : maximum length
  • @return boolean true if the input length is lesser or equal to the maximum length, false if not
  • /
protected static function validateMaxLength($mString, $sName, $iMaxLength) { if (true === self::isInt ($iMaxLength)) { if (strlen ($mString) > $iMaxLength) { throw new formCheckerException (str_replace (array ('{__INPUT__}', '{__MAX_LENGTH__}'), array ($sName, $iMaxLength), self::$sLocClass -> getConstant ('INPUT_NOT_IN_MAX_LENGTH'))); } return true; } return false; } /**
  • protected static function validateStrictLength
  • checks if the input has the mandatory strict length
*
  • @param string $mString : the input
  • @param string $sName : user defined name for the data
  • @param int $iStrictLength : strict length
  • @return boolean true if the input length is equal to the mandaotry strict length, false if not
  • /
protected static function validateStrictLength($mString, $sName, $iStrictLength) { if (true === self::isInt ($iStrictLength)) { if (strlen ($mString) !== $iStrictLength) { throw new formCheckerException (str_replace (array ('{__INPUT__}', '{__STRICT_LENGTH__}'), array ($sName, $iStrictLength), self::$sLocClass -> getConstant ('INPUT_NOT_IN_STRICT_LENGTH'))); } return true; } return false; } /**
  • protected static function validateStartsWith
  • checks if the input starts with each values in a given array
*
  • @param string $mString : the input
  • @param string $sName : user defined name for the data
  • @param array $aStarts : array of values
  • @return boolean true if the input starts with at least one of the values, false if not.
  • /
protected static function validateStartsWith ($mString, $sName, $aStarts) { $bRes = false; if (!is_array ($aStarts)) { throw new formCheckerException (formCheckerException::FILTER_NOT_ARRAY); } foreach ($aStarts as $mVal) { if (substr ($mString, 0, strlen ($mVal)) === $mVal) { $bRes = true; } } if (false === $bRes) { throw new formCheckerException (str_replace (array ('{__INPUT__}', '{__START__}'), array ($sName, implode (',', $aStarts)), self::$sLocClass -> getConstant ('INPUT_STARTS_WITH'))); } return $bRes; } /**
  • protected static function validateStartsWith
  • checks if the input does not start with each values in a given array
*
  • @param string $mString : the input
  • @param string $sName : user defined name for the data
  • @param array $aStarts : array of values
  • @return boolean false if the input starts with at least one of the values, true if not.
  • /
protected static function validateStartsWithout ($mString, $sName, $aStarts) { $bRes = true; if (!is_array ($aStarts)) { throw new formCheckerException (formCheckerException::FILTER_NOT_ARRAY); } foreach ($aStarts as $mVal) { if (substr ($mString, 0, strlen ($mVal)) === $mVal) { $bRes = false; break; } } if (false === $bRes) { throw new formCheckerException (str_replace (array ('{__INPUT__}', '{__START__}'), array ($sName, implode (',', $aStarts)), self::$sLocClass -> getConstant ('INPUT_DONOT_START_WITH'))); } return $bRes; } /**
  • protected static function hasForbidden
  • checks if the input is equal to one of the forbidden values
*
  • @param string $mString : the input
  • @param string or array $mForbidden : string or array of forbidden values
  • @return boolean false if the input is equal to one of the forbidden values, true if not
  • /
protected static function hasForbidden ($mString, $mForbidden) { if (is_array ($mForbidden)) { if (in_array ($mString, $mForbidden)) { throw new formCheckerException (str_replace ('{__FORBIDDEN__}', $mForbidden[array_search($mString, $mForbidden)], self::$sLocClass -> getConstant ('INPUT_FORBIDDEN'))); } } else { if ($mForbidden === $mString) { throw new formCheckerException (str_replace ('{__FORBIDDEN__}',$mForbidden, self::$sLocClass -> getConstant ('INPUT_FORBIDDEN'))); } } return true; } /**
  • protected static function hasAllowed
  • checks if the input is equal to one of the allowed (and mandatory) values
*
  • @param string $mString : the input
  • @param string or array $mForbidden : string or array of forbidden values
  • @return boolean false if the input is equal to one of the forbidden values, true if not
  • /
protected static function hasAllowed ($mString, $mAllowed) { if (is_array ($mAllowed)) { if (!in_array ($mString, $mAllowed)) { throw new formCheckerException (self::$sLocClass -> getConstant ('INPUT_ALLOWED')); } } else { if ($mAllowed !== $mString) { throw new formCheckerException (self::$sLocClass -> getConstant ('INPUT_ALLOWED')); } } return true; } /**
  • protected function validate
  • validation method, calls the required check methods
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not, -1 if input is empty
  • /
protected function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { $this -> assign ($sName, $loc); if (false === ($bRes = $this -> isEmpty ($mString, $bMandatory))) { return false; } elseif (true === $bRes) { if (isset ($aOptions['forbidden'])) { if (false === self::hasForbidden ($mString, $aOptions['forbidden'])) { return false; } } if (isset ($aOptions['allowed'])) { if (false === self::hasAllowed ($mString, $aOptions['allowed'])) { return false; } } if (isset ($aOptions['min_length']) && is_int ($aOptions['min_length'])) { if (false === self::validateMinLength ($mString, $this -> sName, $aOptions['min_length'])) { return false; } } if (isset ($aOptions['max_length']) && is_int ($aOptions['max_length'])) { if (false === self::validateMaxLength ($mString, $this -> sName, $aOptions['max_length'])) { return false; } } if (isset ($aOptions['strict_length']) && is_int ($aOptions['strict_length'])) { if (false === self::validateStrictLength ($mString, $this -> sName, $aOptions['strict_length'])) { return false; } } if (isset ($aOptions['starting_with'])) { if (false === self::validateStartsWith ($mString, $this -> sName, $aOptions['starting_with'])) { return false; } } if (isset ($aOptions['not_starting_with'])) { if (false === self::validateStartsWithout ($mString, $this -> sName, $aOptions['not_starting_with'])) { return false; } } } else { return -1; } return true; } } /**
  • class validateText extends validateGen
  • basic text checker class
*
  • /
class validateText extends validateGen { /**
  • protected function validate
  • validation method, calls the required check methods and prior to them, calls parent validate method
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not
  • /
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { if (false === parent::validate ($mString, $sName, $loc, $aOptions, $bMandatory)) { return false; } return true; } } /**
  • class validateEmail extends validateGen
  • emails checker class
*
  • /
class validateEmail extends validateGen { /**
  • protected function validate
  • validation method, checks if the input is an email and prior to it, calls parent validate method
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not
  • /
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { if (false === ($bRes = parent::validate ($mString, $sName, $loc, $aOptions, $bMandatory))) { return false; } elseif (true === $bRes){ if (!preg_match ('`^:alnum:([-_.]?:alnum:)*@:alnum:([-.]?:alnum:)*\.([a-z]{2,4})$`', $mString)) { throw new formCheckerException (self::$sLocClass -> getConstant ('EMAIL_INVALID')); } } return true; } } /**
  • class validateUrl extends validateGen
  • url checker class
*
  • /
class validateUrl extends validateGen { /**
  • protected function validate
  • validation method, checks if the input is an url and prior to it, calls parent validate method
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not
  • /
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { if (false === ($bRes = parent::validate ($mString, $sName, $loc, $aOptions, $bMandatory))) { return false; } elseif (true === $bRes){ if (!preg_match ('`((?:https?|ftp)://\S+:alnum:/?)`si', $mString) && !preg_match ('`((?<!//)(www\.\S+:alnum:/?))`si', $mString)) { throw new formCheckerException (self::$sLocClass -> getConstant ('URL_INVALID')); } } return true; } } /**
  • class validateRegExp extends validateGen
  • user defined regexp checker class
*
  • /
class validateRegExp extends validateGen { /**
  • protected function validate
  • validation method, checks if the input matches the user defined regexp and prior to it, calls parent validate method
  • needs a mandaotory option at least : $aOptions['regexp'] = user defined regexp pattern
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not
  • /
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { if (false === ($bRes = parent::validate ($mString, $sName, $loc, $aOptions, $bMandatory))) { return false; } elseif (true === $bRes){ if (!isset ($aOptions['regexp'])) { throw new formCheckerException (formCheckerException::NO_REGEXP); } $bReg = @preg_match ($aOptions['regexp'], $mString); if ((function_exists ('preg_last_error') && @preg_last_error() !== PREG_NO_ERROR) || false === $bReg) { throw new formCheckerException (formCheckerException::BAD_REGEXP); } elseif (0 === $bReg) { throw new formCheckerException (str_replace ('{__INPUT__}', $this -> sName, self::$sLocClass -> getConstant ('REGEXP_FOUND_NOT_MATCH'))); } } return true; } } /**
  • class validateUserFunc extends validateGen
  • user defined function checker class
*
  • /
class validateUserFunc extends validateGen { /**
  • protected function validate
  • validation method, checks if the input matches the user defined function and prior to it, calls parent validate method
  • needs a mandatory option at least : $aOptions['user_func'] = name of the user function
  • you can add parameters via the optional option $aOptions['user_func_params']. This must be an array with all the parameters.
  • Please note the method will add at the end of the array of options the input $mString.
  • So, your user function MUST implements at least 1 parameter (the input), and if there are others, the input parameter MUST be the last parameter
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not
  • /
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { if (false === ($bRes = parent::validate ($mString, $sName, $loc, $aOptions, $bMandatory))) { return false; } elseif (true === $bRes){ if (!isset ($aOptions['user_func'])) { throw new formCheckerException (formCheckerException::NO_USER_FUNC); } if (isset ($aOptions['user_func_params']) && !is_array ($aOptions['user_func_params'])) { throw new formCheckerException (formCheckerException::USER_FUNC_PARAMS_NO_ARRAY); } $aOptions['user_func_params'][] = $mString; $bFunc = call_user_func_array ($aOptions['user_func'], $aOptions['user_func_params']); if (false === $bFunc) { throw new formCheckerException (str_replace (array ('{__INPUT__}', '{__FUNC__}'), array ($this -> sName, $aOptions['user_func']), self::$sLocClass -> getConstant ('USER_FUNC_RETURNED_FALSE'))); } } return true; } } /**
  • class validateInt extends validateGen
  • integer checker class
*
  • /
class validateInt extends validateGen { /**
  • protected function validate
  • validation method, checks some specific numeric requirements and prior to them, calls parent validate method
*
  • @param string $mString : the input
  • @param string $sName : user defined name given to the input
  • @param string $loc : country alpha 3 code
  • @param array $aOptions : null if no option, array of options
  • @param boolean $bMandatory : true if the input is mandaotry, false if not
  • @return boolean true if the input successfully meets all the requirements, false if not
  • /
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) { if (false === ($bRes = parent::validate ($mString, $sName, $loc, $aOptions, $bMandatory))) { return false; } elseif (true === $bRes) { if (false === ctype_digit ($mString)) { throw new formCheckerException (str_replace ('{__NUMERIC__}', $this -> sName, self::$sLocClass -> getConstant ('NUMERIC_NOT_NUMERIC'))); } if (isset ($aOptions['min_range'])) { if (false === $this -> validateMinRange ($mString, $aOptions['min_range'])) { return false; } } if (isset ($aOptions['max_range'])) { if (false === $this -> validateMaxRange ($mString, $aOptions['max_range'])) { return false; } } } return true; } /**
  • private function validateMinRange
  • checks if the numeric input is greater or equal than the minimum range
*
  • @param string $mString : the input
  • @param int $iMinRange : minimum range
  • @return boolean if the input is greater or equal than the minimum range, false if not
  • /
private function validateMinRange ($mString, $iMinRange) { if (true === parent::isInt ($iMinRange)) { if ($mString < $iMinRange) { throw new formCheckerException (str_replace (array ('{__NUMERIC__}', '{__MIN_RANGE__}'), array ($this -> sName, $iMinRange), self::$sLocClass -> getConstant ('NUMERIC_NOT_IN_MIN_RANGE'))); } return true; } return false; } /**
  • private function validateMaxRange
  • checks if the numeric input is lesser or equal than the maximum range
*
  • @param string $mString : the input
  • @param int $iMaxRange : maximum range
  • @return boolean if the input is lesser or equal than the maximum range, false if not
  • /
private function validateMaxRange ($mString, $iMaxRange) { if (true === parent::isInt ($iMaxRange)) { if ($mString > $iMaxRange) { throw new formCheckerException (str_replace (array ('{__NUMERIC__}', '{__MAX_RANGE__}'), array ($this -> sName, $iMaxRange), self::$sLocClass -> getConstant ('NUMERIC_NOT_IN_MAX_RANGE'))); } return true; } return false; } } /**
  • class formChecker
  • only class to be called
  • uses ReflectionClass to call the correct validateZZZ class
*
  • /
class formChecker { /**
  • constants defining the allowed validation classes
*
  • /
const VALIDATE_EMAIL = 'validateEmail'; const VALIDATE_INT = 'validateInt'; const VALIDATE_TEXT = 'validateText'; const VALIDATE_URL = 'validateUrl'; const VALIDATE_REGEXP = 'validateRegExp'; const VALIDATE_USER_FUNC = 'validateUserFunc'; /**
  • public static aMsg
  • static property storing the messages returned by the validateZZZ classes (error messages)
  • key is the user defined name for the input, value being the error message
*
  • @var array
  • /
public static $aMsg = null; /**
  • private bValid
  • true if the form (all the input validated) is ok, false if there is at least one error among all the validation
*
  • @var boolean
  • /
private $bValid = true; /**
  • private loc
  • localization property, country alpha 3 code
*
  • @var string
  • /
private $loc = null; /**
  • public function __construct
  • constructor, sets some properties : localization, and reset aMsg array of error messages
*
  • @param string $loc
  • /
public function __construct ($loc = 'FRA') { self::$aMsg = null; $this -> loc = $loc; } /**
  • public function validate
  • call the validation type required, via ReflectionClass
  • sets the formChecker::bValid property to false if any error is detected on an input
*
  • @param string $mString : the input
  • @param string $sName : user defined name for the input
  • @param formChecker constant $cPattern : the validation type to be applied to this input
  • @param array $aOptions : null if not options, array of options on the other hand. default to null
  • @param boolean $bMandatory : true if the input must not be empty, false if not. default to true
  • @return unknown
  • /
public function validate ($mString, $sName, $cPattern, $aOptions = null, $bMandatory = true) { if (false === class_exists ($cPattern)) { throw new Exception (formCheckerException::CLASS_NOT_EXISTS); } $oReflect = new ReflectionClass($cPattern); $o = $oReflect -> newInstance (); try { $bRes = $o -> validate ($mString, $sName, $this -> loc, $aOptions, $bMandatory); } catch (Exception $e) { self::$aMsg[$sName] = $e -> getMessage (); $bRes = $this -> bValid = false; } return $bRes; } /**
  • public function sanitizeStr
  • sanitize a string, given an array of options :
  • addslashes => adds slashes...(default)
  • htmlentities => encode html entities (default)
  • urlencode => encode as en url
  • trim => apply a trim
  • mssqlEscape => escape quotes for mssql
*
  • @param string $mString : the input
  • @param array $aOptions : array of options
  • @return string
  • /
public function sanitizeStr ($mString, $aOptions = array ('addslashes', 'htmlentities')) { if (in_array ('addslashes', $aOptions)) { $mString = addslashes ($mString); } if (in_array ('htmlentities', $aOptions)) { $mString = htmlentities ($mString); } if (in_array ('urlencode', $aOptions)) { $mString = urlencode ($mString); } if (in_array ('trim', $aOptions)) { $mString = trim ($mString); } if (in_array ('mssqlEscape', $aOptions)) { $mString = str_replace ("'", "''", $mString); } return $mString; } /**
  • public function sanitizeInt
  • sanitize a variable (input, so should be a string) as an integer, given an array of options :
  • onlyInt => extract onnly the integer values in the variable
*
  • @param string $mString : the input
  • @param array $aOptions : array of options :
  • onlyInt => retrieve only integer characters
  • @return string
  • /
public function sanitizeInt ($mString, $aOptions = array ('onlyInt')) { if (in_array ('onlyInt', $aOptions)) { preg_match_all ('@([\d]+)+@', $mString, $aRes); if (!empty ($aRes[0])) { $mString = implode ($aRes[0]); } else { $mString = ''; } } return $mString; } /**
  • public function sanitizeUserFunc
  • sanitize a variable (input, so should be a string) as an integer, given a user function.
  • Same rule as the formChecker::VALIDATE_USER_FUNC pattern : the user defined function MUST have at least one parameters which is the input.
  • If there are more parameters, the input MUST be the last parameter.
*
  • @param string $mString : the input
  • @param array $aOptions : array of options
  • @return string
  • /
public function sanitizeUserFunc ($mString, $aOptions = array ('user_func' => '', 'user_func_params' => array ())) { if (!isset ($aOptions['user_func'])) { throw new formCheckerException (formCheckerException::SANITIZE_NO_USER_FUNC); } if (!function_exists ($aOptions['user_func'])) { throw new formCheckerException (formCheckerException::SANITIZE_USER_FUNC_NOT_EXISTS); } if (isset ($aOptions['user_func_params']) && !is_array ($aOptions['user_func_params'])) { throw new formCheckerException (formCheckerException::SANITIZE_USER_FUNC_PARAMS_NOT_ARRAY); } $aOptions['user_func_params'][] = $mString; $mString = call_user_func_array ($aOptions['user_func'], $aOptions['user_func_params']); return $mString; } /**
  • public function isValid
  • returns formChecker::bValid property
  • it will be set to true if every input successfully passed the validation, false if one of them failed
*
  • @return unknown
  • /
public function isValid () { return $this -> bValid; } } /**
  • Example
  • /
/**
  • declarations.
  • of course, should be user input values like POST or GET
  • /
$sEmail = 'moi@moi.com'; $sCp = '00345'; $sNom =''; $sPrenom = ''; $sTel = '04-23-45-67-89'; $sUrl = 'http://monsite.com'; $sToBeSanitized = 'must be uppercase'; /**
  • some user defined function to be used for the formchecker::VALIDATE_USER_FUNC pattern
  • /
function myFunc ($sNeedle, $sHaystack) { if (false !== strpos ($sHaystack, $sNeedle)) { return true; } return false; } /**
  • some user defined function to be used for the formchecker::sanitizeUserFunc method
  • /
function mySanitizer ($mString) { return strtoupper ($mString); } /**
  • French test
  • /
try { /**
  • instanciation of the formChecker
  • /
$iStart = microtime (true); $oChecker = new formChecker; /**
  • just to show sanitization : we remove the '-' from the phone number
  • /
$sSanitizedTel = $oChecker -> sanitizeInt ($sTel); /**
  • just to show sanitization via user defined function : we just return the uppercase version of the string
  • /
$sToBeSanitized = $oChecker -> sanitizeUserFunc ($sToBeSanitized, array ('user_func' => 'mySanitizer')); echo '<br />SANITIZED : ', $sToBeSanitized, '<br />'; /**
  • some validations
  • /
/**
  • using the email validation, and we forbid the use of the 'moi@moi.com'
  • /
if (false === $oChecker -> validate ($sEmail, 'email', formChecker::VALIDATE_EMAIL, array ('forbidden' => 'moi@moi.com'))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using the integer validation : the French zip code should broadly be only integers, strictly 5 in length, and cannot start with 00
  • /
if (false === $oChecker -> validate ($sCp, 'code postal', formChecker::VALIDATE_INT, array ('strict_length' => 5, 'not_starting_with' => array ('00')))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using the basic text validation, nothing special except that the input must not be empty (default valus is true for the mandatory parameter)
  • /
if (false === $oChecker -> validate ($sNom, 'nom', formChecker::VALIDATE_TEXT)) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using again the basic text validation, but the first name is not mandatory (see the last parameter : false); note that mandatory being the last parameter, and
  • as we do not need any option, wu must pass a null value instead of the array of options
  • /
if (false === $oChecker -> validate ($sPrenom, 'prénom', formChecker::VALIDATE_TEXT, null, false)) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using the integer validation for the sanitized phone number. Broadly, the French phone number should be 10 cahracters long, only integers (that's why we sanitied it),
  • and should start with 01, 02, 03, 04, 05, 06 or 08
  • /
if (false === $oChecker -> validate ($sSanitizedTel, 'telephone', formChecker::VALIDATE_INT, array ('strict_length' => 10, 'starting_with' => array ('01', '02', '03', '04', '05', '06', '08')))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using the URL validation
  • /
if (false === $oChecker -> validate ($sUrl, 'url', formChecker::VALIDATE_URL)) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using the regexp validation (ok, my regexp is stupid...)
  • /
if (false === $oChecker -> validate ($sUrl, 'url2', formChecker::VALIDATE_REGEXP, array ('regexp' => '@(doli)@'))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • using the user function validation (ok, my function is stupid...again!)
  • here, my function will check if the string 'da' is in the email string ('moi@moi.com'). It is not, obviously.
  • /
if (false === $oChecker -> validate ($sEmail, 'url3', formChecker::VALIDATE_USER_FUNC, array ('user_func' => 'myFunc', 'user_func_params' => array ('da')))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } /**
  • if there is any error, formchecker::isValid () returns false, else it returns true.
  • If false, we check the error messages.
  • /
if (false === $oChecker -> isValid ()) { echo '<pre>',print_r (formChecker::$aMsg), '</pre>'; } $iStop = microtime (true); echo '<p>ELAPSED : ',$iStop - $iStart,'</p>'; } catch (Exception $e) { echo $e -> getMessage (); } /**
  • English test (same explanations as for the French one)
  • /
try { $oChecker = new formChecker ('ENG'); $sSanitizedTel = $oChecker -> sanitizeInt ($sTel); if (false === $oChecker -> validate ($sEmail, 'email', formChecker::VALIDATE_EMAIL, array ('forbidden' => 'moi@moi.com'))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sCp, 'zip code', formChecker::VALIDATE_INT, array ('strict_length' => 5, 'not_starting_with' => array ('00')))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sNom, 'last name', formChecker::VALIDATE_TEXT)) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sPrenom, 'first name', formChecker::VALIDATE_TEXT, null, false)) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sSanitizedTel, 'phone number', formChecker::VALIDATE_INT, array ('strict_length' => 10, 'starting_with' => array ('01', '02', '03', '04', '05', '06', '08')))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sUrl, 'url', formChecker::VALIDATE_URL)) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sUrl, 'url2', formChecker::VALIDATE_REGEXP, array ('regexp' => '@(doli)@'))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> validate ($sEmail, 'url3', formChecker::VALIDATE_USER_FUNC, array ('user_func' => 'myFunc', 'user_func_params' => array ('da')))) { echo 'FALSE<br />'; } else { echo 'OK<br />'; } if (false === $oChecker -> isValid ()) { echo '<pre>',print_r (formChecker::$aMsg), '</pre>'; } } catch (Exception $e) { echo $e -> getMessage (); } ?>

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

FhX
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3 -
"# *
# * @return unknown
# */
# public function isValid () {
# return $this -> bValid;
# }"

C'est ca oui ...
@return unknown sur une variable boolean ? ;)


J'aime bien pour ma part (apparament, t'a tué tout le monde, personne vient poster :p)...
Juste que c'est un poil trop lourd je trouve.

Surtout au niveau du :
# $oReflect = new ReflectionClass($cPattern);
# $o = $oReflect -> newInstance ();

Parce que tu vas faire une instance de validateUrl par exemple et qui va récupérer TOUTES les méthodes de ta classe abstraite, et puis une autre instance de validateInt par exemple et qui va elle aussi récupérer TOUTES les méthodes de ta classe abstraite INDEPENDEMENT de l'instance "validateUrl".

J'imagine la duplication de code en mémoire lorsque tu instancies toutes les classes filles :)

Je pense que certaines méthodes dans ta classe abstraite doivent passer en statique car elles sont communes à toutes les instances au final... y'a pas une grande spécificité entre les instances.

Si je peux te donner un conseil, c'est celui la. Passer les méthodes en statiques (ca va t'obliger à revoir un peu le code par contre ^^) et puis je pense que c'est tout.
Si, y'a peut être autre chose, mais ca on verra plus tard, jviens de me lever et j'ai faim ^^


Ah vi, fait un bench de ton exemple avant de mettre quoi que ce soit en statique (donc tes classes en l'état), et essaye après. Normalement, tu récupères un peu de ces precieuses millisecondes :p (et surtout un peu de mémoire aussi ^^).

Cependant, le concept est pas mal en lui même, tout est fonctionnel... mais peut être un peu dur à comprendre du premier coup pour quelqu'un qui pige quedalle (surtout au niveau des arguments de ->validate() :p)

Si j'ai le temps, je t'expose mon autre théorie dans la journée... tu vas voir ^^
FhX
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3 -
Alors voila.
Après avoir pris ma douche et tout et tout... voila comment j'aurais fait :p

*****
*****

Je vais prendre ta classe validateUrl :

class validateUrl extends validateGen {
private $mString;
private $sName;
private $aOptions;
private $bMandatory;

public function __construct($mString, $sName, $aOptions=NULL, $bMandatory=TRUE) {
$this->mString = $mString...; // etc...
}

public function validate() {
if ( !parent::validate() ) {
return false;
} else {
// if pregmatch...()
}
}
}

// Puis dans formChecker::validate();
class formchecker {

public function validate ($oObject) {
if (false ($bRes $oObject -> validate () ) ) {
$this -> bValid = false;
}
return $bRes;
}

}

// et dans ton exemple :
if (false === $oChecker -> validate (new validateUrl($sUrl, 'url') )) {
// etc...
} else {
// etc...
}



Voila un peu comment je voyais ca :)
Dans la théorie, c'est censé fonctionner... ca nécessite de remanier un peu le code dans la classe abstraite mais voila à peu près les grandes lignes :)
malalam
Messages postés
10844
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
Donc après tests, pour l'instant, c'est plus lent de passer les méthodes en statique. Alors que je suis plutôt d'accord avec toi dans l'absolu lol.
Par contre, je vais voir pour tes exceptions...en effet, et gérer ça en dehors avec un bloc try catch.
Pour le reste on verra! Je vais voir ce que je peux faire par rapport à la réflexion...le problème à la base était de récupérer mes constantes. Evidemment, si je m'en passe...je peux aussi me passer de la réflexion. mais j'aimais bien l'idée des constantes de classe pour appeler les masques lol.
kankrelune
Messages postés
1305
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015
-
Pareil que FhX... je trouve ça assez lourd... je ne vois pas l'interet de faire autant de class fille pour une méthode à chaque fois... je pense que tout pourrais être regroupé en une ou deux class... mais c'est un choix tu as peut être des raisons pour... .. .

Sinon... dans les classes filles de validateGen

if (false ($bRes parent::validate (... .. .))) {
return false;
} elseif (true === $bRes)

$bRes ne peut être que booléen il me semble... alors pourquoi un double test... .. ?

@ tchaOo°

ps : bonne année à vous deux... .. .
kankrelune
Messages postés
1305
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015
-
Ah merde... j'avais pas vu le -1 en retour... désolé... .. .

@ tchaOo°

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.