xtopolis Posted September 26, 2008 Share Posted September 26, 2008 [i am new to OOP] I have a Singleton? database object that's instantiated at the top of the page, and passed to User($db) on instantiation... and it gives me that error that I can't call the query() method because it's not an object? Maybe im passing it wrong.. (a form passes post vars to login.php), assume the classes are called, and the defines are there Login.php <?php require_once 'mysql.php'; $db = &new MYSQL('xxxx','xxxx','xxxx','xxxx'); // I tested that the $db object is correct by doing a $db->query(Select...); successfully $client = new Client('alpha',SECRET,DOCROOT); ?> User.php -- only have relevant methods <?php class User { protected $session;//session instance protected $db; function __construct(&$db) { $this->db = &$db; $this->session = &new Session(); } //checks if a session is already logged in, or a new //one is being processed protected function login() { //login hash already set? if($this->session->get('login_hash')){ $this->confirmAuth(); } //post set? if(empty($_POST['un']) || empty($_POST['pw'])){ $this->session->set('login_error','You must enter a username and password.'); $this->redirect(); die('You are being redirected.'); } $this->processLogin(); }//login //set un/pw vars, check if username exists private function processLogin() { $un = preg_replace('/[^0-9A-Z_]/i','',$_POST['un']);//only allows A-Z,0-9,_ to be input, strips out anything else //$pw = hash('whirlpool',$_POST['pw']); $pw = $_POST['pw']; $sql = "SELECT * FROM ".$this->table." WHERE ".UN."='$un'"; try { if(!$result = $db->query($sql)){ // ## HERE IS THE FIRST FAILED CALL ############# throw new DBException('Error while trying to login. Please try again'); } //check only 1 hit if(mysql_num_rows($result) != 1){ $this->session->set('login_error','Invalid username or password.');//USERNAME DOES NOT EXIST $this->redirect(); die('You are being redirected.'); } $row = mysql_fetch_array($result); $this->checkEnabled($row); }catch (DBException $e){//Database problem $this->session->set('login_error',$e->getMessage()); $this->redirect(); die('You are being redirected.'); } }//processLogin }//class ?> Client.php <?php class Client extends User { protected $table; protected $secret; public $redirect; function __construct($table,$secret,$redirect) { parent::__construct($db); $this->table = $table; $this->secret = $secret; $this->redirect = $redirect; //handle fails if($this->session->get('fails')){ $this->fails = $this->session->get('fails'); }else{ $this->fails = 0; $this->session->set('fails',0); } parent::login(); }//__construct } ?> Quote Link to comment Share on other sites More sharing options...
corbin Posted September 26, 2008 Share Posted September 26, 2008 $client = new Client('alpha',SECRET,DOCROOT); function __construct($table,$secret,$redirect) { parent::__construct($db); $db doesn't exist in __construct's scope. Quote Link to comment Share on other sites More sharing options...
xtopolis Posted September 26, 2008 Author Share Posted September 26, 2008 I kind of grasp what you mean, but I'm confused... since I declared $db and instantiated it outside all of the classes, shouldn't it be available almost globally? And which scope is it not in? Client's(and therefore neither User's), or just not in User's scope? I tried adding: $client = new Client($db,'alpha',SECRET,DOCROOT); function __construct($db,$table,$secret,$redirect) { $this->db = &$db; parent::__construct($this->db); but got the same error. ~~ oh, can User not see the $db because it technically never gets down to there...? Quote Link to comment Share on other sites More sharing options...
DarkWater Posted September 26, 2008 Share Posted September 26, 2008 The real problem, I think, is with the constructor for MYSQL. Can you show us that class? Quote Link to comment Share on other sites More sharing options...
xtopolis Posted September 26, 2008 Author Share Posted September 26, 2008 mysql.php, this I copied from one of my Sitepoint books, and added one method <?php //MYSQL class MYSQL { var $host; var $user; var $pass; var $dbname; var $dbConn; //constructor function MYSQL($host,$user,$pass,$dbname) { //assign vars to local vars $this->host = $host; $this->user = $user; $this->pass = $pass; $this->dbname = $dbname; //connect to DB $this->Connect(); } //Connect to DB function Connect() { //connect if(!$this->dbConn = @mysql_connect($this->host, $this->user, $this->pass)) { trigger_error("Could not connect to database."); } //select db if (!@mysql_select_db($this->dbname)) { trigger_error("Could not select database."); } } function &query($sql) { if (!$queryResource = mysql_query($sql, $this->dbConn)) { trigger_error("Query Failed.");// . mysql_error($this->dbConn)); } return $queryResource; } function checkExistsOne($sql) { if (!$queryResource = mysql_query($sql, $this->dbConn)) { trigger_error("Query Failed.");// . mysql_error($this->dbConn)); } $howmany = mysql_num_rows($queryResource); return $howmany; } }//mysql class ?> Quote Link to comment Share on other sites More sharing options...
corbin Posted September 26, 2008 Share Posted September 26, 2008 <?php A function blah() { B } class Bleh { function f1() { C } function f2() { D } } Variables from A, B, C and D cannot be accessed from other scopes without being passed or pulled in (for lack of a better term -- pretty much a globalization). So, if a variable lives in A, if you don't pass it to or declare it global (well not declare it, but more of use the global syntax) in B, it does not exist in B. Similarly, the variable $db does not exist in Client::__construct() unless it is passed or made global to Client::__construct. Think of it this way: function f1($blah) { echo $blah; } function f2($bleh) { f1($blah); f3($bleh); //example } Would you expect $blah to be set? Of course not. Quote Link to comment Share on other sites More sharing options...
xtopolis Posted September 26, 2008 Author Share Posted September 26, 2008 Thank you corbin. I 'fixed' it by adding $db to Client($db,'alpha'....) on instantiation, and then passing $this->db from Client to User::_construct($this->db).. And then made User's $db it's on ($this->db), and the same in the code calling ($this->db->query())... and now it works. I don't really understand why it needs to be $this->db... but I'm happy that it works. Thanks again... What I changed, for reference: class Client { function __construct($db,$table,$secret,$redirect) { $this->db = &$db; parent::__construct($this->db) } } //----------------------- class User { function __construct($db) { $this->db = $db; } ... function login() { ... $result = $this->db->query($sql); } $client = new Client($db,'alpha'.....) Quote Link to comment Share on other sites More sharing options...
corbin Posted September 26, 2008 Share Posted September 26, 2008 class Client { function __construct($db,$table,$secret,$redirect) { $this->db = &$db; parent::__construct($this->db) } } Did you mean right there? It doesn't need to be stored in this->db first. parent::__construct($db) would work fine. Quote Link to comment Share on other sites More sharing options...
xtopolis Posted September 26, 2008 Author Share Posted September 26, 2008 Yea, I had that, changed it to just be class Client { function __construct($db,$table,$secret,$redirect) { parent::__construct($db) } } Thanks Quote Link to comment Share on other sites More sharing options...
corbin Posted September 26, 2008 Share Posted September 26, 2008 No problem. ;p Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.