Apprendre la POO doucement...

Mammouth du PHP | 19672 Messages

31 mai 2008, 15:40

Avant de te plonger dans le code, essayes de formaliser la manière de valider un formulaire et essayes de penser à la structure de ta classe. Isole les éléments et les critères de validation, comment stocker les données avec quelles caractéristiques.

Par exemple, dans un formulaire, certains champs seront obligatoires, d'autres non : comment gérer ça.

J'ajoute qu'il y a une erreur dans ton constructeur : tu assignes la mauvaise valeur à ta propriété VerifFormulaire:donnees : je ne t'en dis pas plus, regarde bien ton code et penses-y ;)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 224 Messages

31 mai 2008, 16:11

Re bonjour :)

Bon, pour ne pas gêner d'avantage les échanges entamés par Supercanard, à qui je remercie au passage de m'avoir permis de poser quelques questions sur son topic, j'ai décidé d'ouvrir une nouvelle discussion, histoire que chacun puisse suivre au mieux les deux échanges...

Cela se passe par ici : Questions sur la POO...

Merci encore à Supercanard pour son indulgence et un très grand merci à Cyrano et Ryle pour toutes leurs explications... d'ailleurs, j'y reviendrai, sur l'autre discussion, sur quelques aspects du message de Ryle... mais ces quelques question théoriques seront pour ce soir, en attendant c'est un peu de la pratique que je propose sur l'autre échange... ;)

Merci encore... à+ :)
Fredo d;o)
"Un pas à la fois me suffit..." (Gandhi)

Mammouth du PHP | 531 Messages

31 mai 2008, 16:25

Hummm... pour l'erreur, c'est plutôt ça non ?
public function __construct( $_POST )
    {
        $this -> donnees = $_POST;
		$this -> NbChampsVides = 0;
		$this -> cle = NULL;
		$this -> valeur = NULL;
		$this -> ErreursForm = NULL;
    }
Sinon pour les champs obligatoires, j'ai un semblant d'idée qui serrais de mettre la liste des champs obligatoires lorsque l'on appelle la méthode....

$VerifForm -> ChampVides( $_POST['champ1'] ', $_POST['champ1'] );

Ou alors plutôt au moment ou l'on appelle la classe.... :

$ChampsAVerifier = $_POST['Champ1'], $_POST['Champ2'];
$VerifForm = new VerifFormulaire( $ChampsAVerifier );

Mais je suis peut etre à coté de la plaque aussi
:D

Mammouth du PHP | 19672 Messages

31 mai 2008, 17:39

Manqué.

Alors un détail : il est inutile d'affecté NULL à tes propriétés de classes. Si tu n'as pas de valeur à y affecter, alors tu les oublies tout simplement, elles seront initialisées au moment opportun dans les méthodes appropriées avec des valeurs.

Mais l'erreur n'est pas là. Tu avais une instanciation correcte de ta classe mais tu n'utilisais pas le paramètre envoyé. Pourtant au départ c'était la bonne méthode, c'est la suite qui ne collait pas.

C'est comme avec n'importe quelle fonction : si tu appelles une fonction en indiquant un paramètre, ça ne sert pas à grand chose si tu n'utilises pas ce paramètre. Penses-y un moment :-k
Regarde ta méthode :
<?php
//... 
    public function __construct( $donnees )
    {
        $this -> donnees = $_POST;
        $this -> NbChampsVides = 0;
        $this -> cle = NULL;
        $this -> valeur = NULL;
        $this -> ErreursForm = NULL;
    }
//...
Là, ton paramètre $donnees n'est jamais utilisé, nulle part. Or c'est pourtant la manière logique d'envoyer les données à traiter dans ton objet. Donc...
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 531 Messages

31 mai 2008, 18:30

Ah j'ai compris, rien ne sert d'envoyer le paramètre donc.
Désolé j'ai mis du temps à capter :lol:

Ok, et maintenant si je veut vérifier seulement certains champs, ma première idée et de faire comme ça, mais je suis pas sur même si ça marche très bien que ce soit une solution correcte... :
( Je me rend compte à l'instant que je n'ai pas déclaré $test comme propriété de l'objet, mais bon ça ne gène pas pour l'instant )


<?php
class VerifFormulaire
{
	private $NbChampsVides;
	private $cle;
	private $valeur;
	private $ErreursForm;

	public function __construct()
    {
		$this -> NbChampsVides = 0;
    }
    
    public function ChampVides( $test )
    {
		foreach( $test as $cle => $valeur )
		{
			if ( $valeur == NULL )
			{
				$this -> NbChampsVides++;
			}
		}
    }
	public function AfficherErreurs()
	{
		if ( $this -> NbChampsVides != 0 )
		{
			$this -> ErreursForm .= $this -> NbChampsVides.' champ(s) vide(s)';
		}
		return $this -> ErreursForm;
	}
}
?>

<?php
if ( isset( $_POST['Champ1'] ) )
{
	$VerifForm = new VerifFormulaire();
	$VerifForm -> ChampVides( array( $_POST['Champ1'] ) );
	$ErreursForm = $VerifForm -> AfficherErreurs();
	echo $ErreursForm;
}
?>

Mammouth du PHP | 19672 Messages

31 mai 2008, 22:57

Ah j'ai compris, rien ne sert d'envoyer le paramètre donc.
Désolé j'ai mis du temps à capter :lol:
Ben non animal... :roll: mais si tu as :
public function __construct( $donnees )
Et qu'après ça tu fais :
$this -> donnees = $_POST; 
Veux-tu bien m'expliquer à quoi sert d'envoyer $donnees ?? Et pourquoi tu ne fais pas plutôt :
$this -> donnees = $donnees; 
:-*
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 531 Messages

31 mai 2008, 23:33

Ah bon attends cette fois je crois que j'ai compris. J'espere, mais si c'est pas le cas, promis je fait pas expré hein :D
Ce qui me met dans la confusion c'ets que lorsque je fait ça :
$VerifForm = new VerifierFormulaire( $_POST );
Je créé donc une instance, et je lui envois un tableau de données

Et dans le constructeur
public function __construct( $donnees )
Je passe donc ce tableau. Comme dans une fonction en fait.

Donc si j'ai bien suivis ça c'est juste ?
// ... Debut
public function __construct( $donnees )
    {
		$this -> donnees = $donnees;
		$this -> NbChampsVides = 0;
		$this -> erreurs = NULL;
    }

// ... suite

$VerifForm = new VerifierFormulaire( $_POST );

Mammouth du PHP | 19672 Messages

01 juin 2008, 07:58

Voilà, tout simplement.

Mais encore une fois, tu initialises $this->erreurs à NULL, c'est complètement sans intérêt.

Un point qu'il faut arriver à saisir de la POO : lorsque tu crées une instance de classe, l'objet créé a des propriétés qui ont ou non une valeur selon ce que tu as défini dans le constructeur. Si tu n'as rien défini, alors la propriété n'a pas de valeur. Et c'est indépendant de ces mêmes propriétés pour un objet qui serait une autre instance parallèle de la même classe.

Pourquoi écrire davantage de code si le supplément est inutile ? :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 531 Messages

01 juin 2008, 18:09

Pas évident à tout comprendre d'un seul coup ^^

Bon j'ai quand même réussi à faire mon tout premier objet, qui fonctionne :)
Meme si ma fonction TesterChampsIdentiques est un peu longue pour ce qu'elle fait.

J'ai toutefois un doute au niveau de tous mes foreach. J'utilise des variables ( $cle et $valeur) qui ne sont pas des propriétés de l'objet. je ne sais pas si j'ai eu tord mais mon raisonnement était que ces variables en question ne servent qu'au sein d'une fonction, donc il n'y a pas lieu que ces variables soient des propriétés de l'objet... puisqu'on ne s'en sert pas ailleur... ??
<?php
/*
A rajouter : Test valeur numérique et test valeurs identiques ( pours champs mot de passe )
*/
class VerifierFormulaire
{
// Propriétés
	private $donnees;
	private $erreurs;
	private $ListeErreurs;
// Constructeur
	public function __construct( $donnees )
    {
		$this -> donnees = $donnees;
		$this -> erreurs = array();
		//$this -> ListeErreurs = NULL;
    }
// Méthodes   
    public function TesterChampsVides( $Champs )
    {
		$Champs = explode( ',', $Champs );
		foreach( $this -> donnees as $cle => $valeur )
		{
			if ( ( in_array( $cle, $Champs ) ) && ( $valeur == NULL ) )
			{
				$this -> erreurs[] = 'Le champ '.$cle.' est obligatoire';
			}
		}
    }
	public function TesterChampsEmail( $Champs )
    {
		$Champs = explode( ',', $Champs );
		foreach( $this -> donnees as $cle => $valeur )
		{
			if ( ( in_array( $cle, $Champs ) ) && ( !ereg( '.+(@.+)(\.[[:alpha:]]{2}([[:alpha:]]?))$', $valeur ) ) )
			{
				$this -> erreurs[] = 'Le champ '.$cle.' doit contenir une adresse email valide';
			}
		}
    }
	public function TesterChampsIdentiques( $Champs )
    {
		$Champs = explode( ',', $Champs );
		$i = 1;
		$x = NULL;
		$y = NULL;
		foreach( $this -> donnees as $cle => $valeur )
		{
			if ( in_array( $cle, $Champs ) )
			{
				if ( $i == 1 )
				{
					$x = $valeur;
					$xNom = $cle;
					$i++;
				}
				else
				{
					$y = $valeur;
					$yNom = $cle;
				}
			}
		}
		if ( $x != $y )
		{
			$this -> erreurs[] = 'Les champs '.$xNom.' et  '.$yNom.' doivent être identiques';
		}
    }
	public function AfficherErreurs()
	{
		$this -> ListeErreurs .= '<ul>';
		foreach( $this -> erreurs as $valeur )
		{
			$this -> ListeErreurs .= '<li>'.$valeur.'</li>';
		}
		$this -> ListeErreurs .= '</ul>';
		return $this -> ListeErreurs;
	}
}
?>

<?php
########## Vérification du formulaire

/*
##### Paramètres
- TestChampsVides : Retournera une erreur si les valeurs sont vides
- TestChampsEmail : Retournera une erreur si les valeurs ne sont pas du type [email protected]
*/
$TestChampsVides = 'Nom,Email'; // Entrez le nom des champs à vérifier ( Entre les '' et séparés par des virgules )
$TestChampsEmail = 'Email'; // Entrez le nom des champs à vérifier ( Entre les '' et séparés par des virgules )
$TestChampsIdentiques = 'Password,Confirmation'; // Entrez le nom des champs à vérifier ( Entre les '' et séparés par des virgules )
/*
##### Vérification
*/
if ( isset( $_POST ) )
{
	$VerifForm = new VerifierFormulaire( $_POST );
	$VerifForm -> TesterChampsVides( $TestChampsVides );
	$VerifForm -> TesterChampsEmail( $TestChampsEmail );
	$VerifForm -> TesterChampsIdentiques( $TestChampsIdentiques );
	$ListeErreurs = $VerifForm -> AfficherErreurs();
	echo $ListeErreurs;
}
?>

<form method="post" action="#">
<p><label>Nom</label><input type="text" name="Nom" /></p>
<p><label>Email</label><input type="text" name="Email" /></p>
<p><label>Password</label><input type="password" name="Password" /></p>
<p><label>Confirmation</label><input type="password" name="Confirmation" /></p>
<input type="submit" />
</form>

Mammouth du PHP | 19672 Messages

01 juin 2008, 18:41

Pour les variables dans les méthodes, ton raisonnement est tout à fait valable.

Et si ça fonctionne à ta satisfaction, alors c'est très bien. Avec le temps, tu amélioreras petit à petit certains détails. Comme par exemple faire des boucles foreach non pas sur les données mais sur le tableau issu du paramètre. Et au fond pourquoi ne pas envoyer directement un paramètre... etc, etc... Tout te montrer maintenant ne serait pas très utile à mon sens. Tes propres raisonnement t'amèneront à optimiser progressivement.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 531 Messages

01 juin 2008, 20:38

Pour les variables dans les méthodes, ton raisonnement est tout à fait valable.

Et si ça fonctionne à ta satisfaction, alors c'est très bien. Avec le temps, tu amélioreras petit à petit certains détails. Comme par exemple faire des boucles foreach non pas sur les données mais sur le tableau issu du paramètre. Et au fond pourquoi ne pas envoyer directement un paramètre... etc, etc... Tout te montrer maintenant ne serait pas très utile à mon sens. Tes propres raisonnement t'amèneront à optimiser progressivement.
Merci de ta réponse.
Je vais pouvoir clore le topic.
Merci à tous ceux qui m'ont aidés et un merci spécial à toi Cyrano ;) C'est grâce à ton exemple que j'ai pu faire mon premier objet. J'ai l'impression d'être un gamin qui découvre les légo là :lol:

Mammouth du PHP | 19672 Messages

01 juin 2008, 21:36

lol, absolument et un jour tu monteras ce genre de chose toi-même D
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
AB
ViPHP | 5818 Messages

01 juin 2008, 23:24

Par exemple dans tes méthodes de test tu fais systématiquement
$Champs = explode( ',', $Champs );
Tu pourrais faire une fonction pour réaliser cette ligne, fonction qui serait appelée par chacune de tes méthodes de test. Ainsi il te suffirait de changer uniquement cette fonction si pour une raison quelconque tu devais changer de séparateur. Mais tu pourrais aussi aller plus loin, déclarer une variable pour le séparateur qui par défaut pourrait-être égal = ',' et à l'instanciation de ta classe ou dans l'appel de tes fonctions, passer en argument le nouveau séparateur s'il est différent de celui par défaut. Cela rendrait ton objet adaptable à plus de situations. Bon, ce n'est pas nécessairement utile, mais juste un exemple au passage.

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

Mammouth du PHP | 531 Messages

01 juin 2008, 23:47

Par exemple dans tes méthodes de test tu fais systématiquement
$Champs = explode( ',', $Champs );
Tu pourrais faire une fonction pour réaliser cette ligne, fonction qui serait appelée par chacune de tes méthodes de test. Ainsi il te suffirait de changer uniquement cette fonction si pour une raison quelconque tu devais changer de séparateur. Mais tu pourrais aussi aller plus loin, déclarer une variable pour le séparateur qui par défaut pourrait-être égal = ',' et à l'instanciation de ta classe ou dans l'appel de tes fonctions, passer en argument le nouveau séparateur s'il est différent de celui par défaut. Cela rendrait ton objet adaptable à plus de situations. Bon, ce n'est pas nécessairement utile, mais juste un exemple au passage.

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]
Juste pour voir si ça rentre bien dans mon crane : Cette méthode appellée par des autres serrais donc private ?

ViPHP
AB
ViPHP | 5818 Messages

02 juin 2008, 01:33

Tant que tu n'as pas à l'utiliser depuis l'extérieur de ta classe, oui. Mais ça fonctionnerait également si tu la mettais "public". La mettre en "private" est une mesure de sécurité.