Variable indirecte non initialisée

Petit nouveau ! | 3 Messages

28 oct. 2011, 18:28

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.

ViPHP
xTG
ViPHP | 7331 Messages

28 oct. 2011, 19:10

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.

Petit nouveau ! | 3 Messages

28 oct. 2011, 19:53

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.

ViPHP
xTG
ViPHP | 7331 Messages

28 oct. 2011, 19:58

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.

Petit nouveau ! | 3 Messages

28 oct. 2011, 21:20

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:

ViPHP
xTG
ViPHP | 7331 Messages

28 oct. 2011, 22:35

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.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 oct. 2011, 12:21

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:
Il en faut peu pour être heureux ......