Journal ha le php et ses élites

Posté par .
Tags : aucun
3
13
oct.
2009
Bonjour,

Je ne résiste pas à vous faire part de quelques fonctions choisies découvertes lors de la maintenance d'un site web.

Voici déjà les équivalents respectifs de addslashes et de htmlentities

function champ2mysql($champ){
$trans = array("'" => "\'", "\\" => "\\\\");
return strtr($champ, $trans);
}



function affiche_accents($champ){
$trans =
array(
"à" => "à",

"â" => "â",

"ä" => "ä",

"é" => "é",

"è" => "è",

"ê" => "ê",

"ë" => "ë",

"î" => "î",

"ï" => "ï",

"ô" => "ô",

"ö" => "ö",

"ù" => "ù",

"û" => "û",

"ü" => "ü",

"ç" => "ç"
);
return strtr($champ, $trans);
}

Passons maintenant aux fonctions de validations de formulaires.

function is_commentaire ( $s ) {
return true;
}

function is_URL($url){
if (!eregi("^http://", $url)) {
return FALSE;
}
$details = parse_url($url);
if (!isset($details['port'])) {
$details['port'] = "80";
}
if (!isset($details['path'])) {
$details['path'] = "/";
}
if (!ereg("[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+", $details['host'])){
$details['host'] = gethostbyname($details['host']);
}
if ($sock = fsockopen( $details['host'], $details['port'])){
$requete = "GET ".$details['path']." HTTP/1.1\r\n";
$requete .= "Host: ".$details['host']."\r\n\r\n";
fputs($sock, $requete);
$str = fgets($sock, 1024);
while(!ereg('^HTTP/1.1 ', $str)){
$str = fgets($sock, 1024);
}
fclose($sock);
list($http, $str, $texte) = explode(" ", $str, 3);
return array($str, $reponse[$str]);
}
return FALSE;
}
  • # affiche_accent

    Posté par . Évalué à 4.

    Les valeurs du tableau sont les entités html : è é etc...
  • # The Daily WTF

    Posté par . Évalué à 9.

    Si tu as des bons morceaux, envoie les à The Daily WTF, pour leur section Code SOD (Snippet of death) : http://thedailywtf.com/Series/CodeSOD.aspx
    • [^] # Re: The Daily WTF

      Posté par . Évalué à 1.

      Hé hé justement en voyant tout ça, moi qui n'y connais vraiment pas grand chose au code en général, j'ai cru me retrouver sur le site du Daily WTF...

      Heureusement qu'ils font des articles avec des images de temps en temps :)
  • # Explications ?

    Posté par . Évalué à 10.

    Pour un (les ?) béotien(s) du PHP, pourrait-on avoir quelques explications ?
    Même si leur apparence prête à réfléchir pour quiconque a une petite expérience de programmation, en quoi ces bouts de code sont-ils à éviter ?
    En gros, que font-ils (pas facile à savoir quand on n'en a jamais fait), comment le font-ils mal et comment peut-on y remédier ?

    Merci
  • # Hoho

    Posté par . Évalué à 10.

    J'aime assez la fonction is_commentaire...
    • [^] # Re: Hoho

      Posté par . Évalué à 5.

      Elle m'a fait penser à ça[1]...

      1 http://xkcd.com/221/
    • [^] # Re: Hoho

      Posté par . Évalué à 4.

      Peut-être une fonction prévue mais pas encore implémentée ?
      • [^] # Re: Hoho

        Posté par (page perso) . Évalué à 4.

        Je suis plutôt d'accord. Je pratique souvent ça. Ca évite plus tard de se retaper tout le code pour savoir où mettre les tests.
      • [^] # Re: Hoho

        Posté par (page perso) . Évalué à 1.

        Cela n'empêche pas que le nom de la fonction est à moitié en anglais, à moitié en français.
        • [^] # Re: Hoho

          Posté par . Évalué à 2.

          En java, la norme recommande que les accesseurs de propriétés s'appellent "get*"/"set*" où * peut être un nom dans n'importe quelle langue. C'est donc relativement courant.
          • [^] # Re: Hoho

            Posté par (page perso) . Évalué à 1.

            Ah bah si tout le monde le fait, c'est que c'est bien !
          • [^] # Re: Hoho

            Posté par . Évalué à 1.

            Oui, pendant mon apprentissage j'ai travaillé sur une appli java avec des isNullOuVide, des getNom, etc.

            En fait, l'équipe utilisait Eclipse, donc ils avaient juste à créer la classe et ses membres, et faire générer les getter/setter par Eclipse. Je doute que quiconque ait envie de passer derrière pour tout traduire.
            • [^] # Re: Hoho

              Posté par . Évalué à 1.

              L'erreur dans ce cas, c'est de mettre les noms d'attributs en francais (ou toute autre langue que l'anglais).

              - La philosophie java, soutenue par la notion de bean, exige que les getter/setter commencent par get/is/set.
              - D'un point de vue lisibilite du code, t'as pas envie d'avoir un attribut nom qui est accede par getName(). Va retrouver tes petits la dedans.

              Donc meme si Java supporte parfaitement un code source ecrit en mandarin oriental via UTF8, c'est une grosse erreur que de coder dans une autre langue.
              Ca serait moins genant si java avait de vraies properties et pas juste un concept batard d'attributs accedes par un wrapper suivant une convention de nommage, mais bon, c'est pas comme si le langage etait repute pour evoluer a la vitesse de l'eclair au galop, donc faut faire avec.

              Ca me rappelle un prof a la fac qui codait en francais, avec les accents et tout.
              Tres sympa pour ceux qui ont un clavier qwerty et qui doivent utiliser sa lib...
              • [^] # Re: Hoho

                Posté par (page perso) . Évalué à 2.

                Parfois, c'est le client qui exige que tout le projet soit en Français, y compris le code source...
                • [^] # Re: Hoho

                  Posté par (page perso) . Évalué à 0.

                  Quoi ? Y'a des informaticiens/développeurs qui ne parlent pas anglais ?

                  I can't believe it... Oups, pardon, je voulais dire "je le crois pas" (ça c'est pour le client, je voudrais pas le froisser non plus :p).
                • [^] # Re: Hoho

                  Posté par . Évalué à 1.

                  Les clients aussi font des erreurs.
                  On a juste pas trop le droit de leur dire. Pas tant qu'ils ont pas paye tout du moins.
              • [^] # Re: Hoho

                Posté par . Évalué à 2.

                Ah mais je suis d'accord :)
                Seulement, moi j'avais pas mon mot à dire hein :p
                Tout était déjà en français, alors j'ai fait avec.
              • [^] # Re: Hoho

                Posté par . Évalué à 2.

                Tiens, d'ailleurs ça donne quoi get/set en français ? "isInteger" je vois bien, ça donnerait "estEntier". Mais "getName" et "setName" ? "obtenirNom" et "definirNom" ?
  • # Petit joueur....

    Posté par . Évalué à 5.

    Une petite macro parmi plein d'autres dans le code sur lequel je bosse :


    #define UOL_IMPLEMENT_FIND_INFO_CLASS(class_name,base_class) \
    UOL_IMPLEMENT_SERIAL( class_name##FindInfo, base_class##FindInfo, \
    UOL_RUNTIME_CLASS(class_name)->GetSchema() | VERSIONABLE_SUBSCHEMA ) \
    class_name##FindInfo::class_name##FindInfo( class_name##Properties *pOriginal ) \
    : m_pOriginal( pOriginal ) { if( m_pOriginal ) m_pOriginal->AddRef() ; } \
    void class_name##FindInfo::OnCreate( UINT uFlags ) \
    { base_class##FindInfo::OnCreate( uFlags ) ; \
    if( GetRuntimeClass() == UOL_RUNTIME_CLASS( class_name##FindInfo ) ) { \
    ASSERT( !m_pProperties ) ; \
    m_pProperties = new class_name##Properties ; \
    m_pProperties->Initialize( this, m_pOriginal ) ; \
    m_pProperties->OnCreate( uFlags ) ; UOL_ASSERT_VALID( m_pProperties ) ; \
    m_pProperties->AddRef() ; \
    if( m_pOriginal ) { SetClass( m_pOriginal->GetOwner()->GetRuntimeClass() ) ; \
    CUOLGUID *pGUID = dynamic_cast<CUOLGUID *>( m_pOriginal->GetOwner() ) ; \
    UOL_ASSERT_VALID( pGUID ) ; SetGUID( &pGUID->GetGUID() ) ; } \
    else SetClass( UOL_RUNTIME_CLASS( class_name ) ) ; \
    if( m_pOriginal ) m_pOriginal->ReleaseRef() ; } } \
    __UOL_IMPLEMENT_GET_PROPERTIES(class_name##FindInfo,class_name##Properties) \
    __UOL_IMPLEMENT_DIAGNOSTICS_FIND_INFO(class_name,base_class)

    • [^] # Re: Petit joueur....

      Posté par . Évalué à 7.

      les gens qui pondent ce genre de truc faudrait des obliger à maintenir leur code
      • [^] # Re: Petit joueur....

        Posté par (page perso) . Évalué à 10.

        s/maintenir/manger la version carte perforées de/

        Sans sel.
      • [^] # Re: Petit joueur....

        Posté par (page perso) . Évalué à 3.

        Comment tu fais quand ils ont quitté la boite ? :-)
        • [^] # Re: Petit joueur....

          Posté par (page perso) . Évalué à 4.

          Après avoir écrit ça, ils n'ont plus le droit de quitter la boite :)
          • [^] # Re: Petit joueur....j

            Posté par (page perso) . Évalué à 6.

            On ferait peut-être mieux de les virer aussi sec ?

            pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

            • [^] # Re: Petit joueur....j

              Posté par . Évalué à 9.

              Ya mieux, tu leur casses les phalanges des 2 pieds.

              Comme ca, ils seront bien force d'arreter de coder avec les pieds.

              :)
          • [^] # Re: Petit joueur....

            Posté par . Évalué à 2.

            Et s'il réussit quand même à quitter la boite en se suicidant ?
          • [^] # Re: Petit joueur....

            Posté par . Évalué à 10.

            je suis dans un domaine technique ou il y est possible de faire des d'horreurs. Quand je tombe dessus je telephone au gars qui a quitté la boite, et j'insiste bien sur son horreur. Des fois qu 'il ai envie de recommencer dans sa nouvelle boite. Et des fois que vraiment pas de bol j'arrive dans sa boite, et que je te tombe de nouveau sur ses horreurs/erreurs.

            Bon je n'ai telephoné que 2 fois, en toute cordialité.

            les mecs font des conneries et si personne ne leur dit , toute leur vie il vont pourrir celle des autres
          • [^] # Re: Petit joueur....

            Posté par (page perso) . Évalué à 8.

            Après avoir écrit ça, ils n'ont plus le droit de quitter la boite :)

            Ca va peut-être t'étonner mais : c'est le but!

            On peut facilement virer un mec qui a fait un code lisible (quelqu'un d'autre va le reprendre), et on ne se prive parfois pas.
            On peut plus difficilement virer un mec qui fait un code pourri (personne ne sera capable de le maintenir), donc on garde l'enfoiré de service grande gueule asocial.

            Ou comment inciter les gens à faire un mauvais code pour garder leur poste...
            • [^] # Re: Petit joueur....

              Posté par . Évalué à 4.

              Moui, c'est pour ça que plus t'es mauvais, plus tu prend du grade...

              Enfin bon, on a tous déjà vu des script sur une seul ligne sans commentaire...
              Ce qui est TRES fort, c'est quand l'auteur se vante devant les béotien de savoir faire les choses avec une seul ligne de code dans un fichier texte (sans bien sur leur préciser que la ligne en question fait 2000 caractères...), du coup le gars passe pour super balèze alors qu'en fait, c'est un naze!

              Bienvenu dans le monde du travail...
    • [^] # Re: Petit joueur....

      Posté par (page perso) . Évalué à 10.

      Et tu te retrouves avec ce qui suit dans un fichier que tu compiles ?


      #include "programme.h"

      PROGRAMME;


      Quand même, ça simplifie bien la lecture ...

      "It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell

    • [^] # Alors moi j'ai des fortunes.

      Posté par (page perso) . Évalué à 3.

      http://ms800.montefiore.ulg.ac.be/~kunysz/fortunes/info0030

      Et quelques unes que j'ai du boulot :
      /*
      * Initially, we populate the island with all the rifraff peers
      * that happen to be lying around. Those with seriously
      * defective clocks are immediately booted off the island. Then,
      * the falsetickers are culled and put to sea. The truechimers
      * remaining are subject to repeated rounds where the most
      * unpopular at each round is kicked off. When the population
      * has dwindled to sys_minclock, the survivors split a million
      * bucks and collectively crank the chimes.
      */
      -- ntp-4.2.2p1/ntpd/ntp_proto.c:clock_select()
      %
      select(0, NULL, NULL, NULL, &tv); // ought to loop until done
      -- top.c
      %
      ret = setsockopt(sockfd, TC_IPPROTO, SO_SET_REPLACE, repl,
      sizeof(*repl) + repl->size);
      if (ret < 0) {
      errno = ret;
      -- iptables/libiptc/libiptc.c:TC_COMMIT()
      %
      <XXX> kernel: Badness in __writeback_single_inode -- does that telle something to anyone ?
      <YYY> XXX, it means __writeback_single_inode was coded by samuel l. jackson
      %
      if (pn->inode==inode) {
      /* Some warning should be appropriate here
      as we got multiple processes for one i-node */
      return;
      }
      -- netstat.c
      %
      #define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE)
      -- netstat.c
      %
      * XXX is trying to understand how coreutils' get_date() works
      * XXX feels pathetic
      %

      J'en ai aussi sur TDWTF.

      pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

    • [^] # Re: Petit joueur....

      Posté par . Évalué à 1.

      Alors là, je suis partagé... En effet, je suis assez fan de méga (voire monstro) macro qui permettent de factoriser du code assez bien. Par exemple, mon dernier exemple en date, pour ceux qui connaissent, le codage d'une bibliothèque pour l'environnement Lua (petit moteur de script, très portable et donc parfait pour l'embarqué). L'ajout de nouveaux types dans Lua est très redondant et si on veut déclarer et utiliser ces types, les macros sont vraiment super.
      Après, il faut savoir leur donner de la gueule. Je suis d'accord que dans l'exemple ci-dessus, c'est vraiment dégueu, mais il suffit de coder la macro comme du code normal (avec les retours chariots et l'indentation d'un code propre), puis avec une commande de remplacement on rajoute un '\' en fin de chaque ligne (sauf la dernière) et enfin (le meilleur !!), grâce à l'outil génial "tal" (http://thomasjensen.com/software/tal/), pour lequel on a évidemment rajouté un raccourci dans vim, on aligne proprement les '\' en fin de ligne. Et voilà, le tour est joué ! Au prochain épisode, comment débugger les macros avec gdb...
      • [^] # Re: Petit joueur....

        Posté par . Évalué à 8.

        Non non, il n'y a aucune excuse pour cette monstruosite.

        Tu utilises des fonctions inline au besoin, mais un truc pareil c'est tout simplement inacceptable, le jour ou je vois un jeunot pondre un truc pareil dans une code review, je lui code 2 claques et l'envoie nettoyer les chiottes.
        • [^] # Re: Petit joueur....

          Posté par . Évalué à 2.

          Y'a des fois où c'est pas possible de le faire avec des fonctions (inline ou pas). Les macros offre la concaténation des arguments (opérateur ##) et c'est sacrément utile !
          • [^] # Re: Petit joueur....

            Posté par . Évalué à 3.

            La concatenation des arguments c'est une ligne, le reste est en inline, t'as vraiment _JAMAIS_ besoin d'une macro de 30-40 lignes
            • [^] # Re: Petit joueur....

              Posté par . Évalué à 8.

              ni de plus de 640 ko de RAM...
            • [^] # Re: Petit joueur....

              Posté par (page perso) . Évalué à 7.

              Tu peux en avoir grandement besoin : http://www.ioccc.org/

              "It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell

            • [^] # Re: Petit joueur....

              Posté par . Évalué à 3.

              Tu ferais comment pour libetc ? (http://ordiluc.net/fs/libetc/)

              Petit extrait :


              #define REWRITE_FUNCTION_SIMPLE(return_type, function_name, signature, orig_call) \
              return_type function_name signature { \
              return_type return_value; \
              char *new_path; \
              \
              PRINT_DEBUG(#function_name ": %s\n", path); \
              \
              new_path = translate (path); \
              return_value = orig_##function_name orig_call; \
              free (new_path); \
              return return_value; \
              }

              REWRITE_FUNCTION_SIMPLE(FILE*, fopen, (const char *path, const char *mode), (new_path, mode))
              REWRITE_FUNCTION_SIMPLE(FILE*, fopen64, (const char *path, const char *mode), (new_path, mode))
              REWRITE_FUNCTION_SIMPLE(FILE*, freopen, (const char *path, const char *mode, FILE *stream), (new_path, mode, stream))
              // … et plein d’autres fonctions comme ça
        • [^] # Re: Petit joueur....

          Posté par . Évalué à 1.

          cette monstruosité comme tu l'appelle, il y en a plein dans les MFC... tu ferais bien de transmettre à tes supérieurs....
          • [^] # Re: Petit joueur....

            Posté par . Évalué à -1.

            Oh rassures toi ca a ete transmis et le message est passe, cf. WPF
            • [^] # Re: Petit joueur....

              Posté par . Évalué à 2.

              Le souci, c'est que WPF n'est pas utilisable qu'en C++/CLI et non directement en c++ natif! On est donc obligé d'utiliser la plateforme .NET pour en tirer parti... l'idée était bonne, mais l'enfermement de cette techno en fait un frein direct à son utilisation.
              Ce serait bien de transmettre le message aussi...
              • [^] # Re: Petit joueur....

                Posté par . Évalué à 1.

                "Le souci, c'est que WPF n'est pas utilisable qu'en C++/CLI et non directement en c++ natif!
                Enfin, je suppose... Parce que sinon je ne comprends pas bien ce que tu cherches à nous dire !
    • [^] # Re: Petit joueur....

      Posté par (page perso) . Évalué à 1.

      C'est amusant, ça ressemble à du code auto-généré. C'est bien un des très rares cas où ce genre de chose est acceptable.
  • # Il y a même un guide pour écrire du code comme ça !

    Posté par . Évalué à 10.

    How To Write Unmaintainable Code : [http://freeworld.thc.org/root/phun/unmaintain.html].

    Comme ils disaient dans une boite ou j'ai passé quelques temps : Nos bugs d'aujourd'hui sont nos emplois de demain.
  • # Avec les trous de sécus en plus !

    Posté par . Évalué à 5.

    Ave,

    Dans la même veine : Aux RMLL 2005, y'avait une conférence par des développeur de NPDS (Nuke Permanent Double Side devenu Net Portal Dynamic System). À un moment, ils présentent une fonctionnalité du CMS : permettre aux utilisateurs d'exécuter du code PHP dans les commentaires. Admettons que ça soit intéressant.

    Et là, la révélation quelque diapos suivant : ils ont réimplémenter la fonction '[http://php.net/call_user_func_array]' avec des gros switch sur le nombre de paramètre qui gérait de 1 à 10 paramètres et générait un code PHP avec de la bête concaténation avant d'évaluer tout ça. Ils ont inventé l'injection de code PHP :)

    4 ans plus, tard, je suis toujours aussi choqué :)

    Étienne.
    • [^] # Re: Avec les trous de sécus en plus !

      Posté par (page perso) . Évalué à 8.

      permettre aux utilisateurs d'exécuter du code PHP dans les commentaires. Admettons que ça soit intéressant.

      Je suis déjà choqué à ce point.
    • [^] # Re: Avec les trous de sécus en plus !

      Posté par (page perso) . Évalué à 1.

      Hum en réalité je comprends un peu le truc.

      Imaginons que je sois dans un objet Pages qui gère les pages d'un site (cas réel), je veux avoir un système de signaux qui permette de greffer des plugins sur mon code de manière propre. Je vais donc avoir une méthode de ce genre :


      public function createPage($title, $lang, $uri = '', $online = true)
      {
      $this->emitSignal('page.create.before', $title, $lang, $uri, $online);
      DB::query('INSERT INTO pages (id, title, lang, uri, online) VALUES (NULL, \''.DB::escape($title).'\', ....
      }


      OK et je veux que emitSignals transmette les arguments en référence au callback du plugin. Je ne peux donc pas faire ça :


      public function emitSignal($name)
      {
      $callback = array('myPlugin', 'myCallback');
      call_user_func($callback, &$this, func_get_args());
      }


      Ça aurait été bien pratique mais func_get_args ne sait pas renvoyer une référence des arguments. Va donc falloir ruser :


      public function emitSignal($signal, &$arg1 = null, &$arg2 = null, &$arg3 = null, &$arg4 = null, &$arg5 = null, &$arg6 = null, &$arg7 = null, &$arg8 = null, &$arg9 =
      null)
      {
      $callback = array('myPlugin', 'myCallback');
      call_user_func($callback, &$this, &$arg1, &$arg2, &$arg3, &$arg4, &$arg5, &$arg6, &$arg7, &$arg8, &$arg9);
      }


      En priant très fort qu'on n'ait jamais besoin de plus de 9 arguments (déjà que le code est horrible). PHP a plein de ce genre de lacunes avec lesquelles il faut composer dès qu'on veux faire des trucs un chouia complexe. Ça s'améliore avec le temps heureusement (et PHP6 est très prometteur sur ce point), mais faut encore faire avec. Donc dans un sens je peux comprendre les mecs de NPDS, même si l'idée de base est mauvaise (irk).

      Sinon dans les autres trucs rigolos :

      define('<?php die("HUHUHU"); ?>', 'AH AHAHAHHA');

      Contrairement à toute attente (et au manuel PHP qui dis que seuls certains caractères sont autorisés dans le nom d'un define), ça fonctionne. On ne peut pas accéder au define (à part avec get_defined_constants()) mais on peux le définir...

      « Je vois bien à quels excès peut conduire une démocratie d'opinion débridée, je le vis tous les jours. » (Nicolas Sarkozy)

      • [^] # Re: Avec les trous de sécus en plus !

        Posté par . Évalué à 3.

        Pourquoi passer tout ça en référence ? Pourquoi ne pas utiliser des objets à la place ? (si tu veux pouvoir les modifier)
        • [^] # Re: Avec les trous de sécus en plus !

          Posté par (page perso) . Évalué à 2.

          Des objets ? Que veux-tu dire ?

          « Je vois bien à quels excès peut conduire une démocratie d'opinion débridée, je le vis tous les jours. » (Nicolas Sarkozy)

          • [^] # Re: Avec les trous de sécus en plus !

            Posté par . Évalué à 1.

            Des instances de classes. Les objets sont toujours passés par "référence".

            Les autres types (strings, ints) ne le sont pas. Dans ce cas ils agissent un peu comme dans beaucoup de langages de scripts : Ils sont immuables. D'ailleurs est-ce que tu as une meilleur solution pour ta méthode emit dans un autre langage de script ?
  • # A deux trois exceptions près

    Posté par (page perso) . Évalué à 3.

    La norme du langage Scheme dit : « si on peut le coder, alors ça n'a pas sa place dans le langage. »
    Ensuite, t'as les libs. Et quand tu fais un logiciel pour faire du Machin 2.0, alors tu prends le SRFI-machin, le Egg-machin, le dumping-grounded-machin… (en gros, une lib).

    C'est aussi le cas de Perl et du CPAN (où tu vas d'abord chercher la solution à ton problème avant de réflechir à comment le résoudre).

    Y'aurait-il que PHP pour coder en dur dans le langage la moitié de tous les programmes des utilisateurs du langage ?
    • [^] # Re: A deux trois exceptions près

      Posté par . Évalué à 3.

      "Y'aurait-il que PHP pour coder en dur dans le langage la moitié de tous les programmes des utilisateurs du langage ? "
      Et les mettre tous dans le namespace par défaut ! (en utilisant peu de préfixes bien sûr, qui aurait pu au moins amoindrir le problème)

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.