multiplication de requete

Mammouth du PHP | 601 Messages

06 févr. 2007, 21:44

On n'a souvent besoin de créer plusieurs requetes sur la même page, voici une méthode sans jointure mais avec une fonction, l'important (je trouve) c'est la méthode :
ce script me permet de sélectionner des rubriques puis des liens (champ page) :
je boucle les rubriques
et dedans je boucle les pages à chaque rubrique trouvée donc pour ça je fait une fonction.
avec comme paramètre une requette
le résultat est visible ici
http://creatif-web.be/developpeur/boucle_test.php
pour la table

Code : Tout sélectionner

CREATE TABLE `pages` ( `page` varchar(20) NOT NULL default '', `description` text NOT NULL, `rubrique` varchar(250) NOT NULL default '', PRIMARY KEY (`page`), UNIQUE KEY `page` (`page`) );
ce qui donne :
Image
<ul>
<?php 
include ("inc/connexion.php");
// DISTINCT supprime les doublons
$r="SELECT DISTINCT rubrique FROM pages";
$requete=mysql_query($r, $lien);
while($bou= mysql_fetch_array($requete))
{	
	echo '<li><strong>'.$bou['rubrique'].'</strong></li>';
	$ttt=$bou['rubrique'];
	$query = "SELECT * FROM pages WHERE rubrique='$ttt'";
	//on lance la fonction avec la deuxième requete $query
	$page=query_page($query);
	if($ttt == $page) 
	{
       // on affiche les les sous rubriques qui correspondent aux pages
	echo '<li>'.$ok['page'].'</li>';
	}
}
// fonction avec en paramètre la requete ce qu'il laisse une grande largesse
function query_page($query)
{
include ("inc/connexion.php");
$result = mysql_query($query, $lien);
 	if (!$result)
	{
		return('');
	}
	while($ok= mysql_fetch_array($result))
	{
		echo '<li>'.$ok['page'].'</li>';
	}
}
?>
</ul>
J'ajouterai que sa permets d'avoir des liens dynamique
Des questions, des améliorations ?
Modifié en dernier par artotal le 07 févr. 2007, 00:30, modifié 2 fois.
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

Modérateur PHPfrance
Modérateur PHPfrance | 7636 Messages

06 févr. 2007, 22:08

Au final ça fait tout de même beaucoup de requêtes...

surtout sur ce passage :
$query = "SELECT * FROM pages WHERE rubrique='$ttt'";
    $page=query_page($query);
    if($ttt == $page) 
    {
    //on lance la fonction avec la deuxième requete $query
    echo '<li>'.query_page($query).'</li>';
    } 
Appeler deux fois de suite la fonction avec la même requête :?

Au final ça ressemble un peu à ça

/!\ Avant de poster se documenter et rechercher.
Qui ne sait pas rendre un service n'a pas le droit d'en demander.
MaBrute

Mammouth du PHP | 601 Messages

06 févr. 2007, 22:51

oui mais pas du tout, en faite grace à DISTINC qu'on peux pas mettre dans plusieurs requete
SELECT DISTINC un_seul_champ FROM ....
et la plupart des requete sont sur les select.
De plus j'élimine les doublons dans la colonne rubrique ensuite je sélectionne tous les enregistrements dans page qui ont comme valeur la même rubrique.
Je me suis fouillé pour trouver une astuce.
Mais surtout je montre qu'on peux très bien appelé une autre table dans la fonction. Ce qui peut être utile pour développer un cms comme se que je fais en ce moment.
J'essaie de comprendre se que tu me dit quand même.
Sa me permet de comparer mais je regarde le post
le résultat est visible sur le bouton WWW
Le menu de gauche
edit
j'ai retirer la fonction c'était une erreur de ma part, donc je ne l'apelle qu'une fois
et je remplace le deuxième appel par
$ok['page']
Et là on voit tout l'intèret d'une fonction :D
Modifié en dernier par artotal le 06 févr. 2007, 23:10, modifié 3 fois.
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

Mammouth du PHP | 1511 Messages

06 févr. 2007, 22:59

Ce que je fais généralement, c'est une requete pour selectionner les blocs, puis une requete pour selectionner les items.
Je fais une boucle sur les items pour les classer dans des tableaux avec comme index quelque chose relatif au bloc parent, et ensuite, il me suffit juste de faire ma boucle avec les blocs en prenant soient de prendre les bons blocs dans le tableau.

Mammouth du PHP | 601 Messages

07 févr. 2007, 00:41

et donc quand on retire la fonction dans un fichier externe "fonction.php" ce que je fais
il reste pas grand chose en code :
<ul>
<?php 
include ("inc/connexion.php");
include ("inc/fonction.php");
$r="SELECT DISTINCT rubrique FROM pages";
$requete=mysql_query($r, $lien);
while($bou= mysql_fetch_array($requete))
{    
    echo '<li><strong>'.$bou['rubrique'].'</strong></li>';
    $ttt=$bou['rubrique'];
    $query = "SELECT * FROM pages WHERE rubrique='$ttt'";
    $page=query_page($query);
    if($ttt == $page) 
    {
          //le résulatat afficher est préparé dans la fonction
    }
}
?>
Modifié en dernier par artotal le 08 févr. 2007, 03:20, modifié 1 fois.
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

Mammouth du PHP | 601 Messages

08 févr. 2007, 03:19

je m'interroge sur l'amélioration de ce script et après coup, dans le test lorsque je retire
  
    if($ttt == $page) 
    {
          echo '<li>'.$ok['page'].'</li>';
          //le résulatat afficher est préparé dans la fonction
    } 
	$page=query_page($query);
	if($ttt == $page)
	{
	}
Et bien ça fonctionne.
Je ne trouve pas ça très élégant.
edit :
	($ttt == $page)? true : false; 
Est ce que le test ternaire est meilleurs que le if ?
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

Mammouth du PHP | 601 Messages

08 févr. 2007, 17:25

@momox
pourrai tu illustrés avec du code ;)
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

08 févr. 2007, 18:37

Deux choses importantes : on ne met jamais jamais jamais jamais jamais de requêtes dans une boucle. Peu importe les circonstances, s'il y une requête SELECT au milieu d'une boucle il y a un problème. Autre point important, mysql_fetch_array() est l'une des fonctions de PHP que je déteste le plus : mysql_fetch_assoc() ou mysql_fetch_row(), point.

Voici un exemple de comment remplacer ces requêtes à répétition par quelque chose de beaucoup plus efficace. Oops, c'est le moment où je m'apprêtais à copier/coller le code dans mon éditeur quand je me suis aperçu que tu utiliser "DISTINCT rubrique" pour la liste des rubriques :-s La liste des rubriques elle est facile à trouver, elle est dans la table rubriques. Et si tu n'as pas de table rubriques alors c'est le moment de revoir ton site. Au final:
$sql = 'SELECT rubrique_id, rubrique_titre
        FROM rubriques
        ORDER BY rubrique_ordre';
$result = mysql_query($sql, $db);

$titres = array();
while ($row = mysql_fetch_assoc($result))
{
	$titres[$row['rubrique_id']] = $row['rubrique_titre'];
}
mysql_free_result($result);

$sql = 'SELECT p.*
        FROM pages p
        JOIN rubrique r USING (rubrique_id)
        ORDER BY r.rubrique_ordre';
$result = mysql_query($sql, $db);

$id = -1;
while ($row = mysql_fetch_assoc($result))
{
	if ($row['rubrique_id'] != $id)
	{
		$id = $row['rubrique_id'];
		echo '<li><strong>', $titres[$id], '</strong></li>';
	}

	echo '<li>', $row['page'], '</li>';
}
mysql_free_result($result);
Si la seule chose que l'on affiche concernant la rubrique est le titre alors on pourrait imaginer le récupérer dans la seconde requête et éliminer la première.

Au fait, c'est quoi connexion.php et pourquoi tu l'inclues à chaque requête ? :-s

Mammouth du PHP | 601 Messages

08 févr. 2007, 19:25

C'est excellent là je vois beaucoup plus clair sur les différentes entre ces trois fonctions.
mysql_fetch...();
Jusqu'à présent s'utilisait ces fonctions, sans vraiment réfléchir
Ainsi je comprend mieux l'acharnement de Cyrano et autre mamouth à utiliser des tableaux à plusieurs dimensions. En émétant des doutes sur mes petites compétences je trouvais ça compliqué
tu m'as convaincus ;)
Par contre là :

Code : Tout sélectionner

on ne met jamais jamais jamais jamais jamais de requêtes dans une boucle
j'ai du mal à saisir la raison ?
j'ai vraiment du mal à tout comprendre, c'est vrai que l'idée de metre une table rubrique à la place du champs ma traversé l'esprit, avec ma méthode je peux le faire
Pourrai tu mettre des commentaires pour illustrer ton code s'il te plait, à partir de là.
$titres[$row['rubrique_id']] = $row['rubrique_titre'];
La connexion si je ne l'inclus pas dans dans la fonction, elle ne fonctionne pas !
C'est la zone d'ombre.
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

ViPHP
ViPHP | 928 Messages

08 févr. 2007, 20:11

La raison pour laquelle on ne met pas de requêtes dans une boucle c'est que les jointures sur les tables sont là pour faire ce boulot. Imagines si ton menu a 10 catégories : ça te fera 10 requêtes alors que 1 seule aurait suffit. Pour des raisons de performances donc, et aussi de propreté.

Mammouth du PHP | 601 Messages

09 févr. 2007, 02:46

implacable ton raisonnement.
Il me faudrai une bonne vingtaine de tuto sur les jointures pour être à l'aise avec, j'ai encore des velléités.
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

ViPHP
ViPHP | 928 Messages

09 févr. 2007, 13:26

En fait si tu prends une table catégorie et une table forum, toi ce que tu fais c'est que tu fais une requête qui sélectionne toutes les catégories, tu fais une boucle et dans ta boucle tu fais une requête qui sélectionne les forums de la catégorie courante, un truc du genre :

Code : Tout sélectionner

$sql = 'SELECT cat_id FROM categorie'; $result = mysql_query($sql) OR die('erreur sql'); while ($row = mysql_fetch_assoc($result)) { $sql = 'SELECT * FROM forums WHERE cat_id = ' . $row['cat_id']; // etc ... }
alors que faire simplement :

Code : Tout sélectionner

SELECT c.*, f.* FROM categories c, forums f WHERE f.cat_id = c.cat_id
aurait suffit ;)

Mammouth du PHP | 601 Messages

10 févr. 2007, 18:22

ce que tu donnes ne fait rien, même ce qui est donné plus haut me fait douter :
les rubriques sont en gras :
http://creatif-web.be/mysql/index.php
<?php 
include ("inc/connexion.php");
// DISTINCT supprime les doublons
$r = 'SELECT pages.*, rubrique.*
        FROM pages, rubrique
	   WHERE pages.rubrique_page=rubrique.rubrique';
$requete=mysql_query($r, $lien);
while($bou= mysql_fetch_assoc($requete))
{	
	echo '<strong>'.$bou['rubrique_page'].'</strong><br />'.$bou['page'].'<br />';
}
mysql_free_result($requete);
?>

Code : Tout sélectionner

CREATE TABLE `rubrique` ( `rubrique_id` int(11) NOT NULL auto_increment, `rubrique` varchar(250) collate latin1_general_ci default NULL, PRIMARY KEY (`rubrique_id`), UNIQUE KEY `rubrique_id` (`rubrique_id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; CREATE TABLE `pages` ( `page` varchar(20) collate latin1_general_ci NOT NULL default '', `description` text collate latin1_general_ci NOT NULL, `rubrique_page` varchar(250) collate latin1_general_ci NOT NULL default '', PRIMARY KEY (`page`), UNIQUE KEY `page` (`page`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Sa n'affiche en aucun cas les rubriques unique et ensuite les sous-menus ---¿<?¿>
Faudrai peut être pas se raconter d'histoire
Par contre Hubert Roksor donne une soluion, mais je ne comprend pas le jeux de tableaux multidimentionnel ?
http://xavier-artot.com
¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·²°'´¨'°-.,¸¸,.-·°'´¨
système d'exploitation "Ubuntu 7.10"

x@v
Mammouth du PHP | 570 Messages

26 févr. 2007, 21:53

de toute façon on se sert des index et les jointures, bof. Sa prend trod de ressources.
En vitesse d'execution la jointure c'est la pire solution.

ViPHP
ViPHP | 928 Messages

01 mars 2007, 13:32

En vitesse d'execution la jointure c'est la pire solution.
:roll:

Créé une table "employes" avec 1000 employés.
Créé une table "opérations commerciales" avec 500 000 opérations commerciales.
Récupère moi les opérations bancaires faites par chaque employés, le tout regroupé par employé bien sur.

Compare le fait de faire 1 requète SQL avec jointure, et faire 1000 requètes (bah oui une par employer).