IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Petite question sur une curiosité du langage [PHP 5.6]


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : Février 2005
    Messages : 242
    Points : 63
    Points
    63
    Par défaut Petite question sur une curiosité du langage
    Bonsoir,

    J'étais en train de développer paisiblement en PHP jusqu'à tomber sur un code récalcitrant : à première vue, une erreur de logique de ma part.

    A grand coup de var_dump() et de echo, je débug vaillamment, mais le résultat est le même. Du coup, je décide d'isoler l'instruction qui pose problème dans un autre script de test. Mais je constate que la bizarrerie persiste.

    Sans vous faire plus attendre, je m'explique tout de suite avec une série de tests ci-dessous (testé sur phptester.net en version 5.5 et sur mon WampServer 3 avec PHP 5.6.15) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    <?php
     
              var_dump(3 == 3); // renvoie true (normal!)
              var_dump("3" == 3); // renvoie true (compréhensible pour un langage faiblement typé)
              var_dump("3" === 3); // renvoie false (on voit l'utilité de l'opérateur de comparaison strict)
     
              // c'est là que ça se gâte ^^
              var_dump("3-1-2" == 3); // renvoie true (WTF !!!)
              var_dump("3-1-2" === 3); // renvoie false (logique puisque les types sont différents)
     
              // on poussant les tests, je m'aperçois que je peux mettre n'importe quoi derrière le premier chiffre de la chaîne
              // PHP voit toujours ces deux expressions comme "égales"
              var_dump("3xxxxxxxx" == 3); // renvoie toujours true (!!)
     
              var_dump("39xxx" == 39); // -> true : idem avec plusieurs chiffres dans le nombre
              var_dump("424yyy" == 424); // -> true
     
              var_dump("3.1.9" == 39); // -> false : avec des points 
     
    ?>
    Bref, peut-être qu'il y a une explication logique, peut-être pas. J'ai recherché sur Internet si un éventuel bug existait mias je ne trouve rien.

    Du coup ma question est simple : avez-vous déjà rencontré ce cas de figure et existe-t-il une explication car du point de vue logique ce n'est pas correct du tout quand même ^^.

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    La valeur est fournie par la portion initiale de la chaîne de caractères. Si la chaîne de caractères commence par une donnée numérique valide, ce sera la valeur utilisée.
    http://php.net/manual/fr/language.ty...ing.conversion
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Ce n'est pas du tout un bug, c'est prévu comme ça et indiqué dans la doc (après la question "est-ce que c'est la bonne approche ou pas" est un autre sujet).

    http://php.net/manual/en/language.ty...ing.conversion
    Quand tu compares un string et un entier, PHP va d'abord chercher à convertir le string en entier. Si ce n'est pas possible (ex si le string est "3-2-1"), il va le convertir en float. Mais la "conversion" en float ne prends en compte que les premiers caractères numériques à gauche du string, et s'arrête dès qu'il y a un caractère non numérique. "3-2-1" va donc être tronqué en 3. D'où le résultat true.

    La leçon de l'histoire:
    - Ne jamais comparer un string non numérique avec un entier ou un float.
    - Ne jamais comparer un string avec un entier ou un float, sauf si on est absolument sûr que le string est de type numérique, mais dans ce cas pourquoi ne pas le caster en int ou float tout de suite?
    - Ne jamais utiliser l'opérateur ==, sauf si on sait précisément quel résultat on veut avoir. L'opérateur de comparaison par défaut doit être ===.

  4. #4
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : Février 2005
    Messages : 242
    Points : 63
    Points
    63
    Par défaut
    Merci pour la réponse rapide.

    Effectivement, c'est bien noté dans la doc. J'avais chercher "comparaison entier chaine php" mais je n'avais pas pensé au processus de conversion implicite réalisé par PHP.

    La leçon est bien retenue. ^^
    • Cela fait un petit moment que je n'utilise que ===, c'est juste que là j'avais fait une erreur de frappe en omettant le troisième.
    • Avant votre réponse, j'ai fait le cast nécessaire, pour être sûr de comparer deux types identiques.


    En tout cas encore merci j'aurais appris un peu plus sur le fonctionnement de PHP.
    Mais entre nous, et ce n'est que mon avis personnel, je trouve ce comportement un peu absurde. xD

  5. #5
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Pour moi le problème n'est pas de mettre == mais de se retrouver dans une situation où on compare des valeurs qui ne sont pas du même type.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  6. #6
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : Février 2005
    Messages : 242
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Pour moi le problème n'est pas de mettre == mais de se retrouver dans une situation où on compare des valeurs qui ne sont pas du même type.
    Ma variable peut-être soit de type int soit string.

    En tout cas, j'ai eu la réponse à ma question.

    Merci beaucoup.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WS 2003] Petite question sur une GPO
    Par Damzz dans le forum Windows Serveur
    Réponses: 1
    Dernier message: 01/11/2010, 09h24
  2. Petite question sur une requete
    Par dam28800 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 16/02/2010, 09h30
  3. [MySQL] Petite question sur une erreur de mysql
    Par iwf-fr dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 13/12/2006, 16h23
  4. Petite question sur une IHM
    Par beb30 dans le forum MFC
    Réponses: 12
    Dernier message: 10/04/2006, 15h19
  5. Réponses: 24
    Dernier message: 29/08/2005, 13h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo