Dans le cadre de ma d�cision "j'apprends � coder proprement et
efficacement", j'ai 2.5 questions � vous poser (�a ne fait que commencer
:)).
Tout d'abord, pourquoi ne peut-on pas faire :
$a = (explode("?",$string))[0];
puisque explode renvoie un array ?
Ensuite, pourquoi ceci ne fonctionne pas :
array_flip($a);
ni m�me :
array_flip(&$a);
On est donc forc� d'�crire :
$a = array_flip($a);
?
La demi-question : Est-il (vraiment) utile de faire un unset d�s que
l'on a plus besoin d'une variable si cette variable ne contient pas des
tonnes de donn�es ?
Petite anecdote : hier en cherchant si qq un avait d�j� cod� ce que je
voulais, je suis tomb� sur une solution.
Elle est publi�e sur le site d'une agence web. Bon.
Cette solution fait 50 lignes, qui ressemblent � s'y m�prendre � du
visualbasic cod� par un enfant de 10ans.
Voyant �a, j'ai cherch� de mon c�t� pour, au final, arriver � un
meilleur r�sultat en... 5 lignes (et 15 minutes de recherche dans le doc
php) !
Jusque l�, vous me direz, c'est commun dans le monde du web. Sauf que
cette agence � cr�er son CMS en PHP :) (et l�, c'est le drame).
Je ne veux pas devenir comme �a ! Alors je pose des questions :)
Et comme d'hab, c'est sympa de votre part d'y r�pondre.
> Tout d'abord, pourquoi ne peut-on pas faire :
> $a = (explode("?",$string))[0];
> puisque explode renvoie un array ?
C'est une limitation de la grammaire de PHP. Certainement des
implémentations ont été proposées, mais soit les performances, soit les
effets de bord ne permirent pas son intégration.
> Ensuite, pourquoi ceci ne fonctionne pas :
> array_flip($a);
> ni même :
> array_flip(&$a);
> On est donc forcé d'écrire :
> $a = array_flip($a);
> ?
Là tu touche un point sensible du microcosme PHP. La documentation
dit qu'on renvoie le tableau modifié, donc c'est normal.
A noter qu'il n'y a pas de logique globale dans le nom des fonctions,
l'ordre des arguments, ou encore de la manière dont sont traités les
arguments par les fonctions natives.
> La demi-question : Est-il (vraiment) utile de faire un unset dès que
> l'on a plus besoin d'une variable si cette variable ne contient pas des
> tonnes de données ?
Très franchement, on s'en fout. Hormis pour les données volumineuse,
j'ai tendance à ne pas m'en soucier. PHP est censé gérer la mémoire.
> Petite anecdote : hier en cherchant si qq un avait déjà codé ce que je
> voulais, je suis tombé sur une solution.
> Elle est publiée sur le site d'une agence web. Bon.
> Cette solution fait 50 lignes, qui ressemblent à s'y méprendre à du
> visualbasic codé par un enfant de 10ans.
Oui, du PHP :p
> Voyant ça, j'ai cherché de mon côté pour, au final, arriver à un
> meilleur résultat en... 5 lignes (et 15 minutes de recherche dans le doc
> php) !
Ca dépend de ce que tu entends par « meilleur », dans quel contexte.
La concision n'est pas forcément ce qu'il y a de plus intelligent.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
>
> Là tu touche un point sensible du microcosme PHP. La documentation
> dit qu'on renvoie le tableau modifié, donc c'est normal.
> A noter qu'il n'y a pas de logique globale dans le nom des fonctions,
> l'ordre des arguments, ou encore de la manière dont sont traités les
> arguments par les fonctions natives.
Pourquoi, dans d'autres langages oui ?
Je ne comprends pas ce que ça (n')implique (pas).
>> Petite anecdote : hier en cherchant si qq un avait déjà codé ce que je
>> voulais, je suis tombé sur une solution.
>> Elle est publiée sur le site d'une agence web. Bon.
>> Cette solution fait 50 lignes, qui ressemblent à s'y méprendre à du
>> visualbasic codé par un enfant de 10ans.
>
> Oui, du PHP :p
Quand je regarde certains CMS, je trouve ça très propre *visuellement*
(il faut bien comprendre que l'esthétique du code est également un
analyse rapide de la manière de coder ; je dois être synesthésique :)).
Il y a peut-être de grosses erreurs de conception que je ne vois et ne
verrai jamais, mais elles sont à un tout autre niveau que
l'enchevêtrement de if, elseif et foreach sans aucune fonction
spécifique que je vois souvent, et notamment dans le code dont je parle
ci-après.
> Ca dépend de ce que tu entends par « meilleur », dans quel contexte.
> La concision n'est pas forcément ce qu'il y a de plus intelligent.
>
>
Dans ce cas, quelque soit le contexte, je peux vous te l'assurer (bon
j'étais méchant, hors commentaires et accolade, ils sont sur ~30 lignes) !
Parce que PHP est cod� avec les pieds !-)
Certaines op�rations ne peuvent �tre appliqu�es qu'� des variables, pas
� des expressions. Bref, c'est une limitation de l'interpr�teur PHP.
> Ensuite, pourquoi ceci ne fonctionne pas :
> array_flip($a);
> ni m�me :
> array_flip(&$a);
> On est donc forc� d'�crire :
> $a = array_flip($a);
> ?
parce que array_flip est une "vraie" fonction - et fonctionne donc sans
effet de bord. Ca, � mon sens, c'est plut�t une BonneChose. D'autant que
je ne suis pas s�r qu'il soit possible d'impl�menter efficacement ce
type d'op�ration r�ellement "en place" (c'est � dire sans cr�er au moins
temporairement un second tableau), contrairement �, par exemple, un tri
ou un reverse.
<plug>
Tiens au fait, quelqu'un sait comment sont impl�ment�s les tableaux de
PHP ? (ok, je pourrais regarder dans le source, mais l� j'ai un peu la
flemme).
</plug>
> La demi-question : Est-il (vraiment) utile de faire un unset d�s que
> l'on a plus besoin d'une variable si cette variable ne contient pas des
> tonnes de donn�es ?
Dans l'absolu, non. Accessoirement, pour les variables locales, elles
sont (th�oriquement...) lib�r�es automatiquement � la sortie de la
fonction.
> Petite anecdote : hier en cherchant si qq un avait d�j� cod� ce que je
> voulais, je suis tomb� sur une solution.
> Elle est publi�e sur le site d'une agence web. Bon.
> Cette solution fait 50 lignes, qui ressemblent � s'y m�prendre � du
> visualbasic cod� par un enfant de 10ans.
C'est tr�s courant dans le code produit par des agences web (et je sais
de quoi je parles, mouarf...).
> Voyant �a, j'ai cherch� de mon c�t� pour, au final, arriver � un
> meilleur r�sultat en... 5 lignes (et 15 minutes de recherche dans le doc
> php) !
> Jusque l�, vous me direz, c'est commun dans le monde du web.
Pas seulement. Si tu savais les horreurs que j'ai vu dans des applis de
gestion...
> Sauf que
> cette agence � cr�er son CMS en PHP :) (et l�, c'est le drame).
Rien que de tr�s ordinaire, h�las.
> Je ne veux pas devenir comme �a ! Alors je pose des questions :)
m�fie toi des r�ponses !-||
Disons que, au moins au niveau des fonctions builtins et des
bibliothèques standards, la plupart des autres langages essaient de
rester cohérent dans les conventions de nommage, l'ordre des arguments
pour des fonctionnalités similaires, et le mode d'appel (vraie fonction
ou transformation "en place").
En Python, par exemple, je n'ai que très rarement besoin de consulter la
doc pour vérifier un de ces points. En PHP, et particulièrement pour ce
qui touche aux chaines de caractères et aux tableaux (bref, aux deux
types de données les plus essentiels du langage dans ses applications
pratiques), je dois *systématiquement* lire la doc (et ce après
plusieurs années d'utilisation professionnelle et quotidienne).
> Je ne comprends pas ce que ça (n')implique (pas).
Ca implique que je suis nettement plus productif en Python qu'en PHP.
>>> Petite anecdote : hier en cherchant si qq un avait déjà codé ce que
>>> je voulais, je suis tombé sur une solution.
>>> Elle est publiée sur le site d'une agence web. Bon.
>>> Cette solution fait 50 lignes, qui ressemblent à s'y méprendre à du
>>> visualbasic codé par un enfant de 10ans.
>>
>> Oui, du PHP :p
>
> Quand je regarde certains CMS, je trouve ça très propre *visuellement*
> (il faut bien comprendre que l'esthétique du code est également un
> analyse rapide de la manière de coder ; je dois être synesthésique :)).
C'est plus ou moins vrai, à un premier niveau et d'une manière générale.
Mais bon, faut aller plus loin, parce que:
> Il y a peut-être de grosses erreurs de conception que je ne vois et ne
> verrai jamais, mais elles sont à un tout autre niveau que
> l'enchevêtrement de if, elseif et foreach sans aucune fonction
> spécifique que je vois souvent, et notamment dans le code dont je parle
> ci-après.
J'ai plusieur fois été induit en erreur par un code qui, au premier coup
d'oeil, avait l'air raisonnablement propre, structuré et documenté, mais
s'avérait au final être un ramassis d'âneries, d'erreurs grossières, et
d'application stupide de recette toutes faites ou de "bonne pratiques"
mal comprises et inappropriées dans le contexte - notamment certains
projets en PHP "objet" - mouarf - qui atteignent des sommets de débilité
dans le genre "j'ai rien pigé mais j'ai tout fait comme dans le livre".
Et - même si c'est bien plus rare - il m'est arrivé d'être finalement
agréablement surpris par du code qui semblait à première vue un plat de
spaghettis comme celui que tu décris ci-dessus, et s'avérait au final
être certes assez "bourrin", mais par ailleurs correct, robuste,
efficace, et globalement intelligible.
>
>> Ca dépend de ce que tu entends par « meilleur », dans quel contexte.
>> La concision n'est pas forcément ce qu'il y a de plus intelligent.
Je ne peux qu'appuyer. Mais bon, faut pas confondre non plus "explicite"
et "complètement con". Je tombe encore régulièrement sur des c... qui
relèvent quand même du niveau le plus abyssale d'incompréhension des
principes de base, du genre:
if <une_expression_booleenne> {
$var = TRUE;
}
else {
$var = FALSE;
}
Affligeant...
> Dans ce cas, quelque soit le contexte, je peux vous te l'assurer (bon
> j'étais méchant, hors commentaires et accolade, ils sont sur ~30 lignes) !
Tu nous posterais un lien sur le code en question (et éventuellement ta
propre implémentation) ?-)
Ca implique que quand on connaît la philosophie du langage on peut
deviner le nom d'une fonction dont on a besoin, et même l'ordre et le
type de ses arguments sans avoir besoin d'aller vérifier dans la doc en
permanence, et risquer une erreur stupide par ce qu'on a confondu la
syntaxe de deux fonctions proches.
--
Greetings, Salutations,
Guiraud Belissen, Château du Ciel, Drachenwald,
Chris CII, Rennes, France
> Parce que PHP est codé avec les pieds !-)
Chut ! Des décideurs pressés vont t'entendre !
> parce que array_flip est une "vraie" fonction - et fonctionne donc sans
> effet de bord. Ca, à mon sens, c'est plutôt une BonneChose. D'autant que
> je ne suis pas sûr qu'il soit possible d'implémenter efficacement ce
> type d'opération réellement "en place" (c'est à dire sans créer au moins
> temporairement un second tableau), contrairement à, par exemple, un tri
> ou un reverse.
C'est une question d'école. Quand on a été élevé à la POO, on
s'attend à ce que l'« objet » soit manipulé.
> <plug>
> Tiens au fait, quelqu'un sait comment sont implémentés les tableaux de
> PHP ? (ok, je pourrais regarder dans le source, mais là j'ai un peu la
> flemme).
> </plug>
Ce sont des hashtables.
> Pas seulement. Si tu savais les horreurs que j'ai vu dans des applis de
> gestion...
Comme l'usage des float pour gérer les flux monétaires ?
Bruno Desthuilliers a écrit :
> Tu nous posterais un lien sur le code en question (et éventuellement ta
> propre implémentation) ?-)
Ah la la... c'est que ce n'est pas très gentil tout ça...
Bon, j'ai changé le nom des variables. Je poste pas un lien ici parce
qu'ils pourraient mal le prendre (je m'étonne moi-même de tant d'attentions)
Voici la merveille donc (j'attends que tu me dises que c'est puissant et
robuste :) Tu noteras surtout la qualité des booléens). Vous aurez
compris que ça prend l'url et que ça y ajoute ou modifie une valeur en
GET, ainsi :
$url = addGET("http://www.monsite.com/rep/index.html?page=3&lang=fr",
"page", "7");
function addGET($url, $pNom, $pValeur){
$urlFinal = "";
if($pNom==""){
$urlFinal = $url;
}else{
$t_url = explode("?",$url);
if(count($t_url)==1){
$urlFinal .= $url;
if(substr($url,strlen($url)-1,strlen($url))!="/"){
$t_url2 = explode("/",$url);
if(preg_match("/./",$t_url2[count($t_url2)-1])==false){
$urlFinal .= "/";
}
}
$urlFinal .= "?".$pNom."=".$pValeur;
}else if(count($t_url)==2){
$addQString = "non";
$t_queryString = explode("&",$t_url[1]);
foreach($t_queryString as $cle => $NValeur){
$t_param = explode("=",$NValeur);
if($t_param[0]==$pNom){
$addQString = "oui";
}
}
if($addQString=="non"){
$urlFinal = $url."&".$pNom."=".$pValeur;
}else if($addQString=="oui"){
$urlFinal = $t_url[0]."?";
foreach($t_queryString as $cle => $NValeur){
if($cle > 0){
$urlFinal .= "&";
}
$t_NValeur = explode("=",$NValeur);
if($t_NValeur[0]==$pNom){
$urlFinal .= $pNom."=".$pValeur;
}else{
$urlFinal .= $t_NValeur[0]."=".$t_NValeur[1];
}
}
}
}
}
return $urlFinal;
}
ᅵa, c'est typique de ceux qui programment ᅵ par essais et erreurs ᅵ
jusqu'ᅵ ce que ᅵa marche, au lieu d'aller lire la doc. Tout d'abord, ils
ont l'air de penser que le troisiᅵme paramᅵtre est une position dans la
chaᅵne au lieu d'ᅵtre une longueur (en commenᅵant ᅵ strlen($url)-1, la
longueur restante ne peut pas ᅵtre plus grande que 1, et il est donc
inutile d'y mettre strlen($url)). Ensuite, en lisant la doc ils auraient
vu qu'on peut supprimer ce troisiᅵme paramᅵtre quand on veut lire
jusqu'ᅵ la fin de la chaᅵne. Enfin, mettre -1 en deuxiᅵme paramᅵtre est
plus simple et plus rapide que de calculer la longueur avec strlen($url)
et de lui soustraire 1.
Donc :
if (substr($url, -1) != "/") {
> $t_url2 = explode("/",$url);
> if(preg_match("/./",$t_url2[count($t_url2)-1])==false){
> $urlFinal .= "/";
> }
MOUHAHAHAHAHA !!!
Tu as bien fait de publier ce bout de code, ᅵ'aurait ᅵtᅵ dommage de le
rater.
Le preg_match('/./', ...), ᅵa vᅵrifie par une faᅵon extraordinairement
compliquᅵe que la chaᅵne n'est pas vide. Le rᅵsultat vaut 0 si la chaᅵne
est vide, valeur entiᅵre qu'ils comparent avec un boolᅵen (heureusement
pour eux, par ᅵ == ᅵ au lieu de ᅵ === ᅵ), et au final ils rajoutent donc
un '/' ᅵ la fin de cette URL si le dernier ᅵlᅵment du tableau issu de
l'explode() est vide (c'est-ᅵ-dire, en clair, si l'URL se terminait dᅵjᅵ
par un '/').
Seulement, ce test ubuesque n'est fait que dans le cas oᅵ l'URL ne se
terminait justement *pas* par un '/' !
En rᅵsumᅵ, ce code fait :
SI l'URL ne se termine pas par un '/' MAIS qu'elle se termine par un
'/', ALORS rajouter un '/'.
C'est tout simplement excellent !
Allez, je vais lire le reste, ᅵa risque d'ᅵtre drᅵle.
--
Olivier Miakinen
à envoyer à
http://thedailywtf.com/
ou
http://fr.thedailywtf.com/ ça !
>
> En rᅵsumᅵ, ce code fait :
> SI l'URL ne se termine pas par un '/' MAIS qu'elle se termine par un
> '/', ALORS rajouter un '/'.
>
J'aime bcp ton analyse pertinente. Moi, dᅵs que j'ai vu l'amalgame de if
et des preg_match avec des regexp aussi con et des boolᅵen oui/non
(c'est tout ceci que j'appelle le "visuel" d'un code), j'ai fui (en
fait, j'ai hᅵsitᅵ ᅵ ᅵtre mᅵchant sur leur site - parce que je rappelle
qu'ils ont fait un CMS !!! -, puis ᅵ leur donner mon code, puis ᅵ leur
proposer de recruter un dᅵveloppeur, pour finalement ne rien faire, par
expᅵrience : toute critique envers un pro se retourne forcᅵment contre
toi ᅵ un moment).
Donc c'est un truc qui date d'avant PHP4 sans quoi il y aurait un
parse_url pour simplifier.
Et par conséquent, ils ne pouvaient pas utiliser non plus
http_buidl_query :)
J'ai un gros doute tout d'un coup: le "php 1" dans le sujet, je croyais
que ça signifiait que c'est ta première question, mais en fait c'est la
version de PHP utilisée par l'agence ? :D
Bon, c'est pas beau de se moquer, je ne le ferai plus. Quoi que...
--
Réseau IRC Francophone: http://www.zeolia.net
Aide et astuces : http://www.g33k-zone.org
Communauté Francophone sur les Eggdrops: http://www.eggdrop.fr
> Donc c'est un truc qui date d'avant PHP4 sans quoi il y aurait un
> parse_url pour simplifier.
> Et par conséquent, ils ne pouvaient pas utiliser non plus
> http_buidl_query :)
>
Rah, tu as trouvé mon code de 5 lignes :)
> J'ai un gros doute tout d'un coup: le "php 1" dans le sujet, je croyais
> que ça signifiait que c'est ta première question, mais en fait c'est la
> version de PHP utilisée par l'agence ? :D
>
> Bon, c'est pas beau de se moquer, je ne le ferai plus. Quoi que...
>
Fais gaffe, c'est toi qui m'avais dit un jour que je n'étais pas
toujours très délicat ;)
Le reste n'ᅵtait pas si drᅵle que ᅵa, finalement, mᅵme si bien sᅵr on
peut faire beaucoup plus simple.
Et je suis d'accord avec toi qu'utiliser les valeurs chaᅵnes "oui" et
"non" au lieu des boolᅵens true et false n'est pas la faᅵon la plus
intelligente de programmer. Qui plus est, on se rend compte que la
variable $addQString est bien mal nommᅵe (ou que les valeurs sont
interverties) ; en effet, $addQString vaut "oui" dans le cas oᅵ il ne
faut *pas* ajouter (add) un nouveau paramᅵtre (ᅵ la Q. String), mais
qu'au contraire il faut remplacer un paramᅵtre existant.
Cordialement,
--
Olivier Miakinen
La POO n'est pas en soi une "bonne pratique".
> Ceci dit, je me rends compte sur certains projets que de jolis dev
> sortis de l'école ont tout ce qu'il faut comme acronyme à leur cv, mais
> ils codent avec une bêtise incommensurable...
Rien de neuf sous le soleil.
>
> Bruno Desthuilliers a écrit :
>> Tu nous posterais un lien sur le code en question (et éventuellement
>> ta propre implémentation) ?-)
>
> Ah la la... c'est que ce n'est pas très gentil tout ça...
> Bon, j'ai changé le nom des variables. Je poste pas un lien ici parce
> qu'ils pourraient mal le prendre
Y z'ont qu'a pas coder comme des gorets lobotomisés.
> (je m'étonne moi-même de tant
> d'attentions)
On aime bien rire !-)
> Voici la merveille donc (j'attends que tu me dises que c'est puissant et
> robuste :)
Pas exactement, non...
> Tu noteras surtout la qualité des booléens). Vous aurez
> compris que ça prend l'url et que ça y ajoute ou modifie une valeur en
> GET, ainsi :
> $url = addGET("http://www.monsite.com/rep/index.html?page=3&lang=fr",
> "page", "7");
MOUAHAHAHAHAHAHAHAHAHA !!!!
Oh p..., bin là je suis pas déçu, ça valait le voyage... Ca longtemps
que j'avais pas vu un tel tas de bouse - à ce stade là, ça confine à
l'oeuvre d'art !-)
Y'en aurais pour plusieurs jours à analyser toutes les conneries que
contient ce code. Tu devrais le poster sur le dailyWTF, c'est un cas
d'école ce truc. Surtout quand on arrive au preg_match, là vraiment j'en
suis arrivé à douter de moi-même. WHAT ??? THE ??? FUCK ???????
Bien, on peut voir ta version, maintenant ?-)
niark niark...
>> parce que array_flip est une "vraie" fonction - et fonctionne donc
>> sans effet de bord. Ca, à mon sens, c'est plutôt une BonneChose.
>> D'autant que je ne suis pas sûr qu'il soit possible d'implémenter
>> efficacement ce type d'opération réellement "en place" (c'est à dire
>> sans créer au moins temporairement un second tableau), contrairement
>> à, par exemple, un tri ou un reverse.
> C'est une question d'école. Quand on a été élevé à la POO, on s'attend
> à ce que l'« objet » soit manipulé.
Pas forcément. J'ai été élevé à la POO, mais je sais aussi écrire une
fonction "pure".
>> <plug>
>> Tiens au fait, quelqu'un sait comment sont implémentés les tableaux de
>> PHP ? (ok, je pourrais regarder dans le source, mais là j'ai un peu la
>> flemme).
>> </plug>
> Ce sont des hashtables.
Je me demandais - dans la mesure où ils conservent l'ordre d'insertion...
>> Pas seulement. Si tu savais les horreurs que j'ai vu dans des applis
>> de gestion...
> Comme l'usage des float pour gérer les flux monétaires ?
Mouahahahaha ! Je l'avais oubliée celle là.
Disons que je commence à comprendre l'intérêt de la POO, notamment en
terme de productivité.
Je pense que je n'aurai jamais à gérer un projet assez complexe pour
devoir maitriser vraiment la POO (mais c'est un cercle vicieux).
>
> MOUAHAHAHAHAHAHAHAHAHA !!!!
>
> Oh p..., bin là je suis pas déçu, ça valait le voyage... Ca longtemps
> que j'avais pas vu un tel tas de bouse - à ce stade là, ça confine à
> l'oeuvre d'art !-)
>
Ah ça, la robustesse, c'est parfois un peu rude :)
> Bien, on peut voir ta version, maintenant ?-)
S'il n'y a pas de bétise à la copie/reconstruction (maintenant, c'est en
fait 3 fonctions dans mon projet).
Là, vous aurez compris qu'on enlève et supprime, au moyen de tableaux.
Le foreach, c'est parce que je n'ai pas trouvé plus simple pour faire un
"array_delete".
function changeQuery($add=array(),$del=array()) {
parse_str(urldecode($_SERVER['QUERY_STRING']),$output);
if (count($del))
foreach ($del as $value) {
if (isset($output[$value])) unset($output[$value]);
}
$result = array_merge($output,$add);
return http_build_query($result, '', '&');
}
En PHP, c'est d'un intérêt limité (j'ai pas dit "inutile", hein...). Ca
a plus de sens dans un langage objet (un vrai, je veux dire), et - en
matière de développement web, avec un modèle d'exécution basé sur un
long running process.
>
>> Bien, on peut voir ta version, maintenant ?-)
>
> S'il n'y a pas de bétise à la copie/reconstruction (maintenant, c'est en
> fait 3 fonctions dans mon projet).
> Là, vous aurez compris qu'on enlève et supprime, au moyen de tableaux.
> Le foreach, c'est parce que je n'ai pas trouvé plus simple pour faire un
> "array_delete".
doit y avoir moyen avec un array_diff, mais ça n'apportera probablement
pas grand chose ni en perfs ni en lisibilité - au contraire.
>
> function changeQuery($add=array(),$del=array()) {
> parse_str(urldecode($_SERVER['QUERY_STRING']),$output);
1/ t'a pas déclaré ni initialisé $output avant.
2/ et si je veux travailler sur une autre url ? (ou, plus exactement, la
querystring d'une autre url).
> if (count($del))
Si $del est un tableau vide, la boucle foreach ne sera de toutes façons
pas exécutée. Donc le test est inutile.
> foreach ($del as $value) {
ce sont plutôt des clés, non ?-)
> if (isset($output[$value])) unset($output[$value]);
J'aime pas les conditionnelles incomplètes:
if (isset($output[$value])) {
unset($output[$value]);
}
le jour où tu veux ajouter un log, un trace ou quoi ou qu'est-ce, au
moins tu risques pas de manger une fermeture de bloc au passage...
> }
> $result = array_merge($output,$add);
Attention, il est parfaitement valide d'avoir plusieurs fois le même
paramètre dans une querystring (paramètre multivalué). Avec array_merge,
tu aura un remplacement pur et simple.
> return http_build_query($result, '', '&');
> }
Manque quand même un truc : là tu renvoie une querystring, pas une URL
complète.
Je suis d'accord avec certaines de tes remarques, mais pas avec
d'autres.
Le 06/11/2009 16:41, Bruno Desthuilliers rᅵpondait ᅵ Olivier Masson :
>>
>> function changeQuery($add=array(),$del=array()) {
>> parse_str(urldecode($_SERVER['QUERY_STRING']),$output);
>
> 1/ t'as pas dᅵclarᅵ ni initialisᅵ $output avant.
Pas d'accord : c'est la fonction parse_str() qui initialise la valeur
(il n'y a pas de cas oᅵ la fonction puisse laisser cette valeur non
initialisᅵe). Ta remarque me fait penser au genre de code suivant que
l'on voit quelquefois :
$variable = 0; // initialisation
$variable = ... rᅵsultat d'un calcul ...
Quant ᅵ dᅵclarer sans initialiser... ben c'est du PHP, hein !
> 2/ et si je veux travailler sur une autre url ? (ou, plus exactement, la
> querystring d'une autre url).
Ben ᅵa, je suppose que le besoin ne s'en fait pas sentir dans ce code
(mais seul Olivier Masson pourrait le dire).
>> if (count($del))
>
> Si $del est un tableau vide, la boucle foreach ne sera de toutes faᅵons
> pas exᅵcutᅵe. Donc le test est inutile.
Oui, entiᅵrement d'accord.
>> foreach ($del as $value) {
>
> ce sont plutᅵt des clᅵs, non ?-)
Oui, mais lᅵ tu chipotes. Les noms des clᅵs sont aussi des valeurs...
mais oui, ok, j'ai vu le souriard.
>> if (isset($output[$value])) unset($output[$value]);
>
> J'aime pas les conditionnelles incomplᅵtes:
>
> if (isset($output[$value])) {
> unset($output[$value]);
> }
D'accord et pas d'accord.
Je serais d'accord s'il l'avait ᅵcrit sur deux lignes :
if (isset($output[$value]))
unset($output[$value]);
Mais ᅵ mon sens il n'y a pas de danger quand c'est sur une seule ligne :
if (isset($output[$value])) unset($output[$value]);
> le jour oᅵ tu veux ajouter un log, un trace ou quoi ou qu'est-ce, au
> moins tu risques pas de manger une fermeture de bloc au passage...
Pour ma part, j'ajoute les accolades au moment de mettre ce code sur
deux lignes pour y ajouter l'instruction supplᅵmentaire. Pas de risque
de se tromper.
>> $result = array_merge($output,$add);
>
> Attention, il est parfaitement valide d'avoir plusieurs fois le mᅵme
> paramᅵtre dans une querystring (paramᅵtre multivaluᅵ). Avec array_merge,
> tu aura un remplacement pur et simple.
Voui, m'enfin bon, avec l'ancien code les paramᅵtres multivaluᅵs
n'ᅵtaient pas gᅵrᅵs non plus vu que tu ne pouvais pas dire quelle valeur
tu voulais remplacer : on peut donc supposer que ce cas n'est pas censᅵ
se produire.
Cela dit, ajouter un commentaire pour expliquer les limitations pourrait
ᅵtre utile.
>> return http_build_query($result, '', '&');
>> }
>
> Manque quand mᅵme un truc : lᅵ tu renvoie une querystring, pas une URL
> complᅵte.
L'ancien code prenait une URL complᅵte et renvoyait une URL complᅵte, le
nouveau prend une query string et renvoie une query string : ᅵa me
semble cohᅵrent. Le reste du traitement sera fait en dehors de cette
fonction, forcᅵment.
Cordialement,
--
Olivier Miakinen
Il semble que je me sois fourvoyᅵ ici :
<http://www.php.net/manual/fr/function.parse-str.php#89565>
Toutes mes excuses, donc.
Cordialement,
--
Olivier Miakinen
> En PHP, c'est d'un intérêt limité (j'ai pas dit "inutile", hein...). Ca
> a plus de sens dans un langage objet (un vrai, je veux dire), et - en
> matière de développement web, avec un modèle d'exécution basé sur un
> long running process.
>
Pourtant PHP5 est censé être pas mal objet non (et le 6 carrément donc) ?
Je doute que ce soit inutile tout de même (oui, tu l'as pas dit, ok.)
>>
>> function changeQuery($add=array(),$del=array()) {
>> parse_str(urldecode($_SERVER['QUERY_STRING']),$output);
>
> 1/ t'a pas déclaré ni initialisé $output avant.
>
exact mais ça l'est en fait.
> 2/ et si je veux travailler sur une autre url ? (ou, plus exactement, la
> querystring d'une autre url).
Ben je veux pas :)
Comme je l'ai dit, c'est adapté à mon contexte.
Et j'en profite pour indiquer un argument qui ne me convainc pas dans la
POO : c'est extensible, réutilisable...
Super ! Mais qd j'ai :
1/ des délais à tenir,
2/ des fonctions qui ne me serviront plus ou qui ne me serviront jamais
autrement,
je ne vois nullement l'intérêt de perdre du temps à rendre tout
parfaitement adaptable à tout contexte (c'est aussi valable pour du dev
non objet d'ailleurs.)
>
>> if (count($del))
>
> Si $del est un tableau vide, la boucle foreach ne sera de toutes façons
> pas exécutée. Donc le test est inutile.
>
Ben non : Invalid argument supplied for foreach().
Fonctionne normalement avec ma condition inutile.
>> foreach ($del as $value) {
>
> ce sont plutôt des clés, non ?-)
C'est vrai que ça fait couillon et peut nuire à la compréhension... mais
c'est comme ça (je vais qd même pas faire un flip juste pour pouvoir
lire les key !).
>
>> if (isset($output[$value])) unset($output[$value]);
>
> J'aime pas les conditionnelles incomplètes:
>
> if (isset($output[$value])) {
> unset($output[$value]);
> }
>
Je ne vois pas en quoi c'est incomplet. A mon avis, question de style.
En tout cas, je fais toujours comme ça quand je sais qu'il n'y aura rien
de plus après la condition.
JE SAIS que ça peut ne pas plaire, mais les accolades de partout, ça me
gonfle et je ne trouve pas ça DU TOUT plus lisible.
A l'inverse, les ($a==='prout')?'do_this':(($b==='crotte')?'youpi':'piyou'))
ça m'insupporte.
Il y a aussi une question de gout. Y'en a qui mettent des switch dès la
moindre condition, y'en a (y'en a ?) qui aiment les endif, etc.
> le jour où tu veux ajouter un log, un trace ou quoi ou qu'est-ce, au
> moins tu risques pas de manger une fermeture de bloc au passage...
>
>> }
>
>> $result = array_merge($output,$add);
>
> Attention, il est parfaitement valide d'avoir plusieurs fois le même
> paramètre dans une querystring (paramètre multivalué). Avec array_merge,
> tu aura un remplacement pur et simple.
Alors ça, c'est une TRES BONNE remarque même si dans ce que tu cites ça
ne pose nullement problème.
En effet, des index sont ajoutés aux queries (si j'ai
?nom[]=bob&nom[]=tom, j'obtiens ?nom[0]=bob&nom[1]=tom).
Mais ça coince pour le del car le unset n'est plus bon.
>
>> return http_build_query($result, '', '&');
>> }
>
> Manque quand même un truc : là tu renvoie une querystring, pas une URL
> complète.
Ah ouais ça change tout et puis c'est balèze de reconstruire une url !
:) (et en fait, c'est fait dans mes fonctions)
Ah ? Avec un tableau vide, vraiment ? Ou avec une valeur nulle ?
> Fonctionne normalement avec ma condition inutile.
Peut-ᅵtre parce que count(null) retourne 0, en revanche si j'en crois la
doc count(0) et count("") retournent 1.
Je pensais qu'en indiquant $del=array() dans la dᅵclaration des
arguments (je sais pas si on dit ainsi), c'ᅵtait ok mais non.
>
>> Fonctionne normalement avec ma condition inutile.
>
> Peut-ᅵtre parce que count(null) retourne 0, en revanche si j'en crois la
> doc count(0) et count("") retournent 1.
Prᅵcisᅵment. Je suis dᅵᅵu car je pensais que array() ᅵtait de type array
mais non, c'est null, c'est nul.
En fait, si ᅵa avait ᅵtᅵ comme je pensais ci-dessus, il n'y aurait pas
eu besoin du if.
C'est ok si tu ne passes pas de paramᅵtre ᅵ la fonction. ᅵa ne l'est
plus si tu lui passes une valeur null.
Cf. <http://www.miakinen.net/tmp/test_array.php>
Source :
----------------------------------------------------------------------
<?php
header("Content-Type: text/plain; charset=UTF-8");
function changeQuery($add=array(),$del=array()) {
echo "add : "; var_dump($add);
echo "del : "; var_dump($del);
echo "\n";
}
echo "changeQuery()\n"; changeQuery();
echo "changeQuery(null)\n"; changeQuery(null);
echo "changeQuery(null, null)\n"; changeQuery(null, null);
echo "changeQuery(array(), null)\n"; changeQuery(array(), null);
?>
----------------------------------------------------------------------
Rᅵsultat :
----------------------------------------------------------------------
changeQuery()
add : array(0) {
}
del : array(0) {
}
changeQuery(null)
add : NULL
del : array(0) {
}
changeQuery(null, null)
add : NULL
del : NULL
changeQuery(array(), null)
add : array(0) {
}
del : NULL
----------------------------------------------------------------------
Je ne pense pas que ce soit tout ᅵ fait similaire. Dans le cas qui nous
intᅵresse - et pour autant que je sache -, si tu passes un array ᅵ
parse_str, la fonction n'ira pas en allouer un nouveau. Mais bon, je
peux me tromper, j'ai pas ᅵtᅵ regarder l'implᅵmentation !-)
Dᅵsolᅵ, j'ai ᅵnormᅵment de mal avec les variables qui apparaissent comme
ᅵa de nulle part.
> Quant ᅵ dᅵclarer sans initialiser... ben c'est du PHP, hein !
No comment.
>> 2/ et si je veux travailler sur une autre url ? (ou, plus exactement, la
>> querystring d'une autre url).
>
> Ben ᅵa, je suppose que le besoin ne s'en fait pas sentir dans ce code
Pas encore, peut-ᅵtre - mais c'est quand mᅵme un cas d'utilisation plus
que courant (je parles pas expᅵrience), et qui peut le plus peut le
moins... Un premier paramᅵtre 'querystring' avec une valeur NULL par
dᅵfaut ne coᅵtait pas beaucoup plus cher et rendait immᅵdiatement la
fonction bien plus gᅵnᅵrique.
> (mais seul Olivier Masson pourrait le dire).
>
>>> if (count($del))
>> Si $del est un tableau vide, la boucle foreach ne sera de toutes faᅵons
>> pas exᅵcutᅵe. Donc le test est inutile.
>
> Oui, entiᅵrement d'accord.
>
>>> foreach ($del as $value) {
>> ce sont plutᅵt des clᅵs, non ?-)
>
> Oui, mais lᅵ tu chipotes.
C'est une de mes grandes spᅵcialitᅵs, en effet.
> Les noms des clᅵs sont aussi des valeurs...
Of course. Mais un bon nommage favorise la lisibilitᅵ du code.
> mais oui, ok, j'ai vu le souriard.
>
>>> if (isset($output[$value])) unset($output[$value]);
>> J'aime pas les conditionnelles incomplᅵtes:
>>
>> if (isset($output[$value])) {
>> unset($output[$value]);
>> }
>
> D'accord et pas d'accord.
>
> Je serais d'accord s'il l'avait ᅵcrit sur deux lignes :
>
> if (isset($output[$value]))
> unset($output[$value]);
>
> Mais ᅵ mon sens il n'y a pas de danger quand c'est sur une seule ligne :
>
> if (isset($output[$value])) unset($output[$value]);
>
>> le jour oᅵ tu veux ajouter un log, un trace ou quoi ou qu'est-ce, au
>> moins tu risques pas de manger une fermeture de bloc au passage...
>
> Pour ma part, j'ajoute les accolades au moment de mettre ce code sur
> deux lignes pour y ajouter l'instruction supplᅵmentaire. Pas de risque
> de se tromper.
Et pourtant, j'ai dᅵjᅵ vu le cas.
>>> $result = array_merge($output,$add);
>> Attention, il est parfaitement valide d'avoir plusieurs fois le mᅵme
>> paramᅵtre dans une querystring (paramᅵtre multivaluᅵ). Avec array_merge,
>> tu aura un remplacement pur et simple.
>
> Voui, m'enfin bon, avec l'ancien code les paramᅵtres multivaluᅵs
> n'ᅵtaient pas gᅵrᅵs non plus vu que tu ne pouvais pas dire quelle valeur
> tu voulais remplacer : on peut donc supposer que ce cas n'est pas censᅵ
> se produire.
En l'occurrence, je me contentais d'attirer l'attention d'Olivier sur
une limitation de son code.
> Cela dit, ajouter un commentaire pour expliquer les limitations pourrait
> ᅵtre utile.
+1
>>> return http_build_query($result, '', '&');
>>> }
>> Manque quand mᅵme un truc : lᅵ tu renvoie une querystring, pas une URL
>> complᅵte.
Accessoirement aussi: on peut vouloir gᅵnᅵrer une querystring pour une
autre raison que l'affichage dans une page. Il serait donc prᅵfᅵrable -
en termes de gᅵnᅵricitᅵ - de prᅵciser (via un paramᅵtre optionnel) si on
veut une entitᅵe ou une vraie ᅵperluette.
> L'ancien code prenait une URL complᅵte et renvoyait une URL complᅵte, le
> nouveau prend une query string
Mᅵme pas - hᅵlas ᅵ mon avis.
> et renvoie une query string : ᅵa me
> semble cohᅵrent.
La fonction en elle-mᅵme est cohᅵrente, mais au niveau fonctionnalitᅵ
elle n'est pas ᅵquivalente ᅵ l'original.
> Le reste du traitement sera fait en dehors de cette
> fonction, forcᅵment.
CQFD.
Non. Les deux ont ajouté au modèle objet déjà existant dans PHP4, mais
ça ne fait pas de PHP un langage objet - au sens ou Python ou Ruby sont
des langages objet. En PHP, une chaine n'est pas un objet, un entier
n'est pas un objet, un array n'est pas un objet, une fonction n'est pas
un objet, etc etc.... Bref, PHP reste fondamentalement un langage
procédural.
> Je doute que ce soit inutile tout de même (oui, tu l'as pas dit, ok.)
Non, je ne l'ai pas dit.
>
>>>
>>> function changeQuery($add=array(),$del=array()) {
>>> parse_str(urldecode($_SERVER['QUERY_STRING']),$output);
>>
>> 1/ t'a pas déclaré ni initialisé $output avant.
>>
>
> exact mais ça l'est en fait.
Oui, mais cette variable apparaît de nulle part, et on se demande d'où
elle vient. Ok, c'est un pattern courant en PHP, mais il heure
profondément ma sensibilité artistique !-)
>> 2/ et si je veux travailler sur une autre url ? (ou, plus exactement,
>> la querystring d'une autre url).
>
> Ben je veux pas :)
Tu parie que tu va en avoir besoin plus tôt que tu ne le crois ?-)
> Comme je l'ai dit, c'est adapté à mon contexte.
Donc quand tu aura le besoin de la même fonction mais pouvant bosser sur
n'importe quelle querystring arbitraire, tu fera un copié-collé et tu
aura deux implémentations à maintenir en parallèle ?
> Et j'en profite pour indiquer un argument qui ne me convainc pas dans la
> POO : c'est extensible, réutilisable...
Pas forcément plus que du fonctionnel ou du procédural. Cet argument là,
c'est un peu de l'huile de serpent, n'est-ce pas.
> Super ! Mais qd j'ai :
> 1/ des délais à tenir,
> 2/ des fonctions qui ne me serviront plus ou qui ne me serviront jamais
> autrement,
> je ne vois nullement l'intérêt de perdre du temps à rendre tout
> parfaitement adaptable à tout contexte
Certaines fonctionnalités sont tellement spécifiques à un projet qu'il
serait effectivement inepte de vouloir les rendre générique. D'autre,
par contre, correspondent à des besoins récurrents, et il est parfois
très simple de les rendre tout de suite suffisament générique pour
couvrir la majorité des cas d'utilisation. C'est ici le cas, et
l'"effort" nécessaire est tellement dérisoire (deux lignes de code et 15
secondes de réflexion....) qu'il est AMHA dommage de ne pas l'avoir fait
immédiatement.
> (c'est aussi valable pour du dev
> non objet d'ailleurs.)
Tout à fait.
>
>>
>>> if (count($del))
>>
>> Si $del est un tableau vide, la boucle foreach ne sera de toutes
>> façons pas exécutée. Donc le test est inutile.
>>
>
> Ben non : Invalid argument supplied for foreach().
Le code suivant fonctionne très bien chez moi:
<?php
function foo($bar=array()) {
foreach($bar as $baz) {
echo $baz;
}
}
foo();
?>
> Fonctionne normalement avec ma condition inutile.
AMHA, tu a passé NULL en argument. Auquel cas - si c'est le "pattern"
d'utilisation recommendé - tu devrais tester sur "is_array", pas sur
"count". Mes deux centimes...
>>> foreach ($del as $value) {
>>
>> ce sont plutôt des clés, non ?-)
>
> C'est vrai que ça fait couillon et peut nuire à la compréhension... mais
> c'est comme ça (je vais qd même pas faire un flip juste pour pouvoir
> lire les key !).
Je pensais juste au nommage. Effectivement, ce sont des valeurs, qui
correspondent à des clés dans le tableau représentant la querystring.
Personnellement, j'aurais utilisé "$param" ou "$name" pour éviter toute
ambiguité.
>>
>>> if (isset($output[$value])) unset($output[$value]);
>>
>> J'aime pas les conditionnelles incomplètes:
>>
>> if (isset($output[$value])) {
>> unset($output[$value]);
>> }
>>
>
> Je ne vois pas en quoi c'est incomplet.
cf plus bas.
> A mon avis, question de style.
Tout à fait.
> En tout cas, je fais toujours comme ça quand je sais qu'il n'y aura rien
> de plus après la condition.
> JE SAIS que ça peut ne pas plaire, mais les accolades de partout, ça me
> gonfle et je ne trouve pas ça DU TOUT plus lisible.
>
> A l'inverse, les
> ($a==='prout')?'do_this':(($b==='crotte')?'youpi':'piyou'))
> ça m'insupporte.
Avec deux opérateurs ternaires enchainés, effectivement, ça devient pénible.
> Il y a aussi une question de gout. Y'en a qui mettent des switch dès la
> moindre condition, y'en a (y'en a ?) qui aiment les endif, etc.
Les "endXXX" sont surtout prévus pour le code "embarqué" dans du html -
où les accolades fermantes sont peu lisibles.
>> le jour où tu veux ajouter un log, un trace ou quoi ou qu'est-ce, au
>> moins tu risques pas de manger une fermeture de bloc au passage...
>>> }
>>
>>> $result = array_merge($output,$add);
>>
>> Attention, il est parfaitement valide d'avoir plusieurs fois le même
>> paramètre dans une querystring (paramètre multivalué). Avec
>> array_merge, tu aura un remplacement pur et simple.
>
> Alors ça, c'est une TRES BONNE remarque même si dans ce que tu cites ça
> ne pose nullement problème.
> En effet, des index sont ajoutés aux queries (si j'ai
> ?nom[]=bob&nom[]=tom, j'obtiens ?nom[0]=bob&nom[1]=tom).
> Mais ça coince pour le del car le unset n'est plus bon.
>
>>
>>> return http_build_query($result, '', '&');
>>> }
>>
>> Manque quand même un truc : là tu renvoie une querystring, pas une URL
>> complète.
>
> Ah ouais ça change tout et puis c'est balèze de reconstruire une url !
> :)
Eh, tu postes ton code, je cherche la petite bête, hein ?-)
Je mentionnais surtout ça par "honnêteté" vis à vis de l'autre
magnifique (hahum...) example de code que nous avons si joyeusement
commenté - du point de vue fonctionnel, les deux codes ne sont pas
strictement équivalents. Quoique parler de "fonctionnel" pour l'autre
bout de code, c'est un peu exagéré !-)
Je comprends tout à fait ton raisonnement... qui est celui qui m'a jadis
fait perdre des heures. Car il est toujours très délicat de déterminer
ce qui pourra être utile, si toutefois c'est utile un jour. Mais
également des questions comme "faut-il que je sécurise toutes les
entrées ?", ce qui peut être très long à faire, alors que l'interface
(encore une fois, excuse-moi pour le vocabulaire pas forcément
approprié) ne sera *jamais* publique et que je suis pas encore assez
vieux pour m'auto-SQL-injecter :)
Donc dans le cas que tu cites, ok, mais moi j'ai la flemme d'ajouter un
argument à chaque fois. Et cette fonctionne est très utilisée dans mon
code. Donc je monte ma fonction pour que, par défaut, elle soit
argumentée pour le cas le plus classique ($_SERVER['REQUEST_URI'])
>
> Eh, tu postes ton code, je cherche la petite bête, hein ?-)
>
Oui, oui, mais dans mon code je reconstruis l'url.
Là, j'ai posté le principe.
Mais tu as raison d'avoir tout relevé car le count à été remplacé par le
is_array et je vais modifié la fonction pour le $del.
J'imagine la tonne de commentaires négatifs si j'avais posté tout le bloc :)
Mais en fait, c'est comme ça que l'on devrait apprendre.
(Plutôt que de) En plus de lire des bouquins et des docs, je devrais
payer un 2 gars (un avis n'est jamais suffisant ;)) pour relire quelques
scripts et hop, on y passe 1 semaine. Mais ça va faire cher la formation !
Trouvᅵ sur le ᅵ daily WTF ᅵ francophone :
http://img.thedailywtf.com/images/fr/errors/bateau.JPG
--
Olivier Miakinen
Bonjour,
> Le 05/11/2009 21:12, Micka�l Wolff a �crit :
> > Comme l'usage des float pour g�rer les flux mon�taires ?
>
> Trouv� sur le � daily WTF � francophone :
> http://img.thedailywtf.com/images/fr/errors/bateau.JPG
Mouarf :)
Plus s�rieusement, d�terminer quel type de variable choisir en fonction
du contexte et du r�sultat attendu est tr�s important quel que soit le
langage de programmation utilis�, mais �a l'est encore plus quand on
code avec un langage comme PHP, tr�s faiblement typ�, qui va accepter �
peu pr�s n'importe quoi en entr�e et s'adapter comme il peut (mais
g�n�ralement pas comme l'auteur du code le souhaiterait) pour retourner
un r�sultat.
Sans oublier la base de donn�es, qui stocke les informations dans des
champs dont les caract�ristiques (encodage et typage) doivent elles
aussi �tre d�finies pr�cis�ment si on veut �viter les effets de bords.
Je pense utile de souligner ces points, parce que quand on d�bute en
programmation (ou en PHP, sujet de ce fil), on n'en tient souvent pas
compte par inexp�rience, et on se trouve ensuite confront� � des
probl�mes qui auraient pu �tre �vit�s en suivant d�s le d�part quelques
de bon sens.
Mes deux centimes.
--
Eric
Vous utilisez quoi pour les sous alors ?
Parce que moi, qd j'ai du float en base ᅵ exploiter, je garde bᅵtement
le float (bien ᅵvidemment, je n'affiche que 2 dᅵcimales et je passe par
printf).
Et quand c'est moi qui m'occupe de la base... je fais pareil :)
Mais bon, je ne gᅵre pas les ᅵchanges de devises sur lesquelles un
cercle de gens puants (oups, HS) peuvent se faire un max sur un
changement de la 4eme dᅵcimales.
> Vous utilisez quoi pour les sous alors ?
> Parce que moi, qd j'ai du float en base à exploiter, je garde bêtement
> le float (bien évidemment, je n'affiche que 2 décimales et je passe par
> printf).
> Et quand c'est moi qui m'occupe de la base... je fais pareil :)
Le problème provient du fait qu'il est impossible de repésenter un
nombre décimal non entier en nombre binaire exact. Ce qu'on sait faire,
c'est adopter une représentation du nombre. Le standad IEEE 754 et
successeurs proposent une représentation d'une précision acceptable pour
un utilisateur qui souhaite privilégier les performances du calcul au
détriment de l'exactitude.
Si dans le calcul d'une scène 3D l'imprécision n'est pas
problématique, dans les calculs de TVA cette approximation est
intolérable. Du moins pour l'URSSAF.
La plupart du temps on ne voit pas la différence. L'écart n'est
véritablement observable que lorsque le nombre d'opérations considérées
pour le calcul est importante, ou que somme deviennent importantes.
> Mais bon, je ne gère pas les échanges de devises sur lesquelles un
> cercle de gens puants (oups, HS) peuvent se faire un max sur un
> changement de la 4eme décimales.
Concrètement, ANSI SQL propose un type précis : DECIMAL. MySQL le
supporte et garanti le comportement du DECIMAL. Du coup, je fais tout
les calculs dans MySQL.
Si tu n'as pas de bases de données, il existe des bibliothèques qui
fournissent cette fonctionnalité (au hasard, GMP qui est disponible dans
PHP).
des dᅵcimaux ou des entiers, selon le contexte.
> Mais bon, je ne gᅵre pas les ᅵchanges de devises sur lesquelles un
> cercle de gens puants (oups, HS) peuvent se faire un max sur un
> changement de la 4eme dᅵcimales.
De simples calculs TTC / HT, remises (fixe / pourcentage), frais de
port, tati pouffin - bref, des trucs que tu va trouver dans n'importe
quelle appli de gestion commerciale, de commerce en ligne, de paie, etc,
suffisent ᅵ fausser le rᅵsultat.
Been here, done that...
> Car il est toujours très délicat de déterminer
> ce qui pourra être utile, si toutefois c'est utile un jour.
Mmmm... Disons qu'avec l'expérience, certains cas relèvent de l'évidence
- dans un sens comme dans l'autre. Pour moi (c'est à dire "à mon avis,
qui m'est éminemment personnel et que je ne force personne à partager -
tant que je n'ai pas à maintenir le code"), le cas ci-dessus relève de
l'évidence, mais bon, hein... C'est pas mon appli, n'est-ce pas !-)
> Donc dans le cas que tu cites, ok, mais moi j'ai la flemme d'ajouter un
> argument à chaque fois.
Utilise un argument avec une valeur par défaut. Bon, c'est vrai qu'en
PHP y a pas d'arguments nommés, donc c'est un peu plus ch...
>
>>
>> Eh, tu postes ton code, je cherche la petite bête, hein ?-)
(snip)
> J'imagine la tonne de commentaires négatifs si j'avais posté tout le
> bloc :)
"négatifs" ???
> Mais en fait, c'est comme ça que l'on devrait apprendre.
On apprend toujours d'une revue de code - dans un sens comme dans
l'autre (je veux dire, qu'on soit la victime ou le bourreau <g>), et
quelques soient l'expérience, le niveau et le background.
> Concrètement, ANSI SQL propose un type précis : DECIMAL. MySQL le
> supporte et garanti le comportement du DECIMAL. Du coup, je fais tout
> les calculs dans MySQL.
Ok, c'est une bonne idée.
> Si tu n'as pas de bases de données, il existe des bibliothèques qui
> fournissent cette fonctionnalité (au hasard, GMP qui est disponible dans
> PHP).
>
Merci.
Tu ne crois pas si bien dire ! Même si je ne suis pas développeur, je
"programmais" sur mon Sharp puis mon Commodore. Comme j'ai préféré avoir
une vie sociale, j'ai laissé tomber 10 ans durant... mais j'ai eu du mal
ensuite à me défaire de certaines vieilles habitudes comme d'optimiser
la moindre milliseconde au traitement (ça comptait quand je sortais des
Mandelbrot ou des Lyapunov sur l'Amiga !)
Le mieux est l'ennemi du bien.
> Utilise un argument avec une valeur par défaut. Bon, c'est vrai qu'en
> PHP y a pas d'arguments nommés, donc c'est un peu plus ch...
Oui, c'est ce que j'ai fait au final... mais non en fait :/ puisque
"Qu'est-ce qu'un argument nommé ?".
>> J'imagine la tonne de commentaires négatifs si j'avais posté tout le
>> bloc :)
>
> "négatifs" ???
Ce que je veux dire c'est que je ne m'attends pas à des applaudissements
en mettant mon code ici :)
>> Utilise un argument avec une valeur par défaut. Bon, c'est vrai qu'en
>> PHP y a pas d'arguments nommés, donc c'est un peu plus ch...
>
> Oui, c'est ce que j'ai fait au final... mais non en fait :/ puisque
> "Qu'est-ce qu'un argument nommé ?".
Certains langages permettent de passer les arguments "dans le désordre"
en les nommant explicitement lors de l'appel. Par exemple, la fonction:
def func(arg1, arg2, arg3):
# code here
peut être appelée ainsi:
func(arg3=42, arg1="yadda", arg2="whatever")
C'est très pratique pour une fonction comme la tienne où il y a
plusieurs arguments avec des valeurs par défaut, en ce que ça évite de
devoir passer explicitement ceux des arguments pour lesquels tu veux
conserver la valeur par défaut.
>>> J'imagine la tonne de commentaires négatifs si j'avais posté tout le
>>> bloc :)
>>
>> "négatifs" ???
>
> Ce que je veux dire c'est que je ne m'attends pas à des applaudissements
> en mettant mon code ici :)
Oh bin c'en était pas loin pourtant. Il a vraiment fallu que je cherche
la petite bête !-)
> Certains langages permettent de passer les arguments "dans le désordre"
> en les nommant explicitement lors de l'appel. Par exemple, la fonction:
>
> def func(arg1, arg2, arg3):
> # code here
>
> peut être appelée ainsi:
>
> func(arg3=42, arg1="yadda", arg2="whatever")
>
En effet, c'est bien pratique !
Pour clore ce premier fil, tu disais que dans les langages OO, tout
était objet. Mais concrètement - si tu as quelques minutes encore à me
consacrer -, ça sert à quoi qu'une variable, par exemple, soit un objet ?
>Pour clore ce premier fil, tu disais que dans les langages OO, tout
>�tait objet. Mais concr�tement - si tu as quelques minutes encore � me
>consacrer -, �a sert � quoi qu'une variable, par exemple, soit un objet ?
Cela permet de simplifier le langage. Tout se g�re de la m�me fa�on.
J'en profite pour rappeler que le PHP est �crit en C ou C++ et que sa
syntaxe est inspir�e du C++. Le langage C a �volu� vers le C++ mais
beaucoup de programmeurs comme moi continuent � m�langer les concepts
des deux langages et � faire du code avec � la fois du C et du C++.
Je pense que cela vient de la fa�on dont on a appris le langage. Si
quelqu'un d�bute en POO directement sans avoir connu de langage
proc�dural ou s�quentiel, il est probable que son code en PHP sera
beaucoup plus pr�s du POO que s'il a suivi la vieille route plus
traditionnelle alors qu'on d�butait avec les classiques de l'�poque
(Fortran ou Basic dans mon cas, Pascal un peu plus tard, puis
langage C quand il est devenu plus populaire).
Un concept int�ressant de la POO est qu'on fait une action sur un
objet alors qu'en langage proc�dural, on fait une s�rie d'actions
pour obtenir un r�sultat. En PHP, il est rare que cela soit
important puisque la plupart des pages en PHP sont appel�es une seule
fois et que l'action perform�e n'aura pas de cons�quence plus tard.
Mais dans les grosses applications, chaque fois qu'une page sera
affich�e, cela pourrait avoir un effet sur la page suivante (par
exemple, si on fait une boutique en ligne, on ajoute quelque chose
au panier et ce panier est conserv� et augment�, puis transform�
en facture ou achat). On peut alors faire un parall�le avec les
objets en question, le panier devenant un objet par exemple.
Denis
Définition selon laquelle ni C++ ni Java ne sont des langages objets,
puisque les deux ont des types non-objet !-)
Fais pas gaffe, je suis un peu extrémiste, des fois...
> Mais concrètement - si tu as quelques minutes encore à me
> consacrer -, ça sert à quoi qu'une variable, par exemple, soit un objet ?
Dans l'absolu, à rien, pourquoi ?-)
Plus sérieusement, avoir un modèle à peu près uniforme simplifie
nettement la vie - que ce soit un modèle objet ou non, d'ailleurs. Mais
ce dont je parlais était plus de l'ordre d'une différence d'utilisation
pratique induite par le fait que le langage soit _fondamentalement_ un
langage objet ou non.
En Python ou en Ruby, il est naturel et évident d'utiliser des objets,
puisque tout ce que tu peux manipuler est un forcément un objet[1].
En PHP, la surcouche objet est et reste une surcouche par dessus un
langage fondamentalement procédural, et il plus naturel et évident (et,
pour la plupart des besoins, plus efficace) d'utiliser une approche
procédurale.
Accessoirement, le modèle objet de PHP est *très* loin derrière ceux de
Ruby et Python en terme de fonctionnalités, de souplesse et de
puissance. Ca tient un peu de la comparaison entre une trotinette et un
missile balistique !-)
Accessoirement aussi, une architecture tout-objet (avec le surcoût que
ça implique) n'est pas vraiment optimale dans le contexte du modèle
d'exécution de PHP, où il faut reconstruire le mondre entier à chaque
requête HTTP.
[1] Ca n'interdit pas (en Python au moins) d'avoir des fonctions
"ordinaires", mais ces fonctions elles-mêmes sont des objets. Bref,
Python ne force pas à tout mettre dans des classes (comme Java par
exemple), et n'interdit pas de mixer procédural et OO (et même un peu de
FP).
Si je puis me permettre de répondre, en admettant que PHP soit ce genre
de langage, au lieu d'utiliser la fonction "in_array()", on pourrait
invoquer la méthode correspondante d'un objet de type "Array".
Ça donnerait :
<?php
// On crée un objet de type "Array", d'où l'opérateur "new".
$tableau = new Array("tata", "momo", "lili");
// On teste l'existence d'un élément dans le tableau.
$test = $tableau->in_array("riri"); // donne FALSE dans l'ex.
?>
Ce serait donc une écriture différente et, peut-être, offrirait une
meilleure sémantique au codage.
Cordialement,
Pascal
> [1] Ca n'interdit pas (en Python au moins) d'avoir des fonctions
> "ordinaires", mais ces fonctions elles-mêmes sont des objets. Bref,
> Python ne force pas à tout mettre dans des classes (comme Java par
> exemple), et n'interdit pas de mixer procédural et OO (et même un peu de
> FP).
ça explique pourquoi j'ai déjà fait des scripts Python sans trop voir de
différences avec PHP :o)
Merci pour ces éclaircissements.
Ou, pour aborder les choses à un plus haut niveau, on pourrait envisager
un operateur 'in' qui fonctionne sur tout objet implémentant
l'interface approprié, ce qui permettrait de ne pas se soucier du type
exact de la "collection" utilisée (tableau ou autre). De même, on
pourrait envisager une implémentation de foreach() qui permette d'itérer
sur tout objet implémentant l'interface adéquate - idem, on gagne
beaucoup en généricité.
Un des objectifs de l'OO est de découpler l'interface de
l'implémentation. D'une part pour faciliter la maintenance
(encapsulation), et d'autre part pour accroitre la généricité
(polymorphisme).
> Je pense que cela vient de la fa�on dont on a appris le langage. Si
> quelqu'un d�bute en POO directement sans avoir connu de langage
> proc�dural ou s�quentiel, il est probable que son code en PHP sera
> beaucoup plus pr�s du POO que s'il a suivi la vieille route plus
> traditionnelle alors qu'on d�butait avec les classiques de l'�poque
J'ai appris la programmation avec _d'abord_ des langages OO, et je tends
� �crire du PHP tr�s proc�dural (et du Python tr�s objet).
> Un concept int�ressant de la POO est qu'on fait une action sur un
> objet
Le concept essentiel est surtout qu'on ne "fait" pas "une action sur un
objet", mais qu'on lui envoie un message. Ce qu'il fait (ou non) �
r�ception de ce message ne concernant que lui. Enfin, th�oriquement !-)
Une des parties importantes de ce concept �tant justement que le
comportement d'un objet donn� � r�ception d'un message donn� est bien
d�coupl� de l'envoi du message en lui-m�me - ce qui permet (entre
autres) d'avoir, pour un m�me message, des comportements diff�rents
selon les objets r�cepteurs (polymorphisme), ou, pour un m�me objet, de
modifier le comportement pour un message donn� sans avoir � se soucier
des �metteurs (encapsulation).
> alors qu'en langage proc�dural, on fait une s�rie d'actions
> pour obtenir un r�sultat.
Mouais... Enfin, n'oublions pas que cette "s�rie d'action" doit bien
�tre impl�ment�e quelque part !-)
> En PHP, il est rare que cela soit
> important puisque la plupart des pages en PHP sont appel�es une seule
> fois et que l'action perform�e n'aura pas de cons�quence plus tard.
> Mais dans les grosses applications, chaque fois qu'une page sera
> affich�e, cela pourrait avoir un effet sur la page suivante (par
> exemple, si on fait une boutique en ligne, on ajoute quelque chose
> au panier et ce panier est conserv� et augment�, puis transform�
> en facture ou achat). On peut alors faire un parall�le avec les
> objets en question, le panier devenant un objet par exemple.
Un ADT suffit � obtenir le m�me r�sultat.
11/10/2009 06:05 PM, Denis Beauregard:
> J'en profite pour rappeler que le PHP est �crit en C ou C++ et que sa
> syntaxe est inspir�e du C++. Le langage C a �volu� vers le C++
Est-ce bien vrai, tout cela?
Il me semble que, contrairement � ce que Denis affirme,
C est rest� C, et que C++ est un "genre de fork" du C.
Me tromp�-je?
PS: on peut attendre vendredi pour en parler,
ce n'est pas ce qui est le plus urgent.
--
Administration syst�me
Recherche & D�veloppement
GulfSat/Blueline, Madagascar
Tel: +261 33 11 207 36
Hum...
- Typage faible?
- Polymorphisme?
Si on pouvait en discuter de maniere générale sur le bon groupe, je suis partant.
Je propose et applique un suivi sur fr.comp.lang.general
En effet, ce dont parle Bruno, là, releve-t-il de la notion de typage faible ou bien
du polymorphisme?
Pouvoir itérer indiférement sur:
- une chaine de caractère
- un tuple
- une liste
- un tableau
- ...
Ceci avec la meme fonction (puisqu'il parle de meme interface)?
Tout s'embrouille dans mon esprit...
--
Administration système
Recherche & Développement