Stan Catalin
Stan Catalin

Reputation: 51

Calling a child object in a parent function

I would like to know If I can call a child's object in a parent function. Like this:

   class Parent {

          public function A() {
             << I want to call the object here >>
             // Some code 
          }
   }

   Class Child extends Parent {

          public function B() {
            // Some code
          }
   }

   $Child = new Child();
   $Child -> B();

The two classes are in different files. My Child class is making a connection with my database with function B(). In my Parent's class, A(), I am trying to insert data I receive from filling a form, but I need a connection to the database and I do not know how I can call that object. Note: My code is working when I have both functions in the same Class.

I did not find the solution, so I will try and post my real code:

 class db_connect extends Model
 {
    private $dbname = "...";
    private $dbuser = "...";
    private $dbpass = "...";
    private $dbhost = "...";
    public $dbc;

    public function Connect()
    {
        $this->dbc = mysqli_connect($this->dbhost, $this->dbuser, $this->dbpass, $this->dbname);

    if($this->dbc === false){
        die("ERROR: Could not connect. " . mysqli_connect_error());    
    }}
}

So this was the Class Child from Above and Connect() was B().

Now the parent

class Model 
{
      public $query;
      public $result;

      public function proccess_data($marca,$model,$pret,$descriere){
         << I am trying to make a connection here from config.php using the function Connect() >>
         $this->query = "INSERT INTO autoturisme (autoturism_id, marca, model, pret, descriere) " .
     "VALUES (NULL, '$marca', '$model', '$pret', '$descriere')";
         $this->result = mysqli_query(<<Also here I would need the connection>>, $this->query) 
    or die(mysqli_error(<<And here>>));
         if($this->result == 1){
         echo "<br/>Your data were processed";
    } else {
         echo "<br/>We are sorry but an error occurred";
    }
        $this->close_db();

}

In the mysqli_query I need a parameter as a mysqli, which is the connection to my database. The parameter is in the Child's Class, $dbc, and it is called in the function Connect() with: $this->dbc . Same goes for mysqli_error. Hope this makes things clearer :).

Upvotes: 4

Views: 400

Answers (3)

PeeHaa
PeeHaa

Reputation: 72672

Considering you have tagged this I will bite.

There is no reason for something called db_connect to ever extend something called Model. Not to mention there is no reason to call something Model which doesn't tell anybody anything and as such is a pretty crappy name for anything.

Secondly as far as I can see there is no reason for you to wrap mysqli to begin with. What do you gain by wrapping an object like that. mysqli comes with an object-oriented interface out of the box.

Finally when you get rid of that odd inheritance tree you have going on you should inject the database connection into the classes that need it. Something like:

class Car
{
    // why do you need a `$query` member when you are not going to use it?
    // same for `$result`

    private $dbConnection;

    public function __construct(mysqli $dbConnection)
    {
        $this->dbConnection = $dbConnection;
    }

    public function add($marca, $model, $pret, $descriere)
    {
        $query = 'INSERT INTO autoturisme';
        $query.= ' (marca, model, pret, descriere)';
        $query.= ' VALUES';
        $query.= ' (?, ?, ?, ?)';

        $stmt = $this->dbConnection->prepare($query);

        $stmt->bind_param('ssss', $marca, $model, $pret, $descriere);

        if (!$stmt->execute()) {
            throw new \Exception('We are sorry but an error occurred');
        }
    }
}

$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$car = new Car($mysqli);

try {
    $car->add('BMW', '325', 'dunnowhatthismeans', 'description?');
} catch(\Exception $e) {
    echo $e->getMessage();
}

Also note that your code is most likely vulnerable to SQL injection.

Upvotes: 3

Katie
Katie

Reputation: 2693

You could try switching it around, so the parent class makes the connection to the database, and provides methods to the child class to access that connection. Here is pseudo-code that roughly shows how that would work.

class Parent {

   // method to run SQL statement
   runSQL(SQL) {
      // connect to database (or do it in constructor) and run the SQL
   }
}

class Child extend Parent {
          public function B() {
              ...
              parent::runSQL("SELECT...")
          }
}

Upvotes: 2

Pritam Banerjee
Pritam Banerjee

Reputation: 18923

You should not ideally call a child's function from an instance of the parent class. This is something that should not be done.

Instead you can override the function in the child class and then call the method from the instance of the child class.

Upvotes: 2

Related Questions