IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

POO - setter et validation


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut POO - setter et validation
    Bonjour,

    je me suis mis à la POO.

    J'ai lu et relu pour beaucouuup d'articles et visionné des tuto pour me familiariser..

    je pense avoir compris le paradigme. Cependant je bloque sur un point.

    En reprenant le principe d'encapsulation, je dois passer par des setters pour modifier les valeurs. ok

    Sauf erreur de ma part, le contrôle de l'intégrité de mes attributs de classe se fait par les setters.

    Le contrôle sur des chaînes de caractères et nombres sont un peu près compris.

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    public function setNom($nom){
    if(is_string($nom)){
    $this->_nom=$nom;
    }}
     
    public funtion setPoids($poids){
    if(!is_int($poids)){
    trigger_error('Entrez un nombre entier', E_USER_WARNING);
    return;
    }
    if($poids>50){
    trigger_error('Le poids doit être inférieur à 50 kg', E_USER_WARNING);
    return;
    }
    $this->_poids=$poids;
    }





    Cependant, je ne trouve aucun exemple concernant le contrôle des attributs "spéciaux" tels que :


    Contrôle au format :

    - date : jj/mm/aaaa

    - mail : ____________@_______.(2 ou3)

    - téléphone : 00.00.00.00.00

    Faut-il utiliser les patterns comme en js ? un exemple ou un lien pour comprendre.

    ou bien est-ce que je fais fausse route ?

    Merci d'avance

  2. #2
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Pour faire des validations, tu peux utiliser la fonction filter_​var avec des flags de validation. Tu as notamment FILTER_VALIDATE_INT, pour les entiers et FILTER_VALIDATE_EMAIL qui valide les adresses emails :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        echo "La valeur ".$email." n'est pas un email valide";
    }
    Si tu as un format spécifique (dans ton cas, le téléphone par exemple), tu peux utiliser FILTER_VALIDATE_REGEXP avec une regex (de la même façon que tu utilises un pattern en HTML5)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (filter_var($string, FILTER_VALIDATE_REGEXP, array("options" => array("regexp"=>"/^[0-9]{2}.[0-9]{2}.[0-9]{2}.[0-9]{2}.[0-9]{2}$/")) === false ){
        echo "La valeur ".$string." n'est pas un téléphone valide";
    }
    Les filtres PHP

    Pour les dates, tu as deux options : soit tu travailles avec un pattern comme pour le téléphone, soit tu essayes d'en faire une DateTime et tu interceptes l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        $date = DateTime::createFromFormat('d/m/Y', $string);
        if ($date === false) {
            echo "la date ".$string." n'est pas correcte ";
        }
    Pour les dates, attention aux dates inexistantes (genre 30 février). Pour tester ça, tu peux reformater la date en chaine et faire une comparaison :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $date = DateTime::createFromFormat('d/m/Y', $string);
    if ($date === false) {
        echo "la date ".$string." n'est pas correcte ";
    } else {
        // on vérifie que la date existe
        $validString = $date->format('d/m/Y');
        if ($string != $validString) {
            echo "oups, il y a un truc bizarre avec cette date";
        } else {
            echo "Super !";
        }
    }
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut
    Merci pour votre aide

    je vais étudier vos codes et sources afin de les comprendre...et les appliquer

  4. #4
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut
    Pour faire un pattern sur une date j'avais utilisé ceci [0-9]{2}[/]{1}[0-9]{2}[/]{1}[0-9]{4}.

    mais j'ai lu des choses comme cela : [0-9]{2}/[0-9]{2}/[0-9]{4}.

    je n'arrive pas à trouver une bonne pratique

  5. #5
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    ne t'embarque pas dans les expressions régulières pour valider une date, PHP est déjà pourvu de tout ce qu'il faut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $p    = '30/02/2018';
    $date = preg_replace('/[^\d]/u', '', $p); // supprime tout ce qui n'est pas numérique : permet d'avoir n'importe quel glyphe comme séparateur du moment qu'il n'est pas numérique (tiret, dièse...)
    if (strlen($date) === 8) {
        // on suppose que le format d'entrée est dmy
        $d = substr($date, 0, 2);
        $m = substr($date, 2, 2);
        $y = substr($date, 4);
        echo 'Date ', $p, ' est ', checkdate($m, $d, $y) ? '' : 'non', ' valide';  // 30/02/2018 => non valide
    }

  6. #6
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Pour faire une réponse un peu plus générique :

    Pour tous les types natif (int, float, etc ...) tu as généralement un is_XXX qui te permet de tester la valeur.
    Pour certaines chose très standard tu peux trouver également ton bonheur dans filter_​var comme l'indique Celira.

    Mais dans la plus part des cas , tu devras mettre en place tes propres validations.

    Souvent cette procédure de validation se fait en 2 temps :

    1- on valide via filter_var la réception des données. C'est une première passe qui permet de vérifier si le paramètre qu'on recois est du type attendu (string, int , float, ...).

    Si la première étape échoue on ne vas pas plus loin , on considère généralement que c'est un problème grave puisque c'est très souvent le résultat d'une utilisation frauduleuse (quelqu'un qui essai d'injecter des données par exemple).
    Si c'est bon on passe à :

    2- Validation de la valeur en fonction de ce que le métier attends. Par exemple : en 1 j'ai validé que mon paramètre est bien une string, maintenant je veux valider que cette string est bien une date valide. C'est en général cette partie qu'on réalise dans les setters.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    Salut,

    ne t'embarque pas dans les expressions régulières pour valider une date, PHP est déjà pourvu de tout ce qu'il faut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $p    = '30/02/2018';
    $date = preg_replace('/[^\d]/u', '', $p); // supprime tout ce qui n'est pas numérique : permet d'avoir n'importe quel glyphe comme séparateur du moment qu'il n'est pas numérique (tiret, dièse...)
    if (strlen($date) === 8) {
        // on suppose que le format d'entrée est dmy
        $d = substr($date, 0, 2);
        $m = substr($date, 2, 2);
        $y = substr($date, 4);
        echo 'Date ', $p, ' est ', checkdate($m, $d, $y) ? '' : 'non', ' valide';  // 30/02/2018 => non valide
    }
    Merci pour vos retours sur lesquels j'ai pas mal travaillé. Je me permets de revenir sur cette réponse. Au regard de mon niveau de compréhension, je trouve que les expressions régulières sont très pratiques (du moins accessibles). Je comprends qu'il vaut mieux travailler avec du "natif (je ne sais pas si cela se dit ainsi) mais une fois les expressions régulières comprises, elles sont relativement puissantes. non ?

    j'ai volontairement travaillé sur des champs particuliers tels que :

    numéro de téléphone : 00.00.00.00.00
    mail : ______@_____.fr
    date : 00/00/0000
    code postal : 00000


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
     
    	public function setDateC($_dateC)
    	{
    		if(!empty($_dateC))
    		{
    			if (filter_var($_dateC, FILTER_VALIDATE_REGEXP, array("options" => array("regexp"=>"/^(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/"))) !== false ) //272
    			{  
    			    $this->_dateC = $_dateC;
    			    return $this;
    			}
    			else
    			{ 
    				echo "le format " .$_dateC. "  est incorrect! <br>";
    			}
    		} 
    		else
    		{
    			echo "Veuillez saisir une date! <br>";
    		}		
    	}
     
     
     
     
    	public function setMailC($_mailC)
    	{
    		if(!empty($_mailC))
    		{
    			if (filter_var($_mailC, FILTER_VALIDATE_EMAIL) !== false) //274
    			{  
    		    	$this->_mailC = $_mailC;
    		    	return $this;
    			} 
    			else 
    			{
    				echo "La valeur " .$_mailC. " est incorrect! <br>";	
    			}	
    		} 
    		else
    		{
    			echo "La saisie de votre email est obligatoire <br>";
    		}
    	}
     
     
     
    	public function setTelC($_telC)
    	{
    		if(!empty($_telC))
    		{
    			if (filter_var($_telC, FILTER_VALIDATE_REGEXP, array("options" => array("regexp"=>"/^[0-9]{2}.[0-9]{2}.[0-9]{2}.[0-9]{2}.[0-9]{2}$/"))) !== false ) //272
    			{ 
    			    $this->_telC = $_telC;
    			    return $this;
    			} 
    			else 
    			{ 
    				echo "le format de votre numéro de téléphone " .$_telC.  "  est incorrect ! <br>";
    			}
    		} 
    		else
    		{
    			echo "La saisie de votre téléphone est obligatoire! <br>";
    		}	
    	}
     
     
     
     
     
    	public function setCpC($_cpC)
    	{
    		if(!empty($_cpC))
    		{
    			if(filter_var($_cpC, FILTER_VALIDATE_INT) == false)	// 257
     
    				{
    					echo (' Veuillez entrez que des nombres entiers pour le code postal');
    				}
     
    			elseif (strlen($_cpC) !=5)
    				{
    						echo (" Le code postal doit comporter 5 entiers");
    				}
    			else 
    				{
    					$this->_cpC = $_cpC;
    			    	return $this;
    				}	
    		} 
    		else
    		{
    			echo "La saisie de votre code postal est obligatoire! <br>";
    		}
    	}
    Soyez indulgent, je suis totalement novice et autodidacte. Mais après de très nombreux tests, tout semble fonctionner.

    Saisie formulaire Contact -> récupération des données dans le fichier Traitement_Contact.php) qui ont été validées sinon message d'erreur.

    Merci de bien vouloir me faire part de vos retours .




    PAR AILLEURS, J'aimerai vous faire partager ma reflexion...je sais par avance que je risque de m'attirer les foudres mais pourquoi ne pas faire la même chose sur un champ string pour contrôler la saisie. je vous présente ma logique :


    Un formulaire de saisie :

    Nom de Famille : (input de type "text")


    => placeholder : demandant une saisie en lettre majuscule "DUPONT"
    => onkeyup='this.value=this.value.toUpperCase()'


    Si l'utilisateur avec ces 2 "aides + transformations" saisit quelque chose de non-valide alors je pars du postulat qu'il cherche à nuire...

    Alors avec une expression régulière très restrictive, est-il possible de se protéger des attaques les plus courantes par exemple j'ai essayé cela pour tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
    public function setNomC($_nomC)
    	{
    		if(!empty($_nomC))
    		{
    				if (filter_var($_nomC, FILTER_VALIDATE_REGEXP, array("options" => array("regexp"=>"/^[A-Z\-\'\.\s]{2,25}$/"))) !== false )  //272
    				{  
    				    $this->_nomC = $_nomC; 
    				    return $this; 
    				}
    				else 
    				{ 
    					echo "le format  " .$_nomC.  " est incorrect! <br>";
    				}
    		} 
    		else
    		{
    			echo "La saisie de votre nom est obligatoire <br>";
    		}
    	}
    Nb : je sais qu'il y a filter_var....... FILTER_SANITIZE_STRING et j'ai également lu filter_input...mais c'est pour bien comprendre les limites ou intérêts avant de me lancer plus loin.



    En sachant, en plus que je ferai des requêtes préparées et j'utiliserai BindValue.

    Est-ce assez de validation et de protection pour avoir des données valides (du moins sur leur format).

    Merci pour vos explications. Merci de bien vouloir également rester accessible.

  8. #8
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Les deux pattern sont identiques : écrire [/]{1} revient à dire que tu dois trouver exactement un caractère parmi une liste de 1 caractère. Autant écrire directement /.
    Cela dit, ton pattern est extrêmement basique : tu vérifies juste le format 2 chiffres, 2 chiffres, 4 chiffres. Du coup ça va valider 23/12/2018 mais aussi 62/57/8450.

    En mieux tu as : (0[1-9]|1[0-9]|2[0-9]|3[01])/(0[1-9]|1[012])/[0-9]{4} (attention, ça accepte des choses comme 30/20/2018)
    Dates pattern
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  9. #9
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par bricoreur Voir le message
    Sauf erreur de ma part, le contrôle de l'intégrité de mes attributs de classe se fait par les setters.
    Généralement non.

    La plupart du temps, tu auras a valider les données de tes instances les unes en fonction de autres : exemple : quand cet attribut vaut X alors cet autre attribut ne doit pas dépasser Y, etc...
    C'est la raison pour laquelle il est préférable de déporter la validation de tes attributs dans une fonction dédiée, ainsi tu auras toute la souplesse voulue pour traiter même les cas les plus tordus.
    Enfin, il est tout à fait possible que ton objet ne dispose pas toutes les valeurs de ses attributs au moment de la définition d'un (et là, la validation croisée...)

    Attention à Datetime qui corrige les valeurs automatiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $date = DateTime::createFromFormat('d/m/Y', '30/02/2018'); // $date vaudra 02/03/2018 -> 2 mars 2018

  10. #10
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Pour détecter ce genre d'erreurs (correction automatique de 30/02/2018 en 02/03/2018), il suffit de contrôler DateTime::getLastErrors() qui contient un warning.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [POO] test de validation format email
    Par Don-Leplang dans le forum Général JavaScript
    Réponses: 15
    Dernier message: 06/02/2009, 11h39
  2. [POO] validation des # de téléphone d'un formulaire généré en PHP
    Par goldor dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/04/2008, 22h16
  3. [POO] Validation plusieurs champ d'un formulaire
    Par elle-même dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 27/02/2008, 09h03
  4. [POO] Pourquoi recourir aux Getters/Setters ?
    Par Wormus dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 18/01/2008, 18h38
  5. Réponses: 14
    Dernier message: 20/04/2007, 09h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo