8768 sujets

Développement web côté serveur, CMS

Bonjour à vous tous,

Considérons le script PHP suivant permettant de récupérer les données dans une table PHPMyAdmin :


<?php
	$mysqli = new mysqli('localhost', 'root', '', 'projet_modeles');
	$result = $mysqli->query('SELECT ville_id, ville_nom FROM villes');
	while($row = $result->fetch_array()){
		$villes[$row['ville_id']] = $row['ville_nom'];
		echo '<ul>';
		foreach($villes as $id => $ville){
			echo '<li>' . $id . ' - ' . $ville . '</li>';
		}
		echo '</ul>';
	}
	$result->free();
	$mysqli->close();
	?>

Je ne comprends pas bien l'utilité d'ajouter une seconde boucle dans la première boucle, surtout que la première récupérait déjà les données de la table et les affichait. Mes cours parlent d'optimisation du code dans le sens où on créé un nouveau tableau de données avec $villes dont la portée globale permettra son utilisation après la boucle while. C'est du chinois pour moi, quelqu'un saurait m'expliquer plus clairement ?

Et pourquoi le résultat est le suivant avec la répétition des listes ?
upload/1653109000-62242-capturedancran2022-05-2106562.png

Merci pour votre aide.
Modifié par ObiJuanKenobi (21 May 2022 - 16:45)
Modérateur
Hello,

Je ne sais pas d'où vient ton code, mais en effet, il n'est pas optimisé. Ensuite, la répétition doit venir du fait, que l'élément <ul> est imbriqué dans ta première boucle.

*code fait de tête. Il se peut qu'il y ait une pétouille

<?php
    $mysqli = new mysqli('localhost', 'root', '', 'projet_modeles');
    $result = $mysqli->query('SELECT ville_id, ville_nom FROM villes');
    $rows = $result->fetch_array();
    echo '<ul>';
    forerach($rows as $row){
        extract($row);
        printf('<li>%s-%s</li>', $ville_id, $ville_nom);
    }
    echo '</ul>';
    $result->free();
    $mysqli->close();
?>


ps :
- Les printf family donne un code plus propre et plus lisible de ce fait (Déjà que php a une syntaxe bien dégueu…)
- extract est bien utile dans ce cas...
Modifié par niuxe (22 May 2022 - 15:03)
Merci niuxe pour tes explications.

Ce code vient de mes cours, j'apprends le PHP. Je ne comprends pas les fonctions printf(); et extract(); car je ne les ai pas abordées pour le moment dans mes cours. Je ne suis qu'au stade de l'initiation sur la création de bases de données.

Il n'y a pas une explication, quand à la répétition des données, en tenant compte juste du code présenté au début ?

Ce sript écrit de cette manière ne répète plus les données :

while($row = $result->fetch_array()){
		$villes[$row['ville_id']] = $row['ville_nom'];
		echo '<ul>';
		echo '<li>' . $row['ville_id'] . ' - ' . $row['ville_nom'] . '</li>';
		echo '</ul>';
	}

Modifié par ObiJuanKenobi (23 May 2022 - 07:16)
Modérateur
php.net est ton ami. Lorsque tu ne connais pas une fonction de la librairie standard, aie le réflexe d'aller sur php.net. En général, la doc officielle est bien faite.

Exemple complémentaire à extract()


<?php
	$user = [
    	'prenom' => "Denis",
    	'nom' => "Michu",
      	'age' => 48,
      	'cheveux' => "blond",
      	'taille' => 175
    ];

	extract($user);
	
	echo $prenom." ".$nom." est âgé de ".$age." ans. Sa taille est de ".$taille."cm et la couleur de ses cheveux est ".$cheveux.".";

?>


exemple complémentaire à printf():

<?php
	$len_monkeys = 3;
	$fruits = "bananes";
	printf("%d singes mangent des %s", $len_monkeys, $fruits);
?>
Tu n'as pas compris niuxe ! Je suis débutant, j'apprends le PHP, j'ai commencé il y a à peine 3 semaines et tu veux déjà que je saute les étapes pour apprendre ce qui n'est pas abordé pour le moment dans mes cours ? En ce moment, j'apprends à créer une base de données, avec PHPMyAdmin, contenant une simple table avec seulement 3 champs, à modifier le contenu de cette table et à afficher les données dans une page HTML au moyen d'un script PHP. Et je cherche juste une explication au pourquoi du comportement d'un script PHP mais tu préfères me proposer d'utiliser d'autres fonctions, qui te sont plus appropriées pour toi, mais qui ne sont pas à ma porté pour le moment car non abordées dans mes cours.

C'est comme si tu disais à un enfant de CP de ne pas hésiter à consulter un dictionnaire pour apprendre de nouveaux mots (parce que c'est, soi disant, son ami) alors qu'il vient tout juste de commencer à apprendre l'alphabet.

Je te suis reconnaissant de me donner des exemples d'utilisation des fonctions extract et printf mais cela ne répond pas à ma question du début qui est "pourquoi la boucle foreach optimise la boucle while ?" parce que c'est ce qui est écrit dans mes cours. Tu me dis que ce n'est pas du tout optimisé et qu'il aurait mieux valut que j'utilise les fonctions extract et printf mais ces deux fonctions ne sont pas abordées dans mes cours de débutant, pour l'instant. Plus tard, quand j'aborderai le PHP plus évolué, je les apprendrai certainement. Mais pour le moment, je préfère m'en rester à mes cours plutôt que de m'éparpiller et m'embrouiller l'esprit avec d'autres fonctions.
Modifié par ObiJuanKenobi (23 May 2022 - 16:02)
Bonjour !

Effectivement selon moi les deux boucles ne devraient pas être imbriquées.
La boucle while te permet de stocker tes données dans la variable $villes en tant que tableau (array).
Tu auras alors une variable à portée globale dont tu pourras ensuite afficher le contenu, comme par exemple ici en affichant une liste format HTML (<ul>, <li>).

Il suffirait de déplacer une accolade de ton code et ça donnerait ceci :

$mysqli = new mysqli('localhost', 'root', '', 'projet_modeles');
$result = $mysqli->query('SELECT ville_id, ville_nom FROM villes');

// Stockage des données dans la variable $villes
while($row = $result->fetch_array()){
	$villes[$row['ville_id']] = $row['ville_nom'];
}

// Affichage sous forme de liste HTML de la variable $villes
echo '<ul>';
foreach($villes as $id => $ville){
	echo '<li>' . $id . ' - ' . $ville . '</li>';
}
echo '</ul>';

$result->free();
$mysqli->close();


Si au lieu de mettre en forme, tu veux simplement vérifier que tes données ont correctement été stockées dans la variable, tu peux utiliser la fonction PHP print_r comme ceci :
print_r ($villes);


J'espère que ça aura répondu à ta question Smiley smile
Merci CelticKiwi.

Mon cours m'explique étape par étape comment créer une table, récupérer et afficher les données dans une page HTML. Il commence par utiliser la boucle while et plus loin il précise que les données ne s'affichent que dans le contexte de la boucle while. Pour pouvoir utiliser les données dans un contexte global, il faut utiliser la boucle foreach. C'est ça qui me tracassait parce que la boucle while affichait déjà les données.

J'ai résolu mon problème de répétition des données en plaçant les données dans un tableau (<table>) au lieu de demander un affichage par echo et concaténation.
Modérateur
ObiJuanKenobi a écrit :
Tu n'as pas compris niuxe ! Je suis débutant, j'apprends le PHP, j'ai commencé il y a à peine 3 semaines et tu veux déjà que je saute les étapes pour apprendre ce qui n'est pas abordé pour le moment dans mes cours ?
...

J'ai bien saisie que tu es débutant. (ce n'est pas un problème en soit. Tout le monde l'a été un jour Smiley cligne )

ObiJuanKenobi a écrit :
En ce moment, j'apprends à créer une base de données,

Sache que le sujet est énorme (il suffit de compter le nombre de livres sur le SQL comparer au php ou un autre langage Smiley cligne ). CREATE TABLE ne suffit pas à faire les choses correctement. Mais, ça tu le verras peut être plus tard.

ObiJuanKenobi a écrit :
mais tu préfères me proposer d'utiliser d'autres fonctions, qui te sont plus appropriées pour toi, mais qui ne sont pas à ma porté pour le moment car non abordées dans mes cours.

Elles ne sont pas plus appropriées. Ton exemple initiale essaie maladroitement d'émuler extract (une boucle de trop (qui ne sert à rien !) pour sortir des variables).
tu sais, je ne fais plus de php depuis un moment. Mais j'en ai fait pendant pas mal d'années (16 ans).

ObiJuanKenobi a écrit :

C'est comme si tu disais à un enfant de CP de ne pas hésiter à consulter un dictionnaire pour apprendre de nouveaux mots (parce que c'est, soi disant, son ami) alors qu'il vient tout juste de commencer à apprendre l'alphabet.

ton exemple est erroné. Si tu veux un exemple analogue : Tu apprends à lire et écrire et je te donne du vocabulaire pour t'enrichir intellectuellement. Quand on ne connait pas un mot, on consulte le dictionnaire. Pour ton sujet, il te suffit de deboguer (!) et de lire la doc que je t'ai joins dans ma réponse (les liens vers la doc officielle).

ObiJuanKenobi a écrit :

Je te suis reconnaissant de me donner des exemples d'utilisation des fonctions extract et printf mais cela ne répond pas à ma question du début qui est "pourquoi la boucle foreach optimise la boucle while ?" parce que c'est ce qui est écrit dans mes cours. Tu me dis que ce n'est pas du tout optimisé et qu'il aurait mieux valut que j'utilise les fonctions extract et printf mais ces deux fonctions ne sont pas abordées dans mes cours de débutant, pour l'instant. Plus tard, quand j'aborderai le PHP plus évolué, je les apprendrai certainement. Mais pour le moment, je préfère m'en rester à mes cours plutôt que de m'éparpiller et m'embrouiller l'esprit avec d'autres fonctions.


Ça n'a pas de sens ce que tu dis. Plus tard, tu te retrouves avec une syntaxe similaire, tu ne vas pas dire, ah bah, je ne l'ai pas appris dans mes cours alors, je ne regarde pas.

Sur alsacreations, tu apprends à t'améliorer. C'est le but de ce forum. Par la suite, quand tu as des connaissances, même petites, tu peux aider les autres !. Nous les modérateurs apportons souvent une plus value. On va souvent au delà des cours. ça permet aux membres plus juniors d'apprendre et surtout de comprendre les concepts qui ne sont pas toujours mis en avant dans les formations.

Ce qui m'a frappé lorsque j'ai découvert cette communauté, c'était la connaissance même sur un sujet aussi basique que le HTML. Parce que le HTML est un langage extrêmement riche.

Pour revenir à ton sujet :

<?php 
//...
$rows = $result->fetch_array();
echo '<ul>';
forerach($rows as $row){
    echo '<li>'.$row['ville_id'].'-'.$row['ville_nom'].'</li>';
}
echo '</ul>';
?>


ps : la différence qu'il y a entre while/for et foreach est que tu as un controle sur les clefs dans certains cas (foreach($var as $key => $value)...) De mémoire, foreach fait une copie en interne du tableau à parser (mais ça c'est à confirmer)
Modifié par niuxe (24 May 2022 - 08:16)