Optimisation de code

Petit nouveau ! | 8 Messages

12 févr. 2008, 14:59

salut :)
alors je poste pas parce que mon code ne marche pas, mais parce que je le trouve pas optimisé

je suis donc curieux de voir comment des "bons" en php ferait en sorte que ce script s'execute en moins de ligne, si toute fois c'est possible :)

(désolé si le nombre de ligne maximum est dépassé)
<?php
$req = "SELECT * FROM matchs WHERE `airaam` = 1";
$resultat = mysql_query ($req, $connexion);
$airaam = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `yo` = 1";
$resultat = mysql_query ($req, $connexion);
$yo = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `patanch` = 1";
$resultat = mysql_query ($req, $connexion);
$patanch = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `badday` = 1";
$resultat = mysql_query ($req, $connexion);
$badday = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `yeto` = 1";
$resultat = mysql_query ($req, $connexion);
$yeto = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `jey` = 1";
$resultat = mysql_query ($req, $connexion);
$jey = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `yannick` = 1";
$resultat = mysql_query ($req, $connexion);
$yannick = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `isy` = 1";
$resultat = mysql_query ($req, $connexion);
$isy = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `zaza` = 1";
$resultat = mysql_query ($req, $connexion);
$zaza = mysql_num_rows($resultat);


$nom[1] = "zAZa";
$nom[2] = "Isy";
$nom[3] = "Yannick";
$nom[4] = "Airaam";
$nom[5] = "Yeto";
$nom[6] = "Jey";
$nom[7] = "Patanch";
$nom[8] = "Yo";
$nom[9] = "badday";

$num[1] = "$zaza";
$num[2] = "$isy";
$num[3] = "$yannick";
$num[4] = "$airaam";
$num[5] = "$yeto";
$num[6] = "$jey";
$num[7] = "$patanch";
$num[8] = "$yo";
$num[9] = "$badday";

array_multisort($num, SORT_DESC, SORT_NUMERIC,$nom, SORT_STRING);
echo "$nom[0] : $num[0]</br>";
echo "$nom[1] : $num[1]</br>";
echo "$nom[2] : $num[2]</br>";
echo "$nom[3] : $num[3]</br>";
echo "$nom[4] : $num[4]</br>";
echo "$nom[5] : $num[5]</br>";
echo "$nom[6] : $num[6]</br>";
echo "$nom[7] : $num[7]</br>";
echo "$nom[8] : $num[8]</br>";

 ?>
voilà merci de vos futures réponses, histoire que je continue à progresser :)

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

d0m
Mammouth du PHP | 1141 Messages

12 févr. 2008, 15:08

Déjà au départ il semblerait au premier coup d'œil que ta table matchs est mal conçue...

On va pas te l'optimiser mais t'expliquer comment faire.

Déjà pour tes requêtes tu as plusieurs fois la même, juste le champ dans la clause WHERE qui change.
Qui dit répétition dit boucle et tableau.

Tu peux déjà commencer par mettre tous les noms pour tes requêtes dans un tableau $noms par exemple.
Tu déclares un autre tableau $matchs qui contiendra tes valeurs que tu mettais dans tes variables $airaam, $yo,....

Ensuite tu parcours le tableau $noms, tu fais les requêtes dans la boucle et tu mets le résultat dans le tableau $matchs avec comme clé le nom.

Mais en refaisant ta table je pense que tu pourrais faire une seule requête bien plus pratique.

Décris nous ce que tu veux faire précisément?

Eléphant du PHP | 73 Messages

12 févr. 2008, 15:16

<?php
$nom = array("zAZa","Isy","Yannick","Airaam","Yeto","Jey","Patanch","Yo","badday");

foreach($nom as $k=>$n) {
	$req = "SELECT * FROM matchs WHERE `{$n}` = 1";
	$resultat = mysql_query ($req, $connexion);
	$num[$k] = mysql_num_rows($resultat);
}


array_multisort($num, SORT_DESC, SORT_NUMERIC, $nom, SORT_STRING);

foreach($nom as $k=>$n) {
	echo "{$n} ... {$num[$k]}<br>";
}
?>
On aurait pu l'optimiser comme ça ton code. Mais c'est vrai que ta BDD est bizarre. Si c'est important les minuscules pour le nom dans la requête, alors il faut utiliser lowercase().
Modifié en dernier par Sedril le 12 févr. 2008, 15:18, modifié 1 fois.
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

12 févr. 2008, 15:17

Effectivement, ta table est mal concue puisque chaque colonne représente une données.

Il vaudrait mieux une colonne (disons "categorie") qui contiendrais airaam, yo, patanch, ... en tant que valeur.

Du coup, tu pourrais utiliser une requête du genre

Code : Tout sélectionner

SELECT categorie, COUNT(1) FROM match GROUP BY categorie
Cette requête te retourne le nombre d'enregistrement correspondants à chaque catégorie.

En plus d'optimiser le fonctionnement, l'amélioration que nous te donnons permettre l'évolutivité de ton code puisque l'ajout d'une nouvelle catégorie ne demandera pas de modification du code source ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Petit nouveau ! | 8 Messages

12 févr. 2008, 15:26

re
ca c'est du rapide au niveau de la réponse ! :)

alors déjà ton principe de tableau et de faire une boucle sur la requête ça m'intéresse pas mal, si tu pouvais détailler un peu en prenant un exemple concret

ensuite pour la table je suis certain que mes tables manquent surement de logique :(

en fait quand je rentre un match sur le site j'indique le nom des joueurs ayant participé au match
j'ai donc un formulaire avec des cases à cocher ou non

airaam []
yo []
patanch []

et la je fait brut de pomme, c'est à dire j'appelle la case à cocher airaam "case_airaam" et si elle est cochée la valeur est 1 sinon 0
donc dans la table il y'a un champ qui s'appelle "case_airaam" et j'y insère une valeur 1 ou 0

et ca se passe comme ca pour les 9 joueurs de l'équipe.....
je me doute bien qu'il doit y avoir quelque chose de plus efficace mais en farfouillant sur le web j'ai rien trouvé de très clair

voila un screen de ma table

Image

EDIT : Alors en finissant mon post je viens de voir 2 réponses entre temps :)

merci sedril, c'est exactement ça que j'imaginai en parlant d'optimisation :)

pour cette fonction
foreach($nom as $k=>$n) {
    $req = "SELECT * FROM matchs WHERE `{$n}` = 1";
    $resultat = mysql_query ($req, $connexion);
    $num[$k] = mysql_num_rows($resultat);
}
ca veut dire que pour chaque entrée du tableau, il va faire la requête en incrémentant la valeur et il réinsère dans le tableau $num, c'est bien ca?


pour zeus : la j'avoue que j'ai du mal à te suivre :oops:
si tu pouvais détailler un chouille :)
Modifié en dernier par airaam le 12 févr. 2008, 15:36, modifié 1 fois.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

12 févr. 2008, 15:33

Effectivement, il y a un énorme problème de conception.

Pour marquer quels joueurs ont participés à quels matchs, il te faut 3 tables :
Une table "match" qui ne contient que les données du matchs (adversaire, score, ...)
Une table "joueur" qui contient les données des différents joueurs (id, pseudo)
Une table "participe" qui contient l'association entre un match et un joueur.

Sinon, le principe du tableau donnera un code moins long en nombre de caractères, mais pas plus optimisé puisque tu feras autant de requête, autant de récupération, ...
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 73 Messages

12 févr. 2008, 15:34

Le code, c'est une chose, la structure de la bdd une autre. Tout dans ton programme repose sur une seule table :( C'est pas bon, il faut essayer de regrouper les informations sur plusieurs entités.

Par exemple :

joueur (id_joueur, pseudo, email)
equipe (id_equipe, nom)
map (id_map, nom)
partie (id_joueur, id_equipe, id_map, date, score)

On reviendra sur la partie code plus tard. Essaye d'adapter ta BDD ou alors expose les informations de ta table avec leurs significations. On peut t'aider à rassembler les infos et trouver les entités.
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

ViPHP
ViPHP | 2144 Messages

12 févr. 2008, 15:36

Je crois qu'il faut se poser les "bonnes questions":
Que se passera-il si un jour il y a beaucoup plus de joueurs qu'actuellement ?
Comment faire en sorte de pouvoir ajouter un nouveau joueur, sans devoir modifier la structure de la base de donnée, et le code de l'application ?
A partir du moment où la base de donnée possède une bonne structure, on ne rencontre pas de grosses difficultés à programmer un code efficace.

Petit nouveau ! | 8 Messages

12 févr. 2008, 15:47

oula j'ai pas l'habitude que ca réponde aussi vite sur un forum :)

jvai essayer de résumer vos remarques

en gros vous me dites qu'il faudrait faire

table match
id_match
adversaire
score
map1
map2
screen1
screen2
screen3
screen4
date

table joueur
id_joueur
pseudo


je vois l'interet de séparer les deux tables, effectivement si un nouveau joueur rentre dans l'equipe (ce qui ne sera pas le cas, mais parlons concret :) ), pas besoin d'ajouter un nouveau champ

le coup de la table "participe" je comprend à peu près son intérêt mais je vois pas trop comment la faire intervenir

je pense que le formulaire me permet de rentrer toutes les infos nécessaire à table match, dans le formulaire je récupère dynamiquement le contenu de table joueur et c'est table participe qui va contenir les noms de ceux qui ont fait le match?

on aurait donc une table participe
id_participe
id_match
id_joueur

mais le champs id_joueur va contenir plusieurs entrées, faudra donc que j'insère un ";" (par ex) pour pouvoir séparer les valeurs ?

ai je capter la logique ?
et le plus important, avez vous capté la mienne ? :D

Eléphant du PHP | 73 Messages

12 févr. 2008, 15:50

la table participe ressemblerait plutot à cela :

id_match
id_joueur

ce qui donne avec un cas concret pour : match 1, joueurs 2, 5 et 7

on insère dans la table participe

1,2
1,5
1,7

Comme cela on peut trouver les joueurs qui ont participé au match 1 avec la requête :

Code : Tout sélectionner

SELECT id_joueur FROM participe WHERE id_match = 1
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

Petit nouveau ! | 8 Messages

12 févr. 2008, 16:03

ah ben oui...que chui con...

donc je commence à cerner la modification que je dois apporter à mes tables

si je dois faire une requète pour calculer le nombre de fois où j'ai fai un match par exemple
et que je suis le joueur avec l'id 1

la requète sera du genre

SELECT count(*) FROM participe WHERE id_joueur = 1

et la pour eviter de retomber dans la succession de requete je refait le code optimiser avec le foreach?

ViPHP
ViPHP | 2144 Messages

12 févr. 2008, 16:04

Et tout aussi simplement compter le nombre de match auxquels chaque joueur à participé, avec une seule requête ;)

Eléphant du PHP | 73 Messages

12 févr. 2008, 16:09

et la pour eviter de retomber dans la succession de requete je refait le code optimiser avec le foreach?
Tu fais une requête du genre :

Code : Tout sélectionner

SELECT count(*), id_joueur FROM participe GROUP BY id_joueur
Ca ramènera 1 ligne par joueur et te donnera le nombre de participation à un match. Il faudra parcourir les enregistrements ramenés par la requête.
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

Petit nouveau ! | 8 Messages

12 févr. 2008, 16:10

oui mais alors la je suis perdu des étapes à suivre au niveau du code :?

il faut recuperer les pseudos des joueurs et les id_joueurs
les mettre dans deux tableaux
faire un foreach comme indiqué ci-dessus

j'ai bon??[/php]

Eléphant du PHP | 73 Messages

12 févr. 2008, 16:13

Non, le code n'est plus adapté à la structure de la BDD maintenant, il faut réécrire. La requête ci-dessus ramènera N lignes à parcourir. Elles contiendront tous les joueurs ainsi que leur nombre de participation à un match.

Tu n'as donc pas besoin de préciser les noms des joueurs.
Image Un bon maître a ce souci constant : enseigner à se passer de lui.