8792 sujets

Développement web côté serveur, CMS

Pages :
Hello,

j'ai un ptit problème de logique, j'essai d'optimiser ce code mais j'arrive pas :

if (isset($_GET)) {
		$year =  'YEAR(date) = \''.$_GET['annee'].'\' ';
		$month = 'MONTH(date) = \''.$_GET['mois'].'\' ';
		$day = 'DAYOFMONTH(date) = \''.$_GET['jour'].'\' ';
		$with_year = 'AND '.$year;
		$with_month = 'AND '.$month;
		$with_day = 'AND '.$day;
		if (isset($_GET['annee']) && ($_GET['annee'] != 'année')) {
			if (isset($_GET['mois']) && ($_GET['mois'] != 'mois')) {
				if (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
					$period = 'WHERE '.$year.$with_month.$with_day;
				}
				else { $period = 'WHERE '.$year.$with_month; }
			}
			elseif (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
				$period = 'WHERE '.$year.$with_day;
			}
		else { $period = 'WHERE '.$year; }
		}
		elseif (isset($_GET['mois']) && ($_GET['mois'] != 'mois')) {
			if (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
				$period = 'WHERE '.$month.$with.$with_day;
			}
			else { $period = 'WHERE '.$month; }
		}
		elseif (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
			$period = 'WHERE '.$day;
		}
	        else { $period = ''; }
}


toute proposition est bienvenue
Modifié par ChrisG (02 Nov 2006 - 10:08)
Bonjour.

Une suggestion :


$y = (isset($_GET["annee"])) ? "YEAR(date) = '" .  $_GET["annee"]  . "'" :"";
$m = (isset($_GET["mois"])) ? "MONTH(date) = '" .  $_GET["mois"] . "'" :"";
$d = (isset($_GET["jour"])) ? "DAYOFMONTH(date) = '" .  $_GET["jour"] . "'" :"";

$where = (count($_GET) > 0) ? "WHERE" : "";

$first_and = (count($_GET) > 1) ? "AND" : "";
$second_and = (count($_GET) > 2) ? "AND" : "";

$period = "$where $y $first_and $m $second_and $d";



... L'usage de $variable = (condition) ? "valeur si vrai" : "valeur si faut";

est un puissant simplificateur.
Modifié par GeorgesM (02 Nov 2006 - 10:28)
GeorgesM a écrit :
... L'usage de $variable = (condition) ? "valeur si vrai" : "valeur si faut";
est un puissant simplificateur.

Pour un habitué, c'est une question de lecture, c'est tout.
Par contre, l'utilisation de l'opérateur ternaire n'est pas forcément une bonne solu pour un deb.
voilà j'ai un peu optimisé mais on dirait que c'est difficile de faire plus :
if (isset($_GET)) {
		if ( (isset($_GET['annee']) && ($_GET['annee'] != 'année')) || (isset($_GET['mois']) && ($_GET['mois'] != 'mois')) || (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) ) {
			$period = 'WHERE ';
			if (isset($_GET['annee']) && ($_GET['annee'] != 'année')) {
				$period .= 'YEAR(date) = \''.$_GET['annee'].'\' '; 
				if (isset($_GET['mois']) && ($_GET['mois'] != 'mois')) {
					$period .= ' AND MONTH(date) = \''.$_GET['mois'].'\' ';
					if (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
						$period .= 'AND DAYOFMONTH(date) = \''.$_GET['jour'].'\' ';
					}
				}
			}
			elseif (isset($_GET['mois']) && ($_GET['mois'] != 'mois')) {
				$period .= 'MONTH(date) = \''.$_GET['mois'].'\' ';
				if (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
					$period .= 'AND DAYOFMONTH(date) = \''.$_GET['jour'].'\' ';
				}
			}
			else { $period .= 'DAYOFMONTH(date) = \''.$_GET['jour'].'\' '; }
		}
		else { $period = ''; }
	}

	if (!$query = mysql_query('SELECT * FROM member '.$period.'ORDER BY `member`.`date` DESC LIMIT '.$debut.' , '.$ratio_articles.'', $link)) {
	echo "Impossible de sélectionner la table : ".mysql_error()."<br />\n";
	}


GeorgesM ton code m'a l'air super mais il fonctionne pas : count($_GET) donne toujours 5 (il y a 2 autres éléments de formulaires) car il y a toujours des valeurs selectionnées par défaut.

Le code complet est ici !
http://goirand.christophe.free.fr/weeb/DB_PHP.php.zip
Modifié par ChrisG (02 Nov 2006 - 16:58)
Si on ne peux pas contrôler le nombre de $_GET, il suffisait de modifier comme suit :


<?php

$t=array();
if (isset($_GET["annee"])) $t[] = "YEAR(date) = '" .  $_GET["annee"]  . "'" ;
if (isset($_GET["mois"])) $t[] = "MONTH(date) = '" .  $_GET["mois"]  . "'" ;
if (isset($_GET["jour"])) $t[] = "DAYOFMONTH(date) = '" .  $_GET["jour"]  . "'" ;

$where = (count($t) > 0) ? "WHERE " : "";
$first_and = (count($t) > 1) ? " AND " : "";
$second_and = (count($t) > 2) ? " AND " : "";

$period = $where.$t[0].$first_and.$t[1].$second_and.$t[2];

?>


C'est quand même plus simple, non ?
Bison a écrit :

Pour un habitué, c'est une question de lecture, c'est tout.
Par contre, l'utilisation de l'opérateur ternaire n'est pas forcément une bonne solu pour un deb.


Pourquoi ?
Parce que la structure conditionnelle saute moins aux yeux que dans un if else classique.

J'ai une question au posteur :
- pourquoi ce passage de tant de variable en GET ?

parce que là, on n'a qu'un visu tronqué du script, donc d'où viennent les valeurs ?
Modifié par Bison (02 Nov 2006 - 17:35)
a écrit :
Parce que la structure conditionnelle saute moins aux yeux que dans un if else classique.


Dans, ce cas, que diriez-vous devant une structure switch ? Parce qu'une structure switch rédigée avec des if then else et elseif, qu'on soit débutant ou chevronné, ça devient immédiatement du code spaghetti.

A mons sens, le débutant devrait systématiquement choisir la bonne structure avant de prendre l'habitude if then else.
GeorgesM a écrit :
A mons sens, le débutant devrait systématiquement choisir la bonne structure avant de prendre l'habitude if then else.
Tout à fait d'accord. Si le code est présenté de façon lisible, l'opérateur ternaire est tout aussi clair qu'un if/else.
GeorgesM a écrit :
Dans, ce cas, que diriez-vous devant une structure switch ?

Le switch... c'est une véritable horreur inmaintenable à long terme (à court aussi d'ailleurs)

En plus, faut savoir que sur plusieurs lignes d'instructions, l'opérateur ternaire va aller se rhabiller.
Donc la structure if else reste le meilleur compromis pour le deb.

GeorgesM a écrit :
A mons sens, le débutant devrait systématiquement choisir la bonne structure avant de prendre l'habitude if then else.

Présente-le moi le débutant qui est à même de choisir d'entrée de jeu la structure qui conviendra le mieux à la perennité de son application.

Je n'en connais aucun. Smiley langue
a écrit :
Le switch... c'est une véritable horreur inmaintenable à long terme (à court aussi d'ailleurs)

Ce n'est pas l'avis de Dennis Ritchie, ni Ken Thompson... Ils ne l'auraient pas implanté en c, et les c-like ne l'auraient pas repris...
a écrit :
En plus, faut savoir que sur plusieurs lignes d'instructions, l'opérateur ternaire va aller se rhabiller.

Je ne comprend pas. Dans le cas de plusieurs lignes d'instructions, on utilise if then else, non ?
... donc, en corrolaire, s'il n'y a qu'une seule ligne à exécuter, on remplace if then else par l'opérateur ternaire. C'est exactement ce que j'ai fait.
a écrit :

Donc la structure if else reste le meilleur compromis pour le deb.

Si vous le dites...

Est-ce que ChrisG a avancé dans ses tests, avec


<?php
$t=array();

if (isset($_GET["annee"])) $t[] = "YEAR(date) = '" .  $_GET["annee"]  . "'" ;
if (isset($_GET["mois"])) $t[] = "MONTH(date) = '" .  $_GET["mois"]  . "'" ;
if (isset($_GET["jour"])) $t[] = "DAYOFMONTH(date) = '" .  $_GET["jour"]  . "'" ;

$where = (count($t) > 0) ? "WHERE " : "";
$first_and = (count($t) > 1) ? " AND " : "";
$second_and = (count($t) > 2) ? " AND " : "";

$period = $where.$t[0].$first_and.$t[1].$second_and.$t[2];
?>


Parce que chez moi, ça marche impec...
Bison a écrit :
Parce que la structure conditionnelle saute moins aux yeux que dans un if else classique.

J'ai une question au posteur :
- pourquoi ce passage de tant de variable en GET ?

parce que là, on n'a qu'un visu tronqué du script, donc d'où viennent les valeurs ?


oui en fait j'ai donné le lien du code de mon script en fin de deuxième intervention dans ce fil.

les deux autres GET viennent de la page choisie et du nombre d'articles/page que l'on veut afficher.
GeorgesM a écrit :
Si on ne peux pas contrôler le nombre de $_GET, il suffisait de modifier comme suit :


<?php

$t=array();
if (isset($_GET["annee"])) $t[] = "YEAR(date) = '" .  $_GET["annee"]  . "'" ;
if (isset($_GET["mois"])) $t[] = "MONTH(date) = '" .  $_GET["mois"]  . "'" ;
if (isset($_GET["jour"])) $t[] = "DAYOFMONTH(date) = '" .  $_GET["jour"]  . "'" ;

$where = (count($t) > 0) ? "WHERE " : "";
$first_and = (count($t) > 1) ? " AND " : "";
$second_and = (count($t) > 2) ? " AND " : "";

$period = $where.$t[0].$first_and.$t[1].$second_and.$t[2];

?>


C'est quand même plus simple, non ?


ta proposition me semble très interessante mais un peu plus gourmande en ressource que celle-ci ?

if (isset($_GET)) {
		$period = '';
		$year =  'YEAR(date) = \''.$_GET['annee'].'\' ';
		$with_year = 'AND '.$year;
		$month = 'MONTH(date) = \''.$_GET['mois'].'\' ';
		$day = 'DAYOFMONTH(date) = \''.$_GET['jour'].'\' ';

		$need_where = true;
		if (isset($_GET['annee']) && ($_GET['annee'] != 'année')) {
			$period = 'WHERE  '.$year;
			$need_where = false;
	        }
		if (isset($_GET['mois']) && ($_GET['mois'] != 'mois')) {
			if ($need_where == true) {
				$period = 'WHERE  '.$month;
				$need_where = false;
			}
			else { $period .= 'AND '.$month; }
		}
		if (isset($_GET['jour']) && ($_GET['jour'] != 'jour')) {
			if($need_where == true) {
				$period = 'WHERE  '.$day;
				$need_where = false;
			}
			else { $period .= 'AND '.$day; }
		}
	}
Faut pas tout mélanger là, on parle bien de PHP !

Je maintiens que le switch est une daube de première catégorie.
Son emploi est d'une lourdeur sans pareille.

Il est très rare qu'un switch ne puisse pas être avantageusement remplacé par un array().
Array() dont PHP maîtrise parfaitement la gestion... d'ailleurs, il suffit de voir les dizaines de fonctions liées pour s'en rendre compte.

<?php
switch($nombre) {
   case 1 :
       echo 'un';
	   break;
   case 2 :
       echo 'deux';
	   break;
   case 3 :
       echo 'trois';
	   break;
   case 4 :
       echo 'quatre';
	   break;
   case 5 :
       echo 'cinq';
	   break;
   default:
       echo 'truc';
}

$tab = array(1=>'un','deux','trois','quatre','cinq');
echo $tab[$nombre]; 
?>

Y a pas photo !
D'autant que la version array() sera bien plus rapide que le switch.
Il en va de même pour une suite d'instruction if-elseif-else, array() est bien plus rapide et plus facilement maintenable.

GeorgesM a écrit :
$period = $where.$t[0].$first_and.$t[1].$second_and.$t[2];

Autant je comprend bien YEAR(date), MONTH(date) et DAYOFMONTH(date), autant la syntaxe précédente me laisse perplexe.
Je trouve que c'est une solide gymnastique pour travailler sur un champ de type DATE ou DATETIME.
Parce que si les 3 doivent être alignés, c'est la même chose que de faire
WHERE date='aaaa-mm-dd'.
De plus, il se passe quoi si une valeur est vide ou faussée ?
On est dans du GET, donc à la portée de n'importe qui ! Smiley ohwell

Le posteur n'a toujours répondu concernant la provenance réelle de ses valeurs via GET, ni pourquoi il les exploite de cette manière.

GeorgesM a écrit :
Parce que chez moi, ça marche impec...

Chez moi, bah ça ne fonctionne pas du tout !
error_reporting(E_ALL) Smiley langue

EDIT :
ChrisG a écrit :
oui en fait j'ai donné le lien du code de mon script en fin de deuxième intervention dans ce fil.

Euh oui p'têt, mais je ne suit jamais un lien vers (ou ne télécharge jamais) un script.
Modifié par Bison (03 Nov 2006 - 10:33)
ChrisG a écrit :

ta proposition me semble très interessante mais un peu plus gourmande en ressource que celle-ci ?


Les deux script font la même chose. Le temps machine est comparable dans les deux cas.
J'utilise un tableau et trois variables en huit lignes.

Votre code utilise six varables sur plus de 20 lignes.

Pour la vitesse d'exécution, j'ai fait exécuter 300000 itérations de l'un et l'autre script, le votre met 8 secondes, et le mien est plus lent à 9 secondes. C'est donc équivalent, et pas du tout gourmand en ressources dans les deux cas.
Bison a écrit :

Chez moi, bah ça ne fonctionne pas du tout !
error_reporting(E_ALL) Smiley langue

EDIT :

Euh oui p'têt, mais je ne suit jamais un lien vers (ou ne télécharge jamais) un script.


Vous avez raison. Smiley fatigue
Modifié par GeorgesM (03 Nov 2006 - 11:15)
ChrisG a écrit :
Hello,

j'ai un ptit problème de logique, j'essai d'optimiser ce code mais j'arrive pas :

if (isset($_GET)) {
...		
} else { $period = ''; }
}


toute proposition est bienvenue


La réponse du développeur serait en toute logique "il n'y a rien à optimiser." Si tu parles d'optimisation en terme de "réduire la vitesse d'exécution", je suis prêt à parier qu'il n'y a pas grand chose à modifier... Qu'est-ce qu'une poignée de if ?

Avant de vouloir optimiser, il vaut mieux profiler l'application, afin de voir quelles sont les parties prenant effectivement le plus temps. Maintenant là je ne pense pas que ça soit le morceaux qui prennent le plus de temps.

Si par contre tu veux optimiser dans le sens "rendre ça plus clair", là effectivement on peut faire des trucs, plein de gens t'ont fait des propositions dans ce topic Smiley smile
GeorgesM, les benchs en PHP, ça ne veut rien dire, c'est bien souvent du pipeau pour amuser la galerie. Smiley biggrin

Et là, je sens que tu vas me demander pourquoi ? Smiley langue

Simple, cela dépend trop de l'environnement, du contenu et des conditions d'utilisation.
Sur une même machine, sur un même nombre d'itération, des différences existent. Smiley cligne

Séparé du contexte, une solu qui semble plus performante sera bourin une fois réintégrée dans son environnement.

Bref, si tu préfères le switch, je ne vais pas t'en priver.
Mais pour moi, l'array() se présente comme suit :
- rapidité
- lisibilité
- efficacité
- perennité
Peut-être, mais de mon côté, j'optimise en utilisant microtime() appliqué à des structures objets pour détecter les portions de code que peuvent ralentir le serveur.
J'ai certains script qui effectuent des manipulations d'images ou des calculs complexes ou des analyses de code source (notament avec des expressions régulières un peu pointues), ainsi que des transformations xslt, etc etc.., et je ressent parfois le besoin de me faire une idée.
Je n'appelle pas ça bench, mais mesure, et je suis tout à fait conscient des différences qu'il peut y avoir entre deux machines, deux versions de php, deux systèmes d'exploitation. Tout cela est basique.
L'interêt est de comparer deux fonctions dans la même environnement et de déduire que l'une est plus efficace que l'autre. Soit un peu plus, beaucoup plus...
Rien à voir avec les switch. La seule galerie que j'amuse, c'est moi-même.
Pages :