Page 1 sur 1

Variable indirecte non initialisée

Posté : 28 oct. 2011, 18:28
par Wounel
Bonjour,

nouvel inscrit, et déjà un pépin :)

J'effectue quelques modifications dans le code d'osTicket (http://osticket.com/). Et je tombe sur un morceau de code que je ne comprends pas du tout (mais qui fonctionne).
C'est la fonction qui effectue la connexion à la base de données. Un truc comme on en voit partout. Sauf que là, le développeur utilise une variable indirecte nommée $$dblink.
Or la variable $dblink (avec un seul $) n'est jamais initialisée. Ni dans cette fonction, ni dans ce fichier, ni ailleurs. Aucune autre occurrence de $dblink ou $$dblink.
Ce qui veut dire que $$dblink n'a pas vraiment de signification (dans mon esprit hein, puisqu'en vrai ça fonctionne).


Le code de la fonction:

Code : Tout sélectionner

function db_connect($dbhost,$dbuser, $dbpass,$dbname = "") { if(!strlen($dbuser) || !strlen($dbpass) || !strlen($dbhost)) return NULL; @$$dblink = mysql_connect($dbhost, $dbuser, $dbpass); if($$dblink && $dbname) @mysql_select_db($dbname); //set desired encoding just in case mysql charset is not UTF-8 - Thanks to FreshMedia if($$dblink) { @mysql_query('SET NAMES "UTF8"'); @mysql_query('SET COLLATION_CONNECTION=utf8_general_ci'); } return $$dblink; }

A chaque passage dans cette fonction, PHP affiche un avertissement comme quoi $$dblink n'est pas définie.

Code : Tout sélectionner

Notice: Undefined variable: dblink in xxxxx/include/mysql.php on line 27
J'ai ajouté un @ devant chaque $$dblink comme le développeur l'avait déjà fait pour la première occurence, mais bon ce n'est pas terrible.


Ma question est: comment est-il possible que ce code fonctionne (puisque l'application fonctionne) alors que $dblink n'est pas initialisée, et donc que $$dblink ne veux rien dire ?


note: j'ai vérifié qu'il n'existe pas d'autre endroit où mysql_connect est utilisée.

Re: Variable indirecte non initialisée

Posté : 28 oct. 2011, 19:10
par xTG
Bah c'est bien moche dans tous les cas. :)
Déclares là et ce sera bien mieux !

Quand au fonctionnement cela peut en effet fonctionner si le $$dblink n'est pas explicitement inclu à chaque mysql_query().
Car dans ce cas il récupère la première connexion qu'il trouve ouverte.

Re: Variable indirecte non initialisée

Posté : 28 oct. 2011, 19:53
par Wounel
Car dans ce cas il récupère la première connexion qu'il trouve ouverte.
C'est le seul endroit où une connexion peut être ouverte, donc il ne peut pas en trouver une déjà ouverte.

Clairement, une variable indirecte non initialisée fonctionne tout de même. Je ne pige pas comment PHP arrive à s'en sortir.

Re: Variable indirecte non initialisée

Posté : 28 oct. 2011, 19:58
par xTG
Tu m'as mal compris, regardes la documentation de la fonction mysql_query et tu verras que le paramètre de la connexion est optionnel. ;)
Il sait la trouver par lui même et ce que tu lui passes une variable ou non, voire même qu'il existe une variable ou non.

Bref que tu génères un warning sur l'existence de la variable n'empêche pas la fonction mysql_connect() d'établir la connexion.

Re: Variable indirecte non initialisée

Posté : 28 oct. 2011, 21:20
par Wounel
Tu m'as mal compris, regardes la documentation de la fonction mysql_query et tu verras que le paramètre de la connexion est optionnel. ;)
Il sait la trouver par lui même et ce que tu lui passes une variable ou non, voire même qu'il existe une variable ou non.

Bref que tu génères un warning sur l'existence de la variable n'empêche pas la fonction mysql_connect() d'établir la connexion.
Ca y est, j'ai pigé :oops:

Je viens de tester en supprimant tout ce qui concerne cette variable moisie:

Code : Tout sélectionner

function db_connect($dbhost,$dbuser, $dbpass,$dbname = "") { if(!strlen($dbuser) || !strlen($dbpass) || !strlen($dbhost)) return NULL; mysql_connect($dbhost, $dbuser, $dbpass); if($dbname) mysql_select_db($dbname); mysql_query('SET NAMES "UTF8"'); mysql_query('SET COLLATION_CONNECTION=utf8_general_ci'); return true; }
Ca fonctionne exactement pareil. Avec les avertissements en moins.

Conclusion: le développeur est encore plus mauvais que moi (je débute).

J'en reviens pas qu'il puisse programmer une application avec de grosses conneries comme ça. En plus il vend du service autour de son truc :shock:

Re: Variable indirecte non initialisée

Posté : 28 oct. 2011, 22:35
par xTG
Il y a des applications vendues 50 000 € et qui sont des plats de spaghettis. ;)
Tant que cela tourne le client en demande pas plus, tous les domaines de l'informatique ne nécessite pas un code qui soit codé proprement et qui fonctionne à l'optimisation près.

Re: Variable indirecte non initialisée

Posté : 29 oct. 2011, 12:21
par moogli
Attention le but, a priori, c'est de retourner le "lien de connexion" or ce n'est plus cas avec ta fonction.

donc simplement virer les $ en double, rend la fonction opértionnel.
<?php
 function db_connect($dbhost,$dbuser, $dbpass,$dbname = "") {
        
        if(!strlen($dbuser) || !strlen($dbpass) || !strlen($dbhost))
             return NULL;

        $dblink = mysql_connect($dbhost, $dbuser, $dbpass);
        if($dblink && $dbname)
            mysql_select_db($dbname);
        //set desired encoding just in case mysql charset is not UTF-8 - Thanks to FreshMedia
        if($dblink) {
            mysql_query('SET NAMES "UTF8"');
            mysql_query('SET COLLATION_CONNECTION=utf8_general_ci');
        }
        return $dblink;
    }
?>
bon par contre pour moi c'est codé avec les pieds et use trop des abus de l'auto cast est n'est pas clair, genre if ($variable) ça veux rien c'est pas sémantiquement correct sachant que cette variable n'es pas prévu pour être booléen. donc un is_ressource, voir un if ($variable !== false) est 100 fois mieux, je ne parle pas des @ a tous va qui ne devraient pas y être (voir une bonne gestion des erreurs :) )

bon courage pour tes modif :mrgreen: