Bonjour,
J'ai suivi le tutoriel "Gestion d'un espace membre (refactorisation)" et je souhaiterais y apporter quelque modifications sur mon site.
Seulement voila, après quelques recherches et quelques essais, je n'arrive pas au resultat voulu.
Les erreurs sont dans le tutoriel affichées de cette façon, c'est très bien, mais elle sont toutes affichées en meme temps.
public function get_erreurs()
{
return $this->errors;
}
$errors = $validation->get_erreurs();
<?php foreach($errors as $error): ?>
<?= $error; ?>
<?php endforeach; ?>
Comment faire pour afficher separement les erreurs, email, mot de passe, etc... ?
Merci d'avance pour votre aide
Salut,
je n'ai pas vraiment compris.
Comme je vois une déclaration de fonction, j'ai l'impression qu'on est dans une classe (laquelle ?)
Mais ensuite tu écris du code procédural donc ça me perturbe (on a pas l'air d'être dans une classe finalement).
En plus j'ai du mal à comprendre ton problème parce-que d'après ce que je vois, $this->errors
semble être un tableau. Et ça me parait parfait.
Tu as les messages d'erreur déjà bien séparé.
J'imagine que si on affiche ce tableau on devrait avoir un truc comme ça :
echo '<pre>';
print_r($this->errors);
echo '</pre>';
// affiche :
Array
(
[email] => message d'erreur pour email
[username] => message d'erreur pour username
[password] => message d'erreur pour password
)
Au passage, à quoi correspond $this
?
Les erreurs sont dans le tutoriel affichées de cette façon
Quelle façon ? De quoi est-ce qu'on parle là ? ^^
Bonjour.
Comment faire pour afficher separement les erreurs, email, mot de passe, etc... ?
Si tu veux par exemple afficher chaque erreur au dessus (ou dessous) de l'input concernant l'erreur dans ton formulaire, au lieu de faire la boucle, tu peux très bien faire quelque chose comme :
<div class="form-group">
<label for="">Pseudo</label>
<input type="text" name="username" class="form-control"/>
<?php if (isset($errors) && isset($errors['username'])): foreach ($errors['username'] as $error):
echo $error;
endforeach; endif; ?>
</div>
/* ... */
SLK, tout les codes ne sont pas dans la meme page et la première partie est bien dans une class en effet,
Validator.class.php :
<?php
class validation{
private $data;
private $erreurs = [];
public function __construct($data)
{
$this->data = $data;
}
private function get_champ($champ)
{
if (!isset($this->data[$champ])) {
return null;
}
return $this->data[$champ];
}
public function is_vide($champ, $erreur_message)
{
$value = $this->get_champ($champ);
if (empty($value)) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_caracteres($champ, $erreur_message)
{
$chaine = htmlspecialchars(trim(@$this->get_champ($champ)), ENT_NOQUOTES, 'UTF-8');
if (!preg_match("#^\pL(\pL+[- ']?)*\pL$#ui", $chaine)) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_long($champ, $erreur_message)
{
if (mb_strlen($this->get_champ($champ), 'UTF-8') > 30) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_court($champ, $erreur_message)
{
if (mb_strlen($this->get_champ($champ), 'UTF-8') < 2) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_unique($champ, $db, $table, $erreur_message)
{
$unique = $db->query("SELECT id FROM $table WHERE $champ = ?", [$this->get_champ($champ)])->fetch();
if ($unique) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_email($champ, $erreur_message)
{
if (!filter_var($this->get_champ($champ), FILTER_VALIDATE_EMAIL)) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_confirme($champ, $erreur_message = '')
{
if ($this->get_champ($champ) != $this->get_champ($champ . '_confirmation')) {
$this->errors[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_valide()
{
return empty($this->errors);
}
public function get_erreurs()
{
return $this->errors;
}
}
J'aurais du tout de suite séparer les codes pour plus de compréhension,
Ensuite sur ma page de connexion j'ai la verification :
if(isset($_POST['connexion'])){
$errors = array();
$validation = new validation($_POST);
$validation->is_vide('email', "Ce champ doit être complété.");
$validation->is_vide('mot_de_passe', "Ce champ doit être complété.");
if($validation->is_valide()){
$validation->is_email('email', "Votre adresse éléctronique n'est pas valide.");
}
if($validation->is_valide()){
$utilisateur = $auth->login($db, $_POST['email'], $_POST['mot_de_passe']);
$session = session::getInstance();
if($utilisateur){
$session->setFlash('vert', 'Vous êtes maintenant connecté.');
app::redirect('compte.php');
}else{
$session->setFlash('rouge', 'Votre adresse éléctronique ou votre mot de passe est incorrecte.');
}
} else {
$errors = $validation->get_erreurs();
}
}
Et j'affiche mes erreurs plus bas dans la page :
<?php if (!empty($errors)): ?>
<?php foreach ($errors as $error): ?>
<?= $error; ?>
<?php endforeach; ?>
<?php endif; ?>
Mon problème c'est que de cette façon les erreurs sont toutes affichées les unes en dessous des autres, et moi je souhaiterais faire comme Lartak le suggère, afficher chaque erreur au dessus de son champ, seulement ça methode ne fonctionne pas, je l'avais déjà essayé mais ça n'affiche rien, c'est bien pour cette raison que je viens vers vous.
Ah oui d'accord, excuse-moi.
Attention,
l'attribut de la classe s'appelle $erreurs
,
mais partout dans la classe tu l'utilises avec $this->errors
.
En effet, il a voulu modifier le code proposé par Grafikart dans le tutoriel pour le franciser, mais il n'a pas fait toutes les modifications nécessaires.
Modifications faites,
<?php
class validation{
private $data;
private $erreurs = [];
public function __construct($data)
{
$this->data = $data;
}
private function get_champ($champ)
{
if (!isset($this->data[$champ])) {
return null;
}
return $this->data[$champ];
}
public function is_vide($champ, $erreur_message)
{
$value = $this->get_champ($champ);
if (empty($value)) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_caracteres($champ, $erreur_message)
{
$chaine = htmlspecialchars(trim(@$this->get_champ($champ)), ENT_NOQUOTES, 'UTF-8');
if (!preg_match("#^\pL(\pL+[- ']?)*\pL$#ui", $chaine)) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_long($champ, $erreur_message)
{
if (mb_strlen($this->get_champ($champ), 'UTF-8') > 30) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_court($champ, $erreur_message)
{
if (mb_strlen($this->get_champ($champ), 'UTF-8') < 2) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_unique($champ, $db, $table, $erreur_message)
{
$unique = $db->query("SELECT id FROM $table WHERE $champ = ?", [$this->get_champ($champ)])->fetch();
if ($unique) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_email($champ, $erreur_message)
{
if (!filter_var($this->get_champ($champ), FILTER_VALIDATE_EMAIL)) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_confirme($champ, $erreur_message = '')
{
if ($this->get_champ($champ) != $this->get_champ($champ . '_confirmation')) {
$this->erreurs[$champ] = $erreur_message;
return false;
}
return true;
}
public function is_valide()
{
return empty($this->erreurs);
}
public function get_erreurs()
{
return $this->erreurs;
}
}
Mais je n'arrive toujours pas à afficher les erreurs séparément :-/
Est-ce que tu as bien un retour dans ta variable $errors
qui devrait être alimentée par $validation->get_erreurs()
?
Si oui, montres nous le résultat.
Avec :
<?php if (!empty($erreurs)): ?>
<?php foreach ($erreurs as $erreur): ?>
<?= '<pre>' . print_r($erreurs) . '</pre>'; ?>
<?php endforeach; ?>
<?php endif; ?>
Array ( [email] => Ce champ doit être complété. [mot_de_passe] => Ce champ doit être complété. )
1
Array ( [email] => Ce champ doit être complété. [mot_de_passe] => Ce champ doit être complété. )
1
Fais un debug de la variable $errors
, car comme ça, ça ne nous aide pas vraiment (avec un var_dump par exemple).
J'aimerai bien le voir juste avant la fin du IF,
et juste avant "l'affichage des erreurs" :
if(isset($_POST['connexion']))
{
...
} else {
$errors = $validation->get_erreurs();
}
echo 'DEBUG 1 :<br>';
echo '<pre>';
print_r($errors);
echo '</pre>';
}
echo 'DEBUG 2 :<br>';
echo '<pre>';
print_r($errors);
echo '</pre>';
<?php if (!empty($errors)): ?>
<?php foreach ($errors as $error): ?>
...
Ça affiche quoi ?
DEBUG 2 : rien
DEBUG 1 :
Array
(
[email] => Ce champ doit être complété.
[mot_de_passe] => Ce champ doit être complété.
)
Et j'affiche mes erreurs plus bas dans la page :
Il y a quoi entre les 2 bouts de code que tu nous a montré ? xD
apparemment $errors est détruit (écrasé) entre temps...
<?php if(isset($_POST['connexion'])){
$erreurs = array();
$validation = new validation($_POST);
$validation->is_vide('email', "Ce champ doit être complété.");
$validation->is_vide('mot_de_passe', "Ce champ doit être complété.");
if($validation->is_valide()){
$validation->is_email('email', "Votre adresse éléctronique n'est pas valide.");
}
if($validation->is_valide()){
$utilisateur = $auth->login($db, $_POST['email'], $_POST['mot_de_passe']);
$session = session::getInstance();
if($utilisateur){
$session->setFlash('vert', 'Vous êtes maintenant connecté.');
app::redirect('compte.php');
}else{
$session->setFlash('rouge', 'Votre adresse éléctronique ou votre mot de passe est incorrecte.');
}
} else {
$erreurs = $validation->get_erreurs();
}
echo 'DEBUG 1 :<br>';
echo '<pre>';
print_r($erreurs);
echo '</pre>';
}
require '../includes/header.php'; ?>
<div class="parallax-connexion">
<div class="container">
<p class="container-titre"><?= $page_name; ?></p>
<p>Connectez-vous pour accéder à votre espace et gérer vos commandes.</p>
<?php
echo 'DEBUG 2 :<br>';
echo '<pre>';
print_r($errors);
echo '</pre>';
?>
<?php if (!empty($erreurs)): ?>
<div class="bulle-haut animated fadeIn">
<div>
<?php foreach ($erreurs as $erreur): ?>
<?= $erreur; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<form method="POST" class="connexion">
<input type="text" name="email" id="email" class="connexion-haut" placeholder="Adresse éléctronique" value="<?php if(!empty($_POST)){ echo $_POST['email'];} ?>" onkeyup="disabledButton();" /><br/>
<input type="password" name="mot_de_passe" id="mot_de_passe" class="connexion-bas" placeholder="Mot de passe" onkeyup="disabledButton();" />
<div class="champ-bouton"><input type="submit" name="connexion" id="connexion" class="bouton-connexion" value="→"/></div>
</form>
<div class="separation"></div>
<p><a href="../membre/oublie.php" title="Mot de passe oublié ?">Mot de passe oublié ?</a></p>
<p>Pas encore membre ? <a href="../membre/inscription.php" title="Créer votre compte gratuitement">Créer votre compte gratuitement</a>.</p><br/>
</div>
</div>
<?php require '../includes/footer.php'; ?>
Je t'ai laissé les deux DEBUG que tu vois s'ils sont bien placés
Mais lol xD
Quand tu as copié/collé mon code,
tu as mis $erreurs au DEBUG 1,
et $errors au DEBUG 2 ^^
Faute d'inattention, excuses moi, dans ce cas les deux DEBUG affichent la même chose
D'accord,
Il y a quoi dans ../includes/header.php
?
J'espère que ce fichier utilise aussi une variable $errors, comme ça on aura trouvé le problème.
Faute d'inattention, excuses moi, dans ce cas les deux DEBUG affichent la même chose
Quand tu as réctifié,
tu as mis $errors pour les 2,
ou $erreurs pour les 2 ?
j'espère que tu as mis $erreurs (et pas $errors),
parce-que juste après il y a un IF avec $erreurs
<?php if (!empty($erreurs)): ?>
Le problème vient du foreach, si je modifie le code par :
<?php if (!empty($erreurs)): ?>
<?= $erreurs['email']; ?>
<?php endif; ?>
L'affichage fonctionne correctement, une idée ?
Trop étrange,
j'en suis arrivé à reproduire très grossièrement ton code pour voir, et chez moi ça s'affiche bien.
Avec ce code :
<?php
if (1 == 1)
{
$erreurs = array(
'plop' => 'bidou',
'kiss' => 'love'
);
echo 'DEBUG 1 :<br>';
echo '<pre>';
print_r($erreurs);
echo '</pre>';
}
?>
<p>plop</p>
<?php
include INCLUDES . 'test.php';
echo 'DEBUG 2 :<br>';
echo '<pre>';
print_r($erreurs);
echo '</pre>';
echo '<br>';
?>
<?php if (!empty($erreurs)): ?>
<div>
<?php foreach ($erreurs as $erreur): ?>
<?= $erreur; ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
Affiche :
IF
DEBUG 1 :
Array
(
[plop] => bidou
[kiss] => love
)
plop
DEBUG 2 :
Array
(
[plop] => bidou
[kiss] => love
)
bidou love
Est-ce qu'une de ces classes ne "cacherait" pas le contenu ?
<div class="bulle-haut animated fadeIn">
Le foreach
semble correct, je n'ai pas l'impression que l'erreur vienne de lui.
Pour afficher le contenu d'un tableau, oui, le foreach
est indispensable.
Non, pas de problemes avec les classes CSS, le code que tu as reprodui est exactement pareil chez moi au niveau de l'affichage, et c'est ce qui me chagrine, on a du mal se comprendre, tes erreurs bibou et love s'affichent l'une derrière l'autre, comment fais tu si maintenant tu veux afficher bibou a un endroit de la page et love a un autre endroit ?
C'est la que je te dis que foreach pose problème
avec :
<?php if (!empty($erreurs)): ?>
<?= $erreurs['plop']; ?>
<?php endif; ?>
ça fonctionne, mais alors le foreach est-il indispensable, à quoi sert-il réelement ?
comment fais tu si maintenant tu veux afficher bibou a un endroit de la page et love a un autre endroit ?
Tu y réponds juste après avec le code que tu montres avec l'exemple du $erreurs['plop']
.
mais alors le foreach est-il indispensable, à quoi sert-il réelement ?
Il sert à boucler les éléments d'un tableau.
Tu devrais sérieusement visionner quelques tutoriels sur PHP du site, Grafikart à fait une multitude de tutoriels concernant PHP.
comment fais tu si maintenant tu veux afficher bibou a un endroit de la page et love a un autre endroit ?
Hein ?
Ben avec un IF,
C'est ce que Lartak t'as montré dans son tout 1er message.
Si la clé existe,
ALORS tu affiches les erreurs,
SINON rien
SI la clé
existe,
ALORS on boucle sur cette clé AS clé => valeur
, pour afficher tous les messages d'erreurs liés à cette clé
Si $erreurs['email']
existe,
ALORS pour chaque $erreurs['email'] as $k => $v
: echo $v . '<br>';
Toi tu veux me faire tourner en bourrique ! (je plaisante)