Page 1 of 1

Using classes to manage database access: Undefined variable

Posted: Tue Sep 26, 2006 5:42 pm
by Tatiana
Weirdan | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


I found a class to manage the access to my database.  I *love* that class, the only problem is that apparently I have no clue how to use a class involving a database properly.  I can call any function in it once, it works like a charm.  But as soon as I have to access the database a second time, then it doesn't work anymore and I get "Notice: Undefined variable" errors and I just don't get why.  I'm pretty sure it's just one detail somewhere that I didn't get.

The class requires a 'connexion.php' file, which goes like this (password removed, obviously):

Code: Select all

<?php
$mysql_adresse = "localhost";
$mysql_login = "admin";
$mysql_pass = "mypassword";
$mysql_base = "pat";
?>
Then the class that manages the database, 'ClasseMysqp.php', goes like this (I won't post it all, just what I think are the revelant parts, but if somebody wants to see the full thing, it's at the bottom of this page - in French, but just to get the code it shouldn't be a problem):

Code: Select all

class ClasseMysql {
    var $adr;               // url de la base
    var $login;             // utilisateur de la base
    var $passe;             // mot de passe
    var $base;              // nom de la base
    var $debug=false;       // si true, affiche les chaines SQL
    var $debug_mode=0;      // paramètres concernant l'affichage des chaînes SQL
    var $sqls=null;         // chaînes SQL à afficher si $debug=SQL_DEMANDE
    
    function ClasseMysql() {
        require_once("connexion.php");
        $this->adr = $mysql_adresse;
        $this->login = $mysql_login;
        $this->passe = $mysql_pass;
        $this->base = $mysql_base;
    }
    
    function connexion() {
        if ($this->base) {
            $obj_db = mysql_connect($this->adr, $this->login, $this->passe); 
            if (!$obj_db) {
                echo '<div style="' . STYLE_MYSQL . '">Erreur de connexion à la base de données <b>' . $this->base . '</b></div>';
                return false;
            }
            if (!mysql_select_db($this->base, $obj_db)) {
                echo '<div style="' . STYLE_MYSQL . '">Erreur : ' . mysql_error( ) . '</div>';
                mysql_close($obj_db);
                return false;
            }
            return true;
        }
        else {
            echo '<div style="' . STYLE_MYSQL . '">Erreur : aucune information de connexion - base de données indisponible</div>';
            return false;
        }
    }
	
	function close() {
		// méthode publique
		mysql_close();
	}

    function select($chaine_sql, $methode, $args=null, $connexion=true) {
        if ($connexion) {
            if (!$this->connexion()) return null;
        }
        $requete = @mysql_query($chaine_sql);
        if ($requete) {
            $methode = PREFIXE_SELEC . $methode;
            if ($args) $resultat = $this->$methode($requete, $args);
            else $resultat = $this->$methode($requete);
            mysql_free_result($requete);
            $err = null;
        }
        else {
            $resultat = null;
            $err = mysql_errno() . " " . mysql_error();
        }
        if ($this->debug && ($err || !$this->estDebugMode(SQL_IFERR))) {
            $this->voirChaineSql($chaine_sql, $err);
        }
        return $resultat;
    }

    function select_cle_tableau($requete) {
        // private method, called by the above method
        $resultat = array();
        while($ligne = mysql_fetch_assoc($requete)) {
            $cle = array_shift($ligne);
            $resultat[$cle] = $ligne;
        }
        return $resultat;
    }
Then I wanted another intermediate class so, when I work on my forms and interacting with the user, I don't have to think of database queries. My own class goes like this:

Code: Select all

<?php
include 'ClasseMysql.php';

class ClasseGererBD {

	function listeConcours() {
		$mysql = new ClasseMysql;
		$mysql->activerDebug(true, SQL_NOW|SQL_COLORS);
		$query = "SELECT id, nom, id_systeme FROM pat_concours";
		return $mysql->select($query, "cle_tableau");
		//$mysql->close();
	}

	function afficherConcours() {
		// méthode publique
		// affiche la liste des concours en permettant la modification et l'ajout
		$tab_concours = $this->listeConcours();

		foreach ($tab_concours as $cle => $valeur) {
			echo $cle . ". ";
			echo $valeur["nom"];
			echo "  (";
			echo $valeur["id_systeme"];
			echo ")<br>";
		}		
	}
}
?>
I know that both of the above functions work, because I get the result I want when I call it. The problem is that I can't call two functions in a row! ??? The first time it works, and the second time I get errors. This is how I make the call (well, obviously I don't need to actually to that, but to simplify my explanations I'll pretend I want to do that):

Code: Select all

<body>
Test...<br><br>

<?
	include 'ClasseGererBD.php';
	
	$bd = new ClasseGererBD;
	echo $bd->afficherConcours();  // this works well!
	echo $bd->afficherConcours();  // THIS HERE WON'T WORK
	
?>
</body>
It shows:

Code: Select all

Test...

1. Contest 2006 (1)

Notice: Undefined variable: mysql_adresse in c:\...........\ClasseMysql.php on line 32

Notice: Undefined variable: mysql_login in c:\............\ClasseMysql.php on line 33

Notice: Undefined variable: mysql_pass in c:\..............\ClasseMysql.php on line 34

Notice: Undefined variable: mysql_base in c:\..........\ClasseMysql.php on line 35
Erreur : aucune information de connexion - base de données indisponible (Error: no connecion information - database unavailable (which is generated by "ClasseMysql.php")

Warning: Invalid argument supplied for foreach() in c:\........\ClasseGererBD.php on line 53
The last warning I understand, I mean basically it can't perform a foreach on an undefied variable, but why in the world are the informations about the database lost?!?

Can anybody help? I'd be so thankful, I've tried so many things that I seem to get more and more lost...


Weirdan | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]

Posted: Tue Sep 26, 2006 5:45 pm
by volka
Please read http://www.php.net/language.variables.scope (perhaps more than once)

Posted: Tue Sep 26, 2006 6:07 pm
by Weirdan
a quick fix:
//........snip......
function ClasseMysql() {
include("connexion.php");
$this->adr = $mysql_adresse;
$this->login = $mysql_login;
$this->passe = $mysql_pass;
$this->base = $mysql_base;
}
//........snip......

Posted: Tue Sep 26, 2006 11:20 pm
by Tatiana
Oh my......... Thanks so much Weirdan!!! As it's so often the case, I wasn't looking for the mistake in the right place. I kind of feel like donating something to this site! :lol:

Those features for posting code are great indeed, I'll make sure to use them the next time! I was becoming so frustrated when I posted that I did read the announcements but totally missed the stickies... :oops: :roll:

Thanks to volka as well, even though it wasn't the cause of my problem (actually, I did think the problem lied somewhere there, so that read won't hurt!).