Optimisation: or et and

ViPHP
AB
ViPHP | 5818 Messages

24 mars 2010, 21:38

Et comment vas-tu faire ensuite pour tester si is_array retourne effectivement true si c'est un tableau sinon false ?
@stealth35, @Dr@ke
C'était une boutade :wink: Si juste après une fonction qui renverra soit un tableau soit false, on veut revérifier que le résultat est bien un tableau ou false, c'est parce qu'on ne fait pas confiance à cette fonction. Alors pourquoi faire confiance à is_array et comment vérifier si is_array fonctionne correctement ensuite ?

Ce genre de vérif est utile s'il y a du code entre la variable et sont exploitation (le code aurait pu malencontreusement modifier le type de la variable) mais c'est inutile si les deux vérifs se suivent.

Donc quand tu fais
while($result = mysql_fetch_assoc($query)) {if (is_array($result)) ....}
c'est un peu comme si tu faisais
if ($a == 1) {if ($a == 1)...}

Mammouth du PHP | 985 Messages

24 mars 2010, 21:45

Je l'ai dis aussi que je savais bien que la fonction n'était pas censée retourner autre chose qu'un tableau.
C'est juste une logique dans ton test et/ou dans ton code.
Quand tu commences a faire attention aux types, à les prendre en compte, les tester -> tu prends conscience de l'importance des types.
Donc ensuite tu l'appliques un peu partout...
Quand tu affiches les résultats d'un tableau et bien on vérifie si c'est un tableau, souvent cela est plus que conseillé et parfois ce n'est pas vraiment nécessaire mais la logique est là.

Mais c'est juste mon avis après tout le monde fait comme il veut :)
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 3300 Messages

24 mars 2010, 23:00

Je l'ai dis aussi que je savais bien que la fonction n'était pas censée retourner autre chose qu'un tableau.
C'est juste une logique dans ton test et/ou dans ton code.
Quand tu commences a faire attention aux types, à les prendre en compte, les tester -> tu prends conscience de l'importance des types.
Donc ensuite tu l'appliques un peu partout...
Quand tu affiches les résultats d'un tableau et bien on vérifie si c'est un tableau, souvent cela est plus que conseillé et parfois ce n'est pas vraiment nécessaire mais la logique est là.

Mais c'est juste mon avis après tout le monde fait comme il veut :)
Ben oui, mais comme c'est obligatoirement un array le test est non seulement inutile mais une perte de temps pour l'analyze syntaxique, et l'exécution de cette ligne de code. Il ne faut pas coder mécaniquement sinon on fait des mauvaises choses, il faut questionner le moindre bout de code pour savoir s'il est utile.
Fait du php depuis que ca existe ou presque :)

Mammouth du PHP | 985 Messages

24 mars 2010, 23:13

Et si il n'y a pas de résultat , tu en fais pas de tests ? :roll:
        $query = mysql_fetch_assoc($query);
            echo $query['toto'];
Rassure moi tu n'affiches pas cela comme ça sans aucun test hein.

Donc au lieu de faire un test bolean sur quelque chose qui ne renvoie pas qu'un bolean, autant faire un test logique et correcte.

Et je présente dans la catégorie...:
is_array()
(question test ce n'est pas trop lourd)

Donc, au contraire de ce que tu dis, is_array() vérifie exactement ce que retourne la fonction mysql_fetch_assoc(), c'est à dire soit un tableau si un résultat, soit false.
Non seulement c'est logique mais c'est propre et compréhensible.

C'est ce que j'appelle optimiser son code :wink:

Il n'y a que le test OR qui peut être à la hauteur, comme cela a été démontré pendant le Topic.
D'où le titre du Topic: Optimisation: or et and
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 3300 Messages

24 mars 2010, 23:54

Et si il n'y a pas de résultat , tu en fais pas de tests ? :roll:
        $query = mysql_fetch_assoc($query);
            echo $query['toto'];
Rassure moi tu n'affiches pas cela comme ça sans aucun test hein.

Donc au lieu de faire un test bolean sur quelque chose qui ne renvoie pas qu'un bolean, autant faire un test logique et correcte.

Et je présente dans la catégorie...:
is_array()
(question test ce n'est pas trop lourd)

Donc, au contraire de ce que tu dis, is_array() vérifie exactement ce que retourne la fonction mysql_fetch_assoc(), c'est à dire soit un tableau si un résultat, soit false.
Non seulement c'est logique mais c'est propre et compréhensible.

C'est ce que j'appelle optimiser son code :wink:

Il n'y a que le test OR qui peut être à la hauteur, comme cela a été démontré pendant le Topic.
D'où le titre du Topic: Optimisation: or et and
Bon alors pour la deuxième fois de ce topic tiré de la doc de php
It only returns an associative array.
donc ton test ne sert à rien. si tu me dis:
$query = mysql_fetch_assoc($query);
if(count($query)>0) {
echo $query['blahblah'];
}
Je te dis ok, mais ton is_array ça revient à faire un if(true).
Fait du php depuis que ca existe ou presque :)

Mammouth du PHP | 985 Messages

25 mars 2010, 00:04

mysql_fetch_assoc() :
Retourne un tableau associatif de chaînes qui contient la ligne lue dans le résultat result, ou bien FALSE s'il ne reste plus de lignes à lire.
C'est bien marqué Tableau ou False

Identique a is_array():
Retourne TRUE si var est un array , FALSE sinon.
un test bolean -> c'est true ou false
Donc ça n'a rien a faire ici.

De plus count va utiliser plus de ressources qu'un simple is_array().

Puis compter un false c'est super logique :roll:

Non sérieux Nagol, tu ne peux pas me dire le contraire sur ce coup là :wink:
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 2287 Messages

25 mars 2010, 00:33

@Dr@ke, @Nagol : ne vous battez pas, vous avez raison tous les deux. Je vous invite à relire une petite phrase de stealth35 au début de ce thread qui est malheureusement passée inaperçue :
et le while = mysql_fetch_assoc() y pas grand monde qui comprend comment ca marche vraiment
Pourquoi revenir sur cette phrase ? Car la méthode qu'on recommande en général pour récupérer les résultats d'une requête (en jargon, un recordset) fait appel à un while (l'alternative étant, si on est sûr que le recordset contiendra au maximum un seul résultat, un if), contrairement au dernier exemple présenté par Dr@ke (qui est aussi celui qu'on trouve dans la page de manuel de php... no comment).

On conseille donc d'écrire une de ces deux formes :
while($result = mysql_fetch_array($con)){
  // zéro ou plusieurs résultats
  echo $result['x'].$result['y'].$result['z'];
}

if($result = mysql_fetch_array($con)){
  // zéro ou un seul résultat
  echo $result['x'].$result['y'].$result['z'];
}
Dans les deux cas, on englobe l'appel à mysql_fetch_* dans un test. Ce test permet de gérer la fin du recordset (quand on a dépassé le nombre de résultats à lire et qu'il n'y a donc plus rien dans le curseur), qui peut dans le cas extrême arriver immédiatement (si la requête n'a rien renvoyé du tout), ce qui correspond au fameux cas FALSE.

Le coup du résultat qui serait sous forme de tableau mais ne contiendrait aucun champ, je n'y crois pas trop car ça ne m'est jamais arrivé ! je ne sais pas si ce cas peut vraiment se produire.
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Mammouth du PHP | 985 Messages

25 mars 2010, 00:50

Il n'y aucun exemple similaire dans le manuel avec un is_array(), j'ai trouvé ça tout seul comme un grand , il y a un moment.
Ton test if fait de cette manière revient à un test boolean, et donc valide, car dans ton cas, cela renvoie soit true soit false.
Donc cela me parait correct, et question performances cela sera équivalent ou presque à un is_array().

Et je le rappelle, le is_array(), ce n'est en fait pas pour un hypothétique tableau vide, mais juste le test qui correspond, d'après moi, aux valeurs de retours exacts de mysql_fetch_assoc().

Sinon ton if est out avec un OR et équivalent d'un is_array():

Cf:
        $query = mysql_fetch_assoc($query) or die();
            echo $query['toto'];
Ou dans une fonction ou un include avec un return:
        $query = mysql_fetch_assoc($query) or return;
            echo $query['toto'];
Après on personnalise comme on veut...

PS, pour ton no comment là :non: :
Il n'y a tout de même pas besoin de faire une thèse dessus pour comprendre que si une fonction renvoie un tableau ou false, et bien la fonction adaptée pour la tester est is_array(), c'est logique et on en gère bien assez de tableaux pour le savoir.
J'estime ne pas avoir besoin de voir un exemple inexistant pour comprendre une chose si banale :roll:


De plus cette chose si banale est OUT avec un simple OR, ce qui je le rappelle est le sujet du Topic justement, le is_array() est venue par au fil de la discussion, c'est tout.
Modifié en dernier par Dr@ke le 25 mars 2010, 01:30, modifié 1 fois.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 2287 Messages

25 mars 2010, 01:29

Il n'y aucun exemple similaire dans le manuel avec un is_array(), j'ai trouvé ça tout seul comme un grand , il y a un moment.
mysql_fetch_* non encapsulé dans un if ou un while : c'est juste de ça dont je parlais. Dans cette situation, que ce soit is_array ou autre chose effectivement il faut gérer le cas d'erreur avec un test dans les lignes qui suivent (et les exemples du manuel viennent brillamment me contredire sur ce point puisqu'ils ne le font pas. Comme quoi, le manuel php est super mais pas parfait non plus...).
Ton test if fait de cette manière revient à un test boolean, et donc valide, car dans ton cas, cela renvoie soit true soit false.
Oui, le test s'évalue en booléen. Je n'ai pas la paternité de ce test, c'est juste ce qu'on voit dans n'importe quel code un peu structuré (le motif est bien éprouvé et facile à retenir apparemment puisque appliqué partout ou presque).
Donc cela me parait correct, et question performances cela sera équivalent ou presque à un is_array()
On peut aussi lever le doigt en l'air et se demander dans quel sens le vent souffle ;) Si tu veux des certitudes sur le point des performances, fais un benchmark (il me semble, à moi que c'est mon avis perso basé sur des souvenirs nébuleux et sur des tests effectués il y a bien longtemps dans une galaxie loint... euh, sur une vieille version de php, donc sans URL ni référence vérifiable à l'appui autre que mes souvenirs, que is_array n'est pas aussi performant que tu sembles le croire et devient même un gouffre à perfs dans certaines conditions, c'est pourquoi je suis sceptique sur ce choix).

Sans benchmark je me garderai bien de dire quel code entre les deux est le plus performant, je souligne juste l'intérêt en terme de concision et d'exhaustivité (donc de lisibilité, de facilité d'écriture/mémorisation également, et de maintenabilité) qui est tout aussi important que la performance brute (et même davantage, à mes yeux).
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Mammouth du PHP | 985 Messages

25 mars 2010, 01:35

Pour les benchs j'ai eu surement tord de lancer le sujet, car effectivement à ce niveau -> ce n'est pas le soucis.
D'ailleurs je vous conseille de les faire vous même, on est souvent surpris :wink:

Donc pour résumer la version officielle serait le if fait à la façon de Calimero, c'est à dire l'équivalent du While.
Une alternative tout aussi correcte serait le is_array().
Et pour finir, le OR qui encore une fois démontre son utilité :)

[EDIT]
Le truc a piger que je n'ai pas compris tout de suite moi, je l'avoue.
C'est que:
if ($var=4) // c'est comme si on testait si $var possédait une valeur non false-> donc true -> donc test boolean valide car $var=4 est convertit en true

// A l'inverse
if ($var = false) // logique ici, -> boolean retourne false

// Ce qui équivaut à:
$var = 4;
if ((bool) $var) // car ici $var est convertit en bool (true) juste pour le test et conserve sa valeur ensuite donc 4.
var_dump($var); //retourne 4
Ce qui explique la syntaxe particulière du while et du if pour les résultats SQL qui fonctionne très bien en test boolean.
Ainsi que la syntaxe du OR et AND sans parenthèses...
(conversion en boolean pour le test et ils gardent tout de même leur valeurs ensuite qui peuvent donc être traitées.)
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 5462 Messages

25 mars 2010, 04:32

du coup ca serais bien qu'on se lance un topic type "divers php" parce que c'est ni "hors sujet" ni "Autres sujets informatiques" quitte a lance un topic en head dans "Méthodologie, modélisation, sécurité", y'a des débat intéressant sur PHP au niveau des pratique, c'est un peu comme le GPS : un trajet plus court n'est pas forcement le trajet le plus économique, et inversement :wink:

Mammouth du PHP | 985 Messages

25 mars 2010, 04:38

Je viens de tester quelques trucs intéressants, qui démontre ce que l'on disait:
// ici $row = mysql_fetch_assoc($query) n'est pas convertit en (bool) mais is_array() sert de boolean
	while (is_array($row = mysql_fetch_assoc($query))) {
echo $row["toto"] . '<br>';
}

// ici on convertit temporairement la valeur de row en (bool) pour reproduire le while habituel
	while ((bool)($row = mysql_fetch_assoc($query))) {
echo $row["toto"] . '<br>';
}
Évidemment ce n'est pas a faire, car pas nécessaire, c'est juste a titre de démonstration, que c'est juste un test boolean...
Et donc une conversion temporaire de la valeur $row en boolean...
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Mammouth du PHP | 985 Messages

25 mars 2010, 08:55

De toute façon c'est clair dans la table Comparaison de types en PHP.
http://www.php.net/manual/fr/types.comparisons.php
La colonne if(x).
Il manque juste le array() non vide qui renvoie true.
(facile a vérifier ou tester avec un var_dump())
Donc, tout ceci on le savait déjà finalement.

C'est juste que la syntaxe while ($var = 4) n'est pas claire.
Mais dans un while on est obligé de l'inclure comme ceci sinon la variable est vérifiée qu'une seule fois.
Pas plus compliqué que cela finalement :wink:

Donc pour le if, ce n'est pas la peine de ce compliquer la vie, autant utiliser la syntaxe habituelle:
$result = mysql_fetch_assoc($con);
if ($result) {
  echo $result['x'].$result['y'].$result['z'];
}
Ou mieux encore, car autant faire le test le plus approprié, c'est à dire le is_array():
$result = mysql_fetch_assoc($con);
if (is_array($result)) {
  echo $result['x'].$result['y'].$result['z'];
}
Ah là, cela devient limpide.

Bref, on ne va passer une semaine la dessus :wink:
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 3300 Messages

25 mars 2010, 10:57

du coup ca serais bien qu'on se lance un topic type "divers php" parce que c'est ni "hors sujet" ni "Autres sujets informatiques" quitte a lance un topic en head dans "Méthodologie, modélisation, sécurité", y'a des débat intéressant sur PHP au niveau des pratique, c'est un peu comme le GPS : un trajet plus court n'est pas forcement le trajet le plus économique, et inversement :wink:
je propose "hors sujets php" ou "topics qui servent à rien mais qu'on aime bien y faire un tour quand même"
Fait du php depuis que ca existe ou presque :)

ViPHP
ViPHP | 3300 Messages

25 mars 2010, 11:04

Je viens de tester quelques trucs intéressants, qui démontre ce que l'on disait:
// ici $row = mysql_fetch_assoc($query) n'est pas convertit en (bool) mais is_array() sert de boolean
	while (is_array($row = mysql_fetch_assoc($query))) {
echo $row["toto"] . '<br>';
}

// ici on convertit temporairement la valeur de row en (bool) pour reproduire le while habituel
	while ((bool)($row = mysql_fetch_assoc($query))) {
echo $row["toto"] . '<br>';
}
Évidemment ce n'est pas a faire, car pas nécessaire, c'est juste a titre de démonstration, que c'est juste un test boolean...
Et donc une conversion temporaire de la valeur $row en boolean...
une affectation est toujours un booléen, et plus précisemment correspond à la valeur de la variable affectée, donc autant ton is_array que ton cast en bool sont redondants mais bon à la limite si tu es persuadé du contraire moi ça me va aussi, je force personne à adopter des points de vue logiques et rationels sur lesquels des dizaines de personnes ici s'entendent.
Fait du php depuis que ca existe ou presque :)