begin process at 2012 05 27 17:58:23
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Formulaires

 > [PHP5] FORMCHECKER : VALIDATION DE SAISIES UTILISATEUR

[PHP5] FORMCHECKER : VALIDATION DE SAISIES UTILISATEUR


 Information sur la source

Note :
10 / 10 - par 4 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Formulaires Classé sous :vérifications, données, utilisateur, formulaire, validation Niveau :Initié Date de création :04/01/2007 Date de mise à jour :08/01/2007 14:48:19 Vu / téléchargé :7 456 / 732

Auteur : malalam

Ecrire un message privé
Site perso
Commentaire sur cette source (23)
Ajouter un commentaire et/ou une note

 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

  • <?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 ();
  • }
  • ?>
<?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 ();
}
?>


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

04 janvier 2007 16:14:55 :
Ajout de quelques méthodes et classes.
04 janvier 2007 17:35:13 :
modification mineure
04 janvier 2007 17:48:35 :
Bug mineur débusqué + ajout d'une option dans la méthode formChecker::sanitizeStr (échappement des apostrophes pour mssql)
08 janvier 2007 09:22:41 :
Optimisations
08 janvier 2007 14:48:20 :
Ajout de doc et d'une option (allowed)

 Sources du même auteur

Source avec Zip ASTUCES/HACK PHP
SQUELETTE DE GESTION DES DROITS
[PHP 5.1] CLASS STRING : NOUVEL EXEMPLE SUR LA SPL
Source avec Zip Source avec une capture [PHP 5.1] PHOTOPHOP (PHPDRAW 2)
Source avec Zip Source avec une capture [PHP5.1] O-LOC : CLASSE ET BACKOFFICE D'INTERNATIONALISATION

 Sources de la même categorie

Source avec Zip Source avec une capture VALIDATEUR DE FORMULAIRE par Reldan
Source avec Zip SUIVI SERVICE CLIENT PHP par hige52
Source avec Zip POO - FORMULAIRE NEWSLETTER PHP - PROFESSEUR-PHP.COM par mtrix000
Source avec Zip Source avec une capture SELECTEUR DE NOTE par Reldan
Source avec Zip Source avec une capture ESPACE MEMBRE , AVEC CASE OPTIONNEL , SANS MYSQL par sartoz

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture VALIDATEUR DE FORMULAIRE par Reldan
Source avec Zip FORMULAIRE D'INSCRIPTION par lelioua
FORM, ORM POUR FORMULAIRE par choy
CLASSE FORM, GESTION DE VALIDATION POUR FORMULAIRE par phpAnonyme
Source avec Zip Source avec une capture FORMOL, PACKAGE PHP5 DE GESTION DE FORMULAIRES XHTML par tmaziere

Commentaires et avis

Commentaire de FhX le 05/01/2007 15:46:18

"#      *
#      * @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 ^^

Commentaire de FhX le 05/01/2007 16:39:00

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 :)

Commentaire de malalam le 05/01/2007 17:32:30 administrateur CS

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.

Commentaire de kankrelune le 05/01/2007 17:41:50

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... .. .

Commentaire de kankrelune le 05/01/2007 17:46:10

Ah merde... j'avais pas vu le -1 en retour... désolé... .. .

@ tchaOo°

Commentaire de malalam le 05/01/2007 18:38:28 administrateur CS

Oui c'est à cause des données pouvant être vides ET Valides, ou vides ET invalides.
Du coup j'ai 3 cas dans la méthode validate de la classe mère. Mais ça ne me plait pas non plus...je n'ai juste pas trouvé d'autre moyen.

En fait l'intérêt de scinder autant est que si jamais je n'ai que une donnée de type texte à vérifier (ou 2), je ne récupère pas des méthodes inutiles dédiées aux emails, url, type numériques etc...

De plus, cela facilite l'évolution des classes, et la création de nouvelles classes. Le processus est implémenté, et ajouter un masque, par exemple, demande juste l'implémentation d'une classe fille. Et tout le reste est déjà géré.

Lors du dév de ce package, ça s'est révélé très efficace par rapport à ma méthode d'avant qui regroupait tout en une classe (ou presque).

Ca, je garde mes petites classes filles lol ;-)

Par contre j'optimise (bon là ce n'est pas flagrant, j'ai perdu un peu de rapidité...mais y a des exceptions lol et c'est encore plus facilement gérable...mais j'espère arriver à plus optimisé).

Et au niveau de l'utilisation en elle-même, une fois qu'on a compris comment se faisait les appels de masque avec les options (ça ok, c'est pas évident..mais en même temps c'est plutôt puissant), c'est très facile à implémenter dans un code.

mais je suis d'accord, c'est loin d'être parfait. En fait, je vais approfondir le côté Reflection, parce que je pense qu'on peut gagner du temps avec (j'en suis pas certain non plus hein...).

Commentaire de FhX le 05/01/2007 18:53:30

Aller, dis leur que l'optimisation à la FhX fonctionne à merveille :p
Pour  if ( !isset(self::LocClass) ) self::LocClass = formCheckerMessages::factory ($loc); j'avais oublié de te dire que étant donné qu'on appèlle la même classe à chaque fois, ca fait une instance à chaque appel :p Bah vi, c'est un Singleton ca... :p

Et voila :) Chui content d'avoir eu raison sur le statique... j'ai eu peur quand tu m'as dit que ca prenait plus de temps :o

Commentaire de malalam le 05/01/2007 19:35:27 administrateur CS

je sais, lol, je suis passé par un stockage de la variable $loc, en statique.
Je regarde ma propriété (validateGen::$sloc) est différente du paramètre passé, si oui, j'instancie sLocClass, sinon non. Comme ça on peut changer de languer au sein du même script (ce qui est, convenons-en, assez peu probable, mais bon...).

Ben en fait là, je suis tjrs plus lent qu'avec la classe originale.
Mais c'est plus joli ;-) (je mettrai à jour la semaine prochaine).
J'ai mis, donc : bcp de méthodes en statique, la propriété sLocClass, j'ai passé en privée quelques méthodes aussi, et j'ai foutu les exceptions à la place des formChecker::$aMsg...bla bla, que j'ai juste mis dans le catch.

Le code est aussi un peu plus court.

Reste à retrouver la vitesse d'antan lol...mais on verra. Suis passé de 0.00086... à 0.00095 en moyenne, au final.
Donc je perds 0.0001 seconde sur ce petit script (la version française uniquement, c'est ce que j'ai benché). Pas énorme de toute manière.

Donc oui, l'optimisation à la FhX a fonctionné à merveille ;-)

Commentaire de FhX le 05/01/2007 21:34:41

Yes ! :p

Fait envoyer le nouveau code maintenant... doit y avoir encore des trucs à parfaire :D

M'est avis que tu seras toujours un peu plus lent que ton bouzin d'avant ... quoi que :/
Jvais m'y pencher demain ^^


Envoi le nouveau code quoi !! Aller ! :p

Commentaire de malalam le 06/01/2007 11:02:16 administrateur CS

je peux pas, il est à mon taf, pas chez moi, et le week-end, suis chez moi ;-)
Donc ce sera lundi :-)

Commentaire de FhX le 07/01/2007 15:54:45

Mince, tu dors pas à ton taff ??

T'es pas un vrai Geek du PHP Mala... rahhhh :p

Commentaire de malalam le 08/01/2007 09:27:08 administrateur CS

Nan, po un vrai... ;-)

C't'en ligne :-)

Commentaire de FhX le 09/01/2007 20:37:58

Je me demande pourquoi c'est encore la ca :
FormChecker::validate();

public function validate ($mString, $sName, $cPattern, $aOptions = null, $bMandatory = true);

Alors..., je décortique :
$mString, c'est la chaine à traiter.
$sName, c'est le nom que tu vas donner à ta chaine (pourquoi ? va savoir :s)
$cPattern, c'est le type de classe que tu vas instancier (hu ? )
$aOptions, ce sont les options de ta classe (la aussi... hu ?)
$bMandatory, encore une autre option un peu spécial.

Orienté objet, y'a comme une erreur la dedand. Tu fais passer en paramètre le type de classe ainsi que les options séparément ?
Pourquoi tu n'as pas retenu mon idée d'origine, c'est à dire de faire :

public function validate ($oObject, $bMandatory = true);

Avec :
$oObject, la classe d'objet instanciée.
$bMandatory, ton option "spéciale".
?

Ton constructeur d'objet devra ressembler à ca :
public function __construct($mString, $aOptions=NULL);

Et pour appeler ta méthode formchecker::validate(), suffit de faire :
return ( $oFormChecker->validate( new validateInt(95000) ) ) ? TRUE : FALSE;

C'est pas plus facile à lire ? A coder aussi je crois non ?
C'est peut être plus lourd niveau temps d'exécution alors ?

Parce qu'après, le code de FormChecker::validate il ressemble à ca :
public function validate($oObject, $bMandatory=TRUE) {
  try {
    $bRes = $oObject -> validate ($bMandatory);
  } catch (Exception $e) {
    self::$aMsg[$sName] = $e -> getMessage ();
    $bRes = $this -> bValid = false;
  }
return $bRes;
}
      

En plus, je suis sur que tu peux te passer de cette classe formchecker... Mais c'est une autre histoire.

Tu peux essayer ma méthode pour voir ? Pas trop le temps en ce moment pour te pondre tout le code mais jvais essayer de le faire à ma sauce et faudra juste que tu me le bench par contre :p
    

Commentaire de FhX le 12/01/2007 19:19:57

Jvois que ca emballe pas :p

Commentaire de malalam le 12/01/2007 19:56:43 administrateur CS

si si, 'scuse, j'ai pas du tout eu le temps de me repencher dessus cette semaine.
Verrai ça la semaine prochaine (si tout va bien lol).

Commentaire de Epoc22 le 24/01/2007 17:03:29

Salut,
c'est un peu chiant la doc est en anglais...

Commentaire de FhX le 24/01/2007 18:12:01

Tu verras par toi même que beaucoup de code en programmation sont en anglais.

C'est comme ca, faut t'y faire :)

Commentaire de malalam le 24/01/2007 19:18:31 administrateur CS

La semaine prochaine...heu... ;-)

Epoc22 => je ne partage pas forcément QUE pour des français...je ne travaille pas non plus forcément QU'AVEC des français...
Donc, je documente en anglais.
Et ça, même la semaine prochaîne, je ne le changerai pas ;-)

Ceci dit, tu noteras que dans le zip, il y a une documentation sur l'utilisation en français, hein...;-)

Commentaire de Epoc22 le 25/01/2007 13:13:12

Je n'ai pas dit que j'était un merde an anglais (au contraire) mais bon... ici c'est un site d'échanges francophone.
Voila @

Commentaire de Epoc22 le 27/01/2007 11:22:23

malalam tu fait de ces trucs de fou... hallucinant

Commentaire de malalam le 27/01/2007 15:24:53 administrateur CS

C'est un compliment...? lol ?
Pour revenir à l'anglais, le truc c'est que je commente mes codes en anglais. Je me vois mal faire 2 fichiers, 1 avec le code commenté en anglais et 1 avec le code commenté en français, spécialement pour CS.
L'anglais que j'utilise est super basique, bourré de fautes parce que je commente généralement très vite sans faire particulièrement attention, et donc à priori compréhensible même si on est mauvais en anglais ;-)

Commentaire de DiGhan le 11/07/2007 23:45:33

Cette source est réellement bien menée ! La gestion des erreurs, le process d'appel à validate(), autant de choses qui en font un excellent outil.
En bref, du trés bon travail !

Commentaire de Phelim le 01/03/2008 21:30:25 10/10

C'est une source très utile.
C'est extrêmement complet et efficace.

Par contre, je ne vois pas forcément l'intérêt des fonctions d'utilisateurs.
Il est facile et plus propre de réaliser d'autres classes de validation ou d'étendre les class existantes.

Etant donné que tout est bon ( convention de codages, documentation, modularité ), je donne la note maximal a cette source

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Formulaire sélection base de données [ par fredo35m ] Bonjour,d&#233;sol&#233; de revenir sur mon probl&#232;me de formulaire mais il me fait des choses bizarres. Alors voil&#224;, je r&#233;sume, j'ai un Validation Formulaire [ par kiboumz ] Bonjour, J'ai cr&#233;e un formulaire duquel j'envoie des donn&#233;es vers une base de donn&#233;es, cependant j'aimerais pouvoir valider mes donn& Formulaire php qui envois les données sur le poste de travail [ par Rikki ] Bonjour ç tous,j'ai une demande un peu particulière.Je voudrais faire un formulaire en php afin que les utilisateurs puissent rapporter les problèmes Comment afficher données issues de la bdd (et les conserver selon critères utilisateur) [ par lolymeupy ] Bonjour, j'essaye de créer un site mais j'ai une question en suspend que je n'arrive pas à résoudre (malgré de nombreuses recherches en tutos et aut Formulaire en PHP Mysql [ par YvanP ] J'ai un site de sport automobile en PHP avec une base de données Mysql.  http://www.onroule.caJe fais un Pool de Formule 1 dans le forum.  Toutefois a Convertir le texte en Image pour la validation du formulaire [ par alvinemambele ] Salut!je cherche de l'aide!j'ai fais un formulaire dans mon web site et je veux qu'avant de l'envoyer que l'utilisateur introduise le code de validati Validation d'un formulaire et execution PHP [ par faty86 ] Salut tout le monde ,Voila, je veux verifier la valideite des donnees saisies dans un formulaire avant de les envoyer. J'ai fait une fonction Formveri Insérer les données d'un formulaire PHP dans un PDF ou un WORD [ par nerault ] Bonjour,Je suis webmaster d'une association en train de se monter et dans le cadre des activités administratives de l'asso, nous avons créer des docum Rennomer un fichier en fonction d'un formulaire [ par mymydu42 ] Bonjour, J'aimerais un peu d'aide, je voudrai créer un script qui renomme des fichiers uploader avec ce que l'utilisateur à rempli dans le formulaire. Rediriger les données d'un formulaire vers une fenêtre d'authentification htaccess [ par niakwel ] Bonsoir,je suis plutot débutant en php et je réalise un site intranet pour ma boite (je suis en alternance).Je voudrais mettre une zone sur la page d'


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,749 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales