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 :

bug PHP 5.4.3 ? [PHP 5.4]


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 56
    Points
    56
    Par défaut bug PHP 5.4.3 ?
    Bonjour,

    Je viens de tomber sur une chose assez étrange en PHP 5.4.3,
    si quelqu'un peut confirmer mon impression.

    J'ai 2 fonctions :

    La première, appelle une fonction de création de dossier et test le déroulement de cette dernière avant d'exécuter ses propres instructions.

    La seconde créer le dossier, dont voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    private function creerDossier($path)
    {
        return (file_exists($path)) ? 'FOLDER_ALREADY_EXISTS' : mkdir($path, 0777);
    }
    Voici les instructions d'appel de cette fonction, qui me retourne un truc assez bizarre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    // Creation du dossier de mise à jour
    $check_folder = $this -> creerDossier($maj_relative_path);
     
    // On vérifie que le dossier n'existe pas déjà (auquel cas, la mise à jour a déjà été proposée)
    if ($check_folder && $check_folder != 'FOLDER_ALREADY_EXISTS')
    {
          // instructions....
    Le problème, est que je ne rentre jamais dans ma condition...
    J'ai fait plusieurs tests dont voici le code, puis les résultats :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    echo 'CHECK FOLDER = exactement >>> ' . $check_folder . ' <<<<br />';
     
    if ($check_folder) echo 'CHECK FOLDER = TRUE<br />'; 
     
    if ($check_folder == 'FOLDER_ALREADY_EXISTS') echo 'CHECK FOLDER = FOLDER_ALREADY_EXISTS<br />'; 
     
    if (is_string($check_folder)) echo 'CHECK FOLDER est une string';
    le résultat est :

    CHECK FOLDER = exactement >>> 1 <<<
    CHECK FOLDER = TRUE
    CHECK FOLDER = FOLDER_ALREADY_EXISTS

    Je ne comprends pas du tout...
    1) le dossier n'existe pas de base.
    2) le dossier se créer quand même.
    3) si j'actualise ma page, j'obtiens :

    CHECK FOLDER = exactement >>> FOLDER_ALREADY_EXISTS <<<
    CHECK FOLDER = TRUE
    CHECK FOLDER = FOLDER_ALREADY_EXISTS
    CHECK FOLDER est une string

    Je suis assez perplexe sur le retour de ce code.
    Quelqu'un pourrait t'il m'éclairer ?

    Merci par avance

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je ne vois pas de problème particulier dans ton code et le comportement à l'air correct: une fois le dossier créé, la valeur spéciale "FOLDER_ALREADY_EXISTS" est correctement renvoyée, ce qui correspond au comportement attendu non ?

    Note: pour vérifier en même temps le type et la valeur d'une donnée, utilise var_dump

    Il y a en revanche un problème de sémantique dans ton code. Il est plus naturel pour la méthode creerDossier de renvoyer tout simplement un booléen (true > ok, false > nok) plutôt que de renvoyer une valeur arbitraire. Même si PHP est faiblement typé, utiliser plusieurs types de retours pour une fonction/méthode est relativement dangereux. Dans ton cas, renvoyer une valeur vraie (une chaine de caractères) alors que ça c'est manifestement mal passé est une mauvaise idée.

    Donc je te recommande d'utiliser soit un retour booléen:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
     
    class Foo {
     
        public function createFolder ($path) {
            return file_exists($path) ? false : mkdir($path);
     
            // ou en plus compact
            //return !file_exists($path) && mkdir($path);
        }
    }
    On peut aussi se servir des exceptions pour obtenir plus de finesse sur le cas d'erreur:
    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
    <?php
     
    class Foo {
     
        public function createFolder ($path) {
            if (file_exists($path)) {
                if (is_dir($path))
                    throw new RuntimeException("directory $path already exists");
                else
                    throw new RuntimeException("file $path already exists");
            }
     
            return mkdir($path);
        }
    }
    Enfin, ce serait quand même plus pratique si ta méthode pouvait créer une arborescence complète. Je te laisse essayer d'imaginer comment

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 56
    Points
    56
    Par défaut
    Merci Benjamin pour cette réponse très complète.

    Effectivement, je me suis lâché sur le typage :-)
    J'en ai bien conscience, utilisant d'autres langages, à fort typage eux (ex c#).

    Néanmoins, je ne renvoie qu'un état, et je le fais pour une bonne raison, une autre fonction se servant également de creerDossier() qui elle, n'attend qu'un booléen. Le code est relativement bien commenté, celui qui passera derrière n'aura aucun mal à le comprendre. Et puis, comme je me sers d'un état de retour, je pourrais très bien aussi renvoyer "vrai" ou "faux" (en string, pas en bool)... Comme ça, je reçois toujours une string, et effectivement, ce serait plus propre... Mais là n'était pas réellement la question

    En fait non, en te citant :

    la valeur spéciale "FOLDER_ALREADY_EXISTS" est correctement renvoyée, ce qui correspond au comportement attendu non ?

    Non ce n'est pas du tout le comportement attendu. En aucun cas elle doit renvoyer la valeur FOLDER_ALREADY_EXISTS au premier passage puisque le dossier n'existe pas encore... D'ailleurs, elle n'est pas censée me renvoyer FOLDER_ALREADY_EXISTS à aucun moment, c'est juste une vérification supplémentaire.

    Qui plus est, le réel problème est (ma question ^^) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if ($check_folder == 'FOLDER_ALREADY_EXISTS') echo 'CHECK FOLDER = FOLDER_ALREADY_EXISTS<br />'; 
     
    if (is_string($check_folder)) echo 'CHECK FOLDER est une string';
    m'affichera, au premier passage, seulement :
    CHECK FOLDER = FOLDER_ALREADY_EXISTS
    (il manque : CHECK FOLDER est une string)

    en revanche, si j'actualise la page, j'ai bien l'affichage :
    CHECK FOLDER = FOLDER_ALREADY_EXISTS
    CHECK FOLDER est une string
    (normale, après actualisation, (redirection désactivée en debug), le dossier existe bien)

    Je suis d'accord sur le second comportement, mais pas sur le premier :
    Je renvoie un booléen, je reçois bien 1, la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if ($check_folder == 'FOLDER_ALREADY_EXISTS')
    ne devrait pas être vrai, et ne devrait pas m'afficher
    CHECK FOLDER = FOLDER_ALREADY_EXISTS

    Et puis, si elle insiste pour me l'afficher (pourquoi pas...) alors, j'insiste pour qu'elle m'affiche aussi CHECK FOLDER est une string

    Non ?

    PS : merci pour ta version "plus compact" dont je ne connaissais pas l'emploi ^^

  4. #4
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Ce sont tes tests qui ne sont pas bons, tu es victime du cast en booléen à cause d'opérateur ==.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var_dump( true == "foobar" ); // true (car "foobar" est casté automatiquement en true)
    Pour vérifier à la fois l'égalité et le type, il faut utiliser l'opérateur de comparaison stricte ===
    Le typage faible c'est pratique mais il faut faire attention

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 56
    Points
    56
    Par défaut
    C'est fou ça...

    Je m'en étais bien rendu compte, avant de m'inscrire sur developpez et de poser ma question

    J'avais bien entendu fait le test avec l'opérateur strict, avant même de tester avec is_string().... C'est même la première chose que j'ai fait en fait ^^
    J'avais même failli le préciser dans mon premier commentaire.

    Tu postes la même réponse, je (re)test pour être certain de pas dire de bêtise, et là étrangement, ça passe...

    J'ai du me mélanger à un moment ou un autre, lapin compris

    Autant pour moi désolé.... J'étais sur le point de downgrader php lol

    Merci bien ;-)

    Merci d'autant plus que je ne savais pas qu'il était casté automatiquement

  6. #6
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Voici un excellent article qui fait le tour de l'épineuse question du cast booléen en PHP: http://11heavens.com/true-or-false-in-php

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 56
    Points
    56
    Par défaut
    rofl, là j'ai envie de dire pas cool par contre !

    La grosse claque début 2013...

    Un bts, 5 ans d’expérience dont 2 à SAP, pour en arriver à ça...

    J'ai mal... Je ne donnerais pas le résultat du challenge lol

    Merci

    Bon sinon je sais où et à quel moment je me suis planté, c'est déjà ça... ^^

  8. #8
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,
    Citation Envoyé par no-war Voir le message
    J'ai mal... Je ne donnerais pas le résultat du challenge lol
    Rassure-toi, même après 8 ans de PHP j'ai encore fait une erreur sur $myArray[] = '0'

  9. #9
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Désolé pour l'affront, je ne connaissait pas ton niveau Dans le doute, je donne toujours quelques articles de référence comme celui-ci.

    Et puis tu sait, je prends régulièrement des vestes sur ce forum également, on fait tous des erreurs

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    Salut,

    Rassure-toi, même après 8 ans de PHP j'ai encore fait une erreur sur $myArray[] = '0'
    C'est bien gentil de ta part, mais mettre tout ça sur le compte des reliquats du réveillon me rassure plus finalement

    J'ai beaucoup aimé le "'1.5 cups' - '3 cups' / 2" ou encore le "'0 times' + 'zero'"

    En plus du tableau également ^^

    Magnifique, très sympa ce petit test ^^

  11. #11
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par Benjamin Delespierre Voir le message
    Désolé pour l'affront, je ne connaissait pas ton niveau Dans le doute, je donne toujours quelques articles de référence comme celui-ci.

    Et puis tu sait, je prends régulièrement des vestes sur ce forum également, on fait tous des erreurs
    Non mais parfait ce petit test, et les affronts permettent aussi de s'améliorer.
    Puis au vu du code très basique fourni, ma réponse aurait été sensiblement identique (manque les exceptions !!! le typage !!!!)

    Merci à vous, et bonne journée ^^

    --

    Mangez des asperges qu'ils disaient !

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

Discussions similaires

  1. [MySQL] bug php quand 2 sites sur meme hébergement
    Par spespam dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 22/06/2009, 15h18
  2. Réponses: 1
    Dernier message: 20/03/2008, 11h09
  3. [PHP-JS] bug php ? ou alors je comprends rien
    Par mikebranque dans le forum Langage
    Réponses: 1
    Dernier message: 25/09/2006, 13h32
  4. BUG PHP ? -> Il me faut un pro !
    Par shadeoner dans le forum Langage
    Réponses: 16
    Dernier message: 15/04/2006, 18h47
  5. [POO] BUG PHP ?? Utilisation référence
    Par aurapp dans le forum Langage
    Réponses: 6
    Dernier message: 04/04/2006, 14h25

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