Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

j'apprends php 1

41 réponses
Avatar
Olivier Masson
Bonjour,

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.

10 réponses

1 2 3 4 5
Avatar
Olivier Masson
Olivier Miakinen a écrit :


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).
Avatar
Bruno Desthuilliers
Olivier Masson a écrit :
Merci pour vos réponses, c'est bien de savoir sur quoi on bosse.
N'étant pas développeur, je n'ai que peu de bonnes pratique, notamment
la poo.



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 ?-)
Avatar
Bruno Desthuilliers
Mickaël Wolff a écrit :
Bruno Desthuilliers a écrit :

Parce que PHP est codé avec les pieds !-)


Chut ! Des décideurs pressés vont t'entendre !



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à.
Avatar
Olivier Miakinen
Le 06/11/2009 00:49, j'écrivais :

Allez, je vais lire le reste, ça risque d'être drôle.



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
Avatar
Olivier Masson
CrazyCat a écrit :

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 ;)
Avatar
Olivier Masson
Bruno Desthuilliers a écrit :
Olivier Masson a écrit :
Merci pour vos réponses, c'est bien de savoir sur quoi on bosse.
N'étant pas développeur, je n'ai que peu de bonnes pratique, notamment
la poo.



La POO n'est pas en soi une "bonne pratique".



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, '', '&amp;');
}
Avatar
Bruno Desthuilliers
Olivier Masson a écrit :
Bruno Desthuilliers a écrit :
Olivier Masson a écrit :
Merci pour vos réponses, c'est bien de savoir sur quoi on bosse.
N'étant pas développeur, je n'ai que peu de bonnes pratique,
notamment la poo.



La POO n'est pas en soi une "bonne pratique".



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).



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, '', '&amp;');
}



Manque quand même un truc : là tu renvoie une querystring, pas une URL
complète.
Avatar
Olivier Miakinen
Bonjour,

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, '', '&amp;');
}



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
Avatar
Olivier Miakinen
Le 06/11/2009 17:09, je répondais à Bruno Desthuilliers :

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 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
Avatar
Olivier Masson
Bruno Desthuilliers a écrit :

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, '', '&amp;');
}



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)
1 2 3 4 5