0

I'm newbie here. I tried to solve this for a day and searching all the way but I still couldn't.

The error shown up

Notice: Undefined variable: db (in dbFunction)

Fatal error: Call to a member function query() on a non-object (in dbFunction)

and code is

dbConnect.php

class dbConnect{
    
    public $db;
    
    public function __construct(){
        $db = new mysqli("localhost", "root", "", "onlineshopping");
        $db->set_charset("charset");
        if (mysqli_connect_errno()) {
            printf("Connect failed: %s\n", mysqli_connect_error());
            exit();
        }
    }   
}

dbFunction

class dbFunction extends dbConnect {  
    
    function __construct() {  
               
    }  
    
    public $db;
    
    public function UserRegister($fname, $lname, $tel, $email, $pass){
        $pass = md5($pass);  
        $db->query("INSERT INTO member(fname, lname, tel, email, password) values('".$fname."','".$lname."','".$tel."','".$email."','".$pass."')") or die(mysqli_error());  
        return $db;     
    }  
}
Community
  • 1
  • 1
Keo
  • 39
  • 1
  • 8
  • 2
    In php working with object properties doing through `$this` variable. In your case `$this->db` – maximkou Jun 02 '16 at 16:10
  • 3
    For one, you should use prepared statements, and for another, `md5` isn't the most secure way of storing passwords, you should look into using more modern functions, for example the native PHP function `password_hash()` and `password_verify()`. As for your issue, you have to specify that it's a variable within the object, not a local one, so you will need to do `$this->db->query("...");` and `return $this->db;` Same goes with your constructor. – Qirel Jun 02 '16 at 16:21
  • `function __construct() { } ` that's just horrible: If your constructor doesn't do anything, then don't specify one. You won't be calling the parent constructor if you override it, so `$this->db` won't be initialized. It's also considered bad practice to create dependencies in the constructor, instead, you should _inject_ them, and assign them to a non-public property: `public function __construct(mysqli $db) { $this->db = $db; }` and declare `protected $db;` – Elias Van Ootegem Jun 02 '16 at 16:26
  • Lastly, the names `dbConnect` and `dbFunction` don't make sense: they're classes, not a functions... and try to adhere to [the coding standards](http://php-fig.org) as much as possible (class names begin with an UpperCase, methods: lowerCase, class definition and method brackets go on a separate line, etc... – Elias Van Ootegem Jun 02 '16 at 16:27

4 Answers4

0

Your dbFunction class redefines __construct() to do nothing, so the $db property remains undefined. If you don't want to change the constructor in dbFunction, just omit it and the parent constructor will be used. If, on the other hand, you want to add to the functionality of the constructor then make sure to call the parent constructor:

function __construct() {  
    parent::__construct();

    // additional dbFunction construction here
} 
wogsland
  • 9,106
  • 19
  • 57
  • 93
  • If you have no process in your constructor, you can also remove it from the children class, then the parent one will be used. – olibiaz Jun 02 '16 at 16:09
0

First of all, your $db is a local variable in the __construct() method and not a class property and second, as pointed by @wogsland it gets overwritten by the child.
You might want to review a bit the OO basics

dbConnect.php

class dbConnect{

    public $db;

    public function __construct(){
        $this->db = new mysqli("localhost", "root", "", "onlineshopping");
        $this->db->set_charset("charset");
        if (mysqli_connect_errno()) {
            printf("Connect failed: %s\n", mysqli_connect_error());
            exit();
        }
    }   
}

dbFunction

class dbFunction extends dbConnect {  

    public function UserRegister($fname, $lname, $tel, $email, $pass){
        $pass = md5($pass);  
        $this->db->query("INSERT INTO member(fname, lname, tel, email, password) values('".$fname."','".$lname."','".$tel."','".$email."','".$pass."')") or die(mysqli_error());       
    }  
}

Notice the replacement of $db with $this->db in both methods.

edit:

My post was an exact answer to your question but, as others have pointed in comments, there are quite a few things you need to improve and my hope was that this code is for your own personal play not something for 'production'.

So, directly related to the code example, two obvious things you might want to expand:

Community
  • 1
  • 1
the-noob
  • 1,322
  • 2
  • 14
  • 19
  • 2
    and no mention of the use of MD5 and prepared statements? you're leaving that guy and future readers open to some serious stuff here. – Funk Forty Niner Jun 02 '16 at 16:28
  • My expectation is that this code is for learning purposes only and not production, there are plenty of bad things about it :) – the-noob Jun 02 '16 at 16:41
  • And prepared statements or the use of MD5 isn't suitable for learning purposes? There is plenty of space left in your answer to include recommendations .. – dbf Jun 02 '16 at 20:50
0

First of all, there's no need to make dbFunction a child class of dbConnect. They aren't related at all. In fact, I couldnt find any need to make dbConnect a class at all. All you need is the module __construct(). I would propose that you read up on OOP concepts :)

Still, answering your question - your __construct() function in dbConnect should return the db variable! You can assign this return value to your db variable in dbFunction.

Add the following line to your dbConnect's __construct() outside the if clause:

return $db;

And then instantiate an object of your class dbConnect in your dbFunction and assign db to that return value. (I'm assuming that dbFunction is not a child of dbConnect now...)

dbConn = new dbConnect()
db = dbConn.__construct()
Tejash Desai
  • 466
  • 4
  • 11
0

First learn some basics of OO programming it seems like you should first read about objects and instances before using them in any fashion. Try this http://litove.com/object-oriented-programming-2/ you will find all your answers.

Sourabh Modi
  • 101
  • 1