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 :

MVC traitement des données utilisateurs


Sujet :

Langage PHP

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 244
    Points
    20 244
    Par défaut MVC traitement des données utilisateurs
    Salut à tous,

    Je m'interroge quant à la meilleur façon de gérer les entrée utilisateur (GPC) dans un modèle MVC.

    Dans l'absolue je récupère par exemple mes données $_POST dans l'action du controller , je passe ensuite ces données au modèle via les paramètres.

    Mais quid du traitement des données ?

    Si par exemple j'ai besoin de vérifier la syntaxe d'un email avant de le sauvegarder je vais faire ça dans l'action puisque cela va conditionner l'appel ou non au model.
    Mais admettons que j'ai besoin de formater les données avant de les insérer dans une base. Est ce que je fait ce formatage dans l'action , dans une méthode privée du controller ou carrément dans le model puisque au final ce formatage est directement liées au besoins du model ?

    D'après mes lectures la théorie voudrait que tout soit fait dans l'action mais dans certain cas on à vite tendance à se retrouver avec des controller monstrueux justement à cause des données utilisateur très importante ou nécessitant beaucoup de traitement.

    Je précise que j'utilise aucun framework spécifique c'est juste une interrogation global sur le sujet.

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Hello

    J'y ai pensé mais je n'ai pas encore pondu de source correcte là dessus. En effet il est du rôle d'un contrôleur de valider les données, ça n'empêche pas pour autant l'instance de Request (ou l'équivalent chez toi) de faire le filtrage.
    La méthode à laquelle j'avais pensé serait d'utiliser filter_var_array en permettant aux contrôlleurs d'importer leur logique dans l'objet Request.

    Quelque chose comme ça pourrait faire l'affaire (même si c'est embryonnaire):
    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
     
    class Request {
     
    	protected $_input;
     
    	protected static $_filters;
     
    	public function __construct () {
    		$this->_inputs = $_REQUEST;
    	}
     
    	public function getTaintedInput ($key) {
    		return isset($this->_inputs[$key]) ? $this->_inputs[$key] : null;
    	}
     
    	public function getInput ($key) {
    		return filter_var($this->getTaintedInput($key), FILTER_SANITIZE_STRING);
    	}
     
    	public function __get ($key) {
    		return $this->getInput($key);
    	}
     
    	public static function setFilters ($filters) {
    		self::$_filters = $filters;
    	}
     
    	public function applyFilters () {
    		if (!empty(self::$_filters))
    			$this->_input = filter_var_array($this->_input, self::$_filters);
    	}
    }

  3. #3
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Mais admettons que j'ai besoin de formater les données avant de les insérer dans une base. Est ce que je fait ce formatage dans l'action , dans une méthode privée du controller ou carrément dans le model puisque au final ce formatage est directement liées au besoins du model ?

    D'après mes lectures la théorie voudrait que tout soit fait dans l'action mais dans certain cas on à vite tendance à se retrouver avec des controller monstrueux justement à cause des données utilisateur très importante ou nécessitant beaucoup de traitement.
    Oui logiquement c'est dans l'action, mais je crois qu'il n'est pas faux de penser qu'il est de la responsabilité de la couche modèle de mettre les données "dans le bon sens" avant de les persister.
    Avec PDOStatement::bindParam ou PDOStatement::bindValue ça fait sens

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 244
    Points
    20 244
    Par défaut
    Merci pour tes deux réponses. Je n'utilise jusqu'à maintenant pas de class "Request". Ca dévie un peu de la "norme" mais ça reste pour moi une surcouche pas forcément nécessaire.
    Mais effectivement en y intégrant un filtrage des données ca prend du sens.

    Je resolve pas le sujet tout de suite defois que d'autres aient des avis divergents.

  5. #5
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    @grunk : Excellente question :-)

    Je me suis déjà posé la même question il y a un bout de temps au moment du développement d'un framework PHP pour ma boite.

    Le plus simple est de contourner le problème en admettant qu'à priori tu ne sais jamais la somme des traitements qu'une action
    nécessitera ni quelle partie du code (controller, model, action) fera ces traitements.

    Donc le but est d'être capable de faire voyager ta donnée utilisateur à travers le modèle (ou toute autre partie du code, au développeur d'être bien organisé)
    en ayant la capacité de définir ce qui est nécessaire au bon fonctionnement du modèle et aussi de collecter les différents messages et erreurs que
    les traitements pourraient renvoyer. Le seul moyen est d'envelopper ta donnée dans une classe qui se charge de toutes ces tâches subalternes.

    Ainsi, la totalité des traitements ne manipule que des instances de cette classe (instance unique ou collection).

    Par extension, cette approche peut aller très loin : dans notre framework lors de la réception du POST,
    à chaque valeur récupérée on rattache via la classe enveloppante l'identifiant du contrôle graphique source de la valeur.
    On injecte le tout dans le modèle (ou la classe action) qui fait ses traitements et à la sortie on regarde si le collecteur d'erreurs rattaché à la classe
    a été mouvementé et si oui automatiquement le framework renvoie l'erreur qui se positionne en fonction de l'identifiant du contrôle graphique.

    En plus c'est assez léger car l'instance ne voyage que par référence.

    En conclusion, je pense qu'il n'y a pas de réponse idéale à ta question.
    Les interprétations du MVC sont légions donc à mon avis il faut parer à toutes les fantaisies.

    Allez pour étayer cette approche je vous propose le squelette allégé de la classe enveloppante :
    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
    class MyVar implements \pse\IEECollectable {
     
    	/**
    	 * Valeur saisie et récupérée par l'utilisateur
    	 * Ne peut faire l'objet d'aucune modification par la suite
    	 * @var mixed
    	 */
    	private $_userValue;
    	/**
    	 * Valeur utilisée par le système pour ses traitements, fonction du type de userValue
    	 * Par ex : toutes les dates sont manipulées sous forme YYYYMMDD indépendamment de ce qui
    	 * a été saisi par l'utilisateur, les heures sous format décimal...
    	 * Dans 99% des cas est équivalent à userValue
    	 * @var mixed
    	 */
    	private $_systemValue;
    	/**
    	 * Valeur formatée pour l'injection des données dans la base de données
             * @var mixed
    	 */
    	private $_dbFormattedValue;	
    	/**
    	 * Constante de la classe PDO référençant le type de donnée
    	 * @var \PDO::PARAM_
    	 */
    	private $_pdoType;
    	/**
    	 * Nom littéral de la valeur utilisé dans l'interface graphique
    	 * utilisé pour la personnalisation automatique des messages d'erreur
    	 * @var string
    	 */
    	private $_guiName;
    	/**
    	 * Stocke l'éventuel alias d'un champ de table auquel est rattaché la variable
    	 * @var string
    	 */
    	private $_linkedAlias;
    	/**
    	 * Stocke l'éventuel id de bloc graphique auquel est rattaché la variable
    	 * @var string
    	 */
    	private $_linkedBlock;
    	/**
    	 * @var \pse\EECollector Collecteur d'erreurs et d'exceptions
    	 */
    	private $_eec;
    }
    Comme vous pouvez le constater, on traite déjà pas mal de cas de figures.

  6. #6
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    J'aime beaucoup cette approche, je serais sûrement ammené à te l'emprunter un jour. Cependant, et je pense que c'est parce que tu ne nous mets pas toute la classe, j'ajouterai bien une capacité de filtrage / sanity ainsi qu'un factory (dans une autre classe) pour permettre d'aller plus vite.

  7. #7
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par Benjamin Delespierre Voir le message
    J'aime beaucoup cette approche, je serais sûrement ammené à te l'emprunter un jour. Cependant, et je pense que c'est parce que tu ne nous mets pas toute la classe, j'ajouterai bien une capacité de filtrage / sanity ainsi qu'un factory (dans une autre classe) pour permettre d'aller plus vite.
    Emprunte, emprunte autant que tu veux

    Par contre je ne pense pas que cela soit une bonne idée de rajouter une capacité de filtrage/sanity. Cette classe n'est pas faite pour ça. Elle propose des services à toute partie du code qui devrait la manipuler. Dans cette logique, tu dois avoir un Validator qui se charge de ta variable MyVar. Il fait son boulot et la renseigne au besoin si elle passe le test ou pas.

    La classe MyVar agrège et empile les résultats des tests passés (surtout ceux qui ne passent pas).
    Il y a un intérêt majeur à ça c'est lors de tests multiples. Si tu supposes que dans un champ tu aies des caractères interdits et une longueur max et que tu enfreignes les deux règles.
    Si la validation se fait à deux endroits distincts du code : tu ballades ta variable à travers tes 2 validateurs et tu récupères ainsi la double erreur.
    Cette approche s'explique car je sépare toujours la validation métier (caractères interdits) de la validation persistence (longueur max).

Discussions similaires

  1. [PHP-JS] Jointure et traitement des données
    Par grunk dans le forum Langage
    Réponses: 2
    Dernier message: 04/10/2006, 23h35
  2. Traitement des données formatées en XML
    Par cedricnguessi dans le forum Autres éditeurs
    Réponses: 14
    Dernier message: 10/07/2006, 14h21
  3. [Formulaires] Traitement des données dans une autre page...
    Par sekiryou dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 04/03/2006, 10h08
  4. [PHP-JS] Traitement des données dans une autre page...
    Par sekiryou dans le forum Langage
    Réponses: 5
    Dernier message: 04/03/2006, 10h06
  5. traitement des données avant envoie dans MySQL
    Par italiasky dans le forum SQL Procédural
    Réponses: 13
    Dernier message: 07/02/2006, 23h50

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