[RESOLU] Un double problème dans une double condition php-mysql

Eléphanteau du PHP | 39 Messages

02 août 2016, 14:47

Bonjour,

J’ai réalisé une requête qui marche

Code : Tout sélectionner

$requete = $connexion->prepare("SELECT champ1, champ2 FROM table3 ORDER BY champ2"); $requete->execute(); $result[1] = $requete->fetchAll(); foreach ($result[1] as $row) { echo '&nbsp;&nbsp;<a href="mapage.php? champ1=' . $row["champ1"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;';}
Cependant comme j’ai dans champ2 des lignes vides ou NULL, je me retrouve au début des résultats avec plein de | que je ne veux pas
Donc j’ai essayé une première condition avant la ligne echo précédente
if($result[1]["champ2”] !== null and $result[1]["champ2"] !== "") { echo '&nbsp;&nbsp;<a href="mapage.php? champ1=' . $row["champ1"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;';} else {echo "";}}
Le message d’erreur est:
Notice: Undefined index: champ2 in on line XX
Je ne comprend car j’ai des conditions similaires pour d’autres requêtes et cela marche !

Voilà pour la première condition.

J’ai une deuxième condition.
champ2 est constitué soit de lignes vides ou nulles comme déjà indiqué, soit de noms et précisément de 1, 2 ou 3 noms séparés par 1 espace (2 noms) ou 2 espaces (3 noms).
Je veux comparer dans la suite de résultats de champ2 le premier nom (seulement) entre le résultat n et n+1 et si le premier nom change, alors d’ajouter dans ma liste un double <br> (pour séparer visuellement).
Et pour commencer je me suis servi comme modèle de la requête d’un fil précedent que j’ai adapté et qui compare le résultat n et n+1 pour les 7 premiers caractères de champ2.
Voici ma requête adaptée

Code : Tout sélectionner

$initialmot = ''; foreach($result as $row){ $rang = $row["champ1"]; $monliennomassocie = $row["champ2"]; $initName = strtoupper(substr($monliennomassocie, 0, 7)); if (strtoupper($initName) != $initialmot) { echo '&nbsp;&nbsp;<a href="mapage.php? champ1=' . $row["champ1"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp; <br><br>'; $initialmot = strtoupper($initName); } echo '&nbsp;&nbsp;<a href="mapage.php? champ1=' . $row["champ1"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;'; }
Je n’ai pas de message d’erreur : Cela donne un résultat mais pas celui que j’attendais.
En fait, il regroupe les noms par paire avant de faire le double <br>
Je ne pige pas !
De toute façon il faut que je modifie :
$initName = strtoupper(substr($monliennomassocie, 0, 7));
Pour que la comparaison entre ligne n et n+1 porte sur le premier nom avant le premier espace s’il y en a un.

Voilà, j’ai beaucoup travaillé mais là j’atteint mes limites actuelles.
Et je compte sur votre coup de pouce.
Merci de votre aide

A+

Seb

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

02 août 2016, 16:17

salut,

premier cas, c'est $row que tu dois utiliser au lieu de $result[1]["champ2"] => $row["champ2"]

si les lignes avec champ2 vide ne t’intéresse pas dégage les dans la requête SQL ;) (and champ2 is not null and trim(champ2) != '' )


cas deux, utilise explode pour séparer la chaîne sur les espaces. avec une variable compteur tu va pouvoir sélectionner l'index qui t’intéresse.
il faut modifier la condition d'affichage pour ne pas prendre en compte le mot initiale vide :
if (strtoupper($initName) != $initialmot && !empty($initialmot) ) {

le dernier echo doit être dans un else sinon tu t'expose à l'affiche double des données quand le if match.

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 39 Messages

02 août 2016, 18:55

Salut moogli, le modérateur,
Ah là c'est que c'est trop facile pour toi et bien trop difficile pour moi (doucement, pas à pas s'il te plaît).
D'abord j'ai fait une erreur en recopiant mes champs, le code qui marche est en réalité (pas 2 fois champ1):
echo '&nbsp;&nbsp;<a href="mapage.php?ident=' . $row["champ1"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;';

ensuite si j'écris la requête comme
$requete = $connexion->prepare("SELECT champ1, champ2 and champ2 is not null and trim(champ2) != '' FROM table3 ORDER BY champ2");

j'ai plein d'erreurs.
Donc j'ai pas pigé où mettre
and champ2 is not null and trim(champ2) != ''

Si je modifie le code en :
if (strtoupper($initName) != $initialmot && !empty($initialmot) )
alors mes doubles <br> sont inactifs et le résultat s'affiche comme avec le tout premier code qui marche dans mon premier message!!

quant au code lié à explode, c'est à des années lumières pour moi!
J’ai quand même regardé la fonction explode sur le net et il y a des exemples comme (pour moi)
$premiermot=explode(" ", $champ2)
echo $premiermot[0];
mais comme dans certains cas (pour les noms avec 1 nom seulement) il n’y a pas d’espace dans champ2, cela va me retourner aucun résultat ou une erreur, non ?
Et puis où le mettre…dans le code avant le if ou dans le foreach ?
Désolé je suis bien trop débutant.
Pourrais-tu me répondre pas à pas pour le code qui convient (progression incrémentale pour moi)?

Je suis débutant et c'est le forum que j'ai choisi.

Merci d'avance

Seb

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

03 août 2016, 10:59

alors pour explode, s'il n'y a pas d'espace cela va tout retourner dans le premier index du tableau ;)
si tu ne sais pas tu te crée un ficher a coté et tu test sans rien casser ;)
par exemple
<?php
var_dump( explode(' ','chaine'));

affiche : array(1) { [0]=> string(6) "chaine" }

pour le SQL le lieux c'est que tu regardes un tuto parce que la effectivement il te manque les bases : http://sqlpro.developpez.com/cours/sqlaz/select/

test tes requêtes sql dans un client (tu as peut être phpmyadmin déjà installé ?) sinon quelque chose comme heidiSQL c'est largement suffisant ;)

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 39 Messages

04 août 2016, 13:59

Salut moogli, modérateur,
Je comprend.
Alors je vais procéder pas à pas de mon côté.
J'ai effectivement PHP My admin et j'avais testé les requêtes.
Donc après lecture de ton fichier (http://sqlpro.developpez.com/cours/sqlaz/select/) je teste :
SELECT champ1, champ2, FROM table3 HAVING trim(champ2 != '') ORDER BY champ2
Et j’ai erreur
#1064 - Erreur de syntaxe près de, etc.
Cette erreur est, d’après le Net, très générale.
Ma table n’est pas en cause puisque la 1ère requête marche (je veux juste ne pas avoir les résultats qui correspondent à des lignes avec le champ2 vide).

Pour ce qui est de Explode, avec mon niveau, je suis pas capable de comprendre tes phrases.
Sauf erreur, je comprend que dans le cas d’un seul mot (pas d’espace) y a pas de souci et que le mot sera pris.
Mais alors pourrais-tu être plus précis et plus adapté à mon cas champ2 pour les variables et la condition ?
Je veux ajouter un double <br> pour la liste de résultat (tableau) quand le premier mot change.
Par exemple, mes résultats sont blabla, blabla cas-1, blabla cas-2 souscas-a, blabla cas-3, bobo, bobo cas-4 souscas-b, bobo cas-5
Je veux obtenir
blabla | blabla cas-1 | blabla cas-2 souscas-a | blabla cas-3 |

bobo | bobo cas-4 souscas-b | bobo cas-5

etc.

Merci de ton aide

A+ Seb

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

04 août 2016, 15:07

C'est plus simple en fait :)
SELECT champ1, champ2, FROM table3 where champ2 is not null and trim(champ2 != '') ORDER BY champ2
pour le reste
<?php
$old = '';
// je laisse faire la requête sql
while($data = ...) {
if(!empty($old) && $old != $data['champ2 '] ) {
echo '<br /><br/>';
}
echo $data['champ2'], ' | ';
$old = $data['champ2 ']
}
Voilà à quoi ça ressemble

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 39 Messages

05 août 2016, 16:16

Ah merci moogli, le modérateur,
dans la requête j'avais mis HAVING parce que je lisais dans le tuto (je cite):
La plupart du temps, la difficulté réside dans la compréhension de la différence entre le filtre WHERE et le filtre HAVING. Disons plus pragmatiquement que le filtre WHERE permet de filtrer les données des tables tandis que le filtre HAVING permet de filtrer les données du résultat...

Erreur funeste!

Maintenant c’est OK, je n’ai plus au début mes parasites correspondant à des lignes vides.
Enfin, j’ai travaillé sur ta proposition qui ne prend plus explode et qui est plus simple (pour moi).
Je l’ai adaptée à mon cas, à mon savoir (je maîtrise un peu la boucle for pas du tout while, j’utilise and et pas &&), mais çà bugge (erreur : Parse error: syntax error, unexpected '}' in line (la dernière), pourtant les { et } sont appairés (j’ai double checké).
Voici mon code :

Code : Tout sélectionner

{ echo '<blockquote>'; $old = ''; $requete = $connexion->prepare("Champ1, Champ2 FROM table3 WHERE Champ2 is not null and trim(Champ2 != '') ORDER BY Champ2"); $requete->execute(); $result[1] = $requete->fetchAll(); foreach ($result[1] as $row) { if(!empty($old) and $old != $result[1]["Champ2"]) {echo '<br><br>';} else { echo '&nbsp;&nbsp;' . $result[1]["Champ2"]. ' | </blockquote>';} $old = $result[1]["Champ2"]}}
Note : en réalité j’aurai à l’avant dernière ligne du code ci dessus, le code suivant (mais çà j’ai pas testé) :
echo '&nbsp;&nbsp;<a href="mapage.php?Ident=' . $row["Champ1"] .'"><i>' . $row["Champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp; </blockquote>';

Sois indulgent, stp!
Qu’est-ce qui cloche?
Merci d’avance (et si je ne te lis pas avant ce soir, je te souhaite un bon WE)
A+ Seb

Eléphanteau du PHP | 39 Messages

09 août 2016, 19:14

Bonjour le forum,

Comme je n’ai pas de réponse de moogli, le modérateur, donc je reprends ma question.

J’ai la requête/code suivante qui marche :

Code : Tout sélectionner

echo '<blockquote>'; $requete = $connexion->prepare("Champ1, Champ2 FROM table3 WHERE Champ2 is not null and trim(Champ2 != '') ORDER BY Champ2"); $requete->execute(); $result[1] = $requete->fetchAll(); foreach ($result[1] as $row) { echo '&nbsp;&nbsp;<a href="mapage.php?ident=' . $row["champ2"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;';} echo '</blockquote>';
Mais comme la liste obtenue n’est pas visuellement claire et aérée, je veux introduire un saut de ligne <br><br> quand le 1er mot de champ2 change d’une ligne à la suivante dans la liste de champ2.
Par exemple, mes résultats dans champ2 sont ligne après ligne sont blabla, blabla cas-1, blabla cas-2 souscas-a, blabla cas-3, bobo, bobo cas-4 souscas-b, bobo cas-5, blurp, blurp cas-1
Je veux obtenir
blabla | blabla cas-1 | blabla cas-2 souscas-a | blabla cas-3 |
un saut de ligne
bobo | bobo cas-4 souscas-b | bobo cas-5
un saut de ligne
blurp | blurp cas-1
etc.

Voici mon code adapté du message précédent de Moogli :

Code : Tout sélectionner

echo '<blockquote>'; $old = ''; $requete = $connexion->prepare("Champ1, Champ2 FROM table3 WHERE Champ2 is not null and trim(Champ2 != '') ORDER BY Champ2"); $requete->execute(); $result[1] = $requete->fetchAll(); foreach ($result[1] as $row) { if(!empty($old) and $old != $result[1]["Champ2"]) {echo '<br><br>&nbsp;&nbsp;<a href="mapage.php?Ident=' . $row["Champ1"] .'"><i>' . $row["Champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp; </blockquote>';} else { echo '&nbsp;&nbsp;<a href="mapage.php?Ident=' . $row["Champ1"] .'"><i>' . $row["Champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp; </blockquote>';} $old = $result[1]["Champ2"]
Je n’ai plus de message d’erreur, mais le code additionnel est neutre car je n’ai pas d’ajout de <br><br> et le résultat est identique au code précédent.
J’ai essayé pour voir de remplacer <br><br> par <p>&nbsp;</p>, mais cela ne change rien et la condition ne passe pas.

Qui peut m’aider ?
Je patauge depuis des heures.
Merci d’avance
A+ Seb

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

19 sept. 2016, 18:15

Bonjour,

Si je comprend bien, le fonctionnement que tu veux mettre en place est le suivant : tu parcours tes enregistrements, tant que $row["Champ2"] garde la même valeur, tu écris à la suite, et dès que $row["Champ2"] change de valeur tu ajoutes un saut de ligne ?

Pour cela il suffit de reprendre ton code initial (enfin celui avec la requête qui exclu les éléments null :)) et d'utiliser une variable temporaire :
$old = ''; // on initialise la variable temporaire à vide
foreach  ($result[1] as $row) { // on boucle
  if ($old!='' && $old!=$row["champ2"]) { // on vérifie ce que contient la variable temporaire
    echo '<br /><br />'; // si on tombe sur une nouvelle valeur de $row["champ2"], on saute des lignes
    $old = $row["champ2"]; // et on met a jour la variable temporaire avec la nouvelle valeur $row["champ2"]; 
  }
  // on affiche ensuite les valeurs souhaitées et on recommence la boucle avec la variable $old qui permet de savoir ce qu'on vient d'afficher
  echo '&nbsp;&nbsp;<a href="mapage.php?ident=' . $row["champ2"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;';
}
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 39 Messages

20 sept. 2016, 17:12

Bonjour Ryle,

Merci beaucoup de reprendre ce fil qui me donne tant de peine.
C'est vraiment très sympa de ta part!

Le code que tu proposes est actif (pas d'erreur) mais ne donne pas le résultat attendu.
Pour mieux comprendre la liste de champ2 ressemble à:
Albert
Albert Ballard
Albert Sand
Albert Tautou
Bernard
Bernard Devienne
Bernard George Calot
Bernard Marie Calot
Bernard Rémi Page
Bernard Vaneau
Claude
Claude Lenard
Claude Marge
David
Eric
Eric Lefort
Fabien
Gérard
Gérard Delorme
Ce que je veux c'est introduire un double <br> quand le 1er mot change (quelque soit le 2ème ou le 3ème à chaque ligne), soit
dans l'exemple ci dessus
entre Albert Tautou et Bernard
entre Bernard Vaneau et Claude
entre Claude Marge et David
entre David et Eric
entre Eric Lefort et Fabien
entre Fabienet Gérard
et ainsi de suite.

C'est plus clair ?

Encore merci et A+
Seb

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

21 sept. 2016, 13:32

salut,

un truc dans le genre
<?php
//récupérer la première partie (avant l'espace)
$debut = substr($row["champ2"], strpos($row["champ2"],''));
if( $debut != $old] {
$old = $debut;
echo '<br /><br />';
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 39 Messages

22 sept. 2016, 12:28

Merci de revnir, Moogli, mais désolé je dois mal interpréter ton instruction <<<//récupérer la première partie (avant l'espace)>>>>>
J’ai corrigé une pétouille : if( $debut != $old) {, à la place de if( $debut != $old] {
Mais malgré cela j’ai une erreur pour tous les résultats:
Warning: strpos(): Empty needle in D:\, etc.
Donc voici le code tel qu’interprété
$old = ''; // on initialise la variable temporaire à vide
foreach ($result[1] as $row) { // on boucle
$debut = substr($row["champ2"], strpos($row["champ2"],''));
if( $debut != $old) {
$old = $debut;
echo '<br /><br />';
echo '&nbsp;&nbsp;<a href="mapage.php?ident=' . $row["champ1"] .'"><i>' . $row["champ2"]. '</i></a>&nbsp;&nbsp;|&nbsp;&nbsp;';
}
J’ai aussi essayé en enlevant la dernière ligne de code ici (echo '&nbsp;&nbsp;<a href=", etc.), mais j’ai toujours le message d’erreur empty needle.
J’ai cherché sur le net l’explication de ce message d’erreur empty needle mais n’ai rien trouvé d’approprié en Français.
Désolé. Cela me dépasse.
A+ Steph
PS: pour être à 100% clair, je reprend ma liste:
Albert
Albert Ballard
Albert Sand
Albert Tautou
Bernard
Bernard Devienne
Bernard George Calot
Bernard Marie Calot
Bernard Rémi Page
Bernard Vaneau
Claude
Claude Lenard
Claude Marge
David
Eric
Eric Lefort
Fabien
Gérard
Gérard Delorme

Et le résultat précis attendu:

Albert (+ lien page web) | Albert Ballard (+ lien page web) | Albert Sand (+ lien page web) | Albert Tautou (+ lien page web) |


Bernard (+ lien page web) | Bernard Devienne (+ lien page web) | Bernard George Calot (+ lien page web) | Bernard Marie Calot (+ lien page web) | Bernard Rémi Page (+ lien page web) | Bernard Vaneau (+ lien page web) |


Claude (+ lien page web) | Claude Lenard (+ lien page web) | Claude Marge (+ lien page web) |

David (+ lien page web) |


Eric (+ lien page web) | Eric Lefort (+ lien page web) |


Fabien (+ lien page web) |


Gérard (+ lien page web) | Gérard Delorme (+ lien page web) |
etc.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

22 sept. 2016, 13:04

suffit de regarder la doc de substr et de voir que j'ai oublié un paramètre (le début) parce que la on prend ce qu'il y après le première espace du coup cela ne fonctionne pas.
C'est bien d'avoir du code, c'est mieux de le comprendre ;)
J'ai aussi oublié la subtilité du fait que strpos retourne zéro mais aussi false et c'est "la même chose" (autoboxing ...). Du coup un cas à prendre en compte.
<?php
header('Content-Type: text/html;encoding: UTF-8');
$tab = ['Albert','Albert Ballard','Albert Sand','Albert Tautou','Bernard','Bernard Devienne','Bernard George Calot','Bernard Marie Calot','Bernard Rémi Page','Bernard Vaneau','Claude','Claude Lenard','Claude Marge','David','Eric','Eric Lefort','Fabien','Gérard','Gérard Delorme'];

$old = '';
foreach ($tab as $key => $value) {
    $p = strpos($value, ' ');
    if ($p === false) {
        $p=strlen($value);
    }
    $debut = substr($value, 0, $p);


    if (!empty($old) && $old != $debut) {
        echo '<br /><br />';
        $old = $debut;
    } elseif (empty($old)) {
        $old = $debut;
    }

    echo $value , ' | ';
}
testé
=>
Albert | Albert Ballard | Albert Sand | Albert Tautou |

Bernard | Bernard Devienne | Bernard George Calot | Bernard Marie Calot | Bernard Rémi Page | Bernard Vaneau |

Claude | Claude Lenard | Claude Marge |

David |

Eric | Eric Lefort |

Fabien |

Gérard | Gérard Delorme |
@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 39 Messages

23 sept. 2016, 17:20

Bonjour Moogli (et indirectement Ryle),
J’ai transposé puis testé et après quelques 2 heures de tâtonnements j’y suis arrivé, notamment en remplaçant $debut par $row["champ2"] (je précise cela pour ceux qui seraient intéressés d’adapter pour leur cas).
Si vous me permettez (modestement) je vous remercie bien sûr mais je suis bien plus à l’aise avec la méthode pédagogique de Ryle, et je le remercie chaleureusement.
Il répond exactement à la question et il ajoute plein de commentaires, ce qui fait que j’ai beaucoup appris et compris et j’ai pu facilement transposer ses soluces à des cas similaires (pour ma demande précédente, il y a 2 mois).
Avec vous et ce dernier script j’ai été jeté à la mer sans savoir nager et je m’en suis quand même sorti, mais je ne peux aller plus loin si (mais ce n’est pas le cas) j’avais des cas similaires.
Et auparavant j’étais carrément dans la mouise.
Sans vouloir vous faire ombrage (vous êtes bénévole et c’est bravo), comme c’est un forum de débutant, j’espère que vous lirez les observations précédentes, humbles, avec intérêt.

Encore merci à tous les 2.
C’est pas facile d’aider les débutants, je sais (je n'abuserai donc pas).

Seb