Home > Net >  How to use a method from a parent class which returns database values in PHP?
How to use a method from a parent class which returns database values in PHP?

Time:05-29

when i run my code i get error message Fatal error: Uncaught Error: Call to a member function run() on null in C:\xampp\htdocs............. i have three class in regards to my problem

  1. Init
  2. Utilities
  3. Withdraw init class holds the database connection
class Init{
    private $pdo;
    function __construct(){
        $servername = "localhost";
        $username = "root";
        $dbName = "**************";
        $password = "";
        try {
            $dsn = "mysql:host=".$servername.";dbname=".$dbName;
            $this->pdo = new PDO($dsn, $username, $password);
            $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            $this->pdo;
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

    public function run($sql, $args = NULL)
    {
        $stmt=null;
        
            if (!$args)
        {
            return $this->pdo->query($sql);
        }
        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute($args);
        } catch (PDOException $e) {
            //SEND THIS TO AUDIT SERVICE FOR LOGGING
            echo $e->getMessage();
        }
        
        return $stmt;
    }
}

cross section of utilities class

require 'init.php';
class Utilities {
    private $db;
    private $msg = [];

    function __construct ($db) {
        $this->db = $db;
    }

    public function getUser ($user) {
        $sql = "SELECT * FROM user_tb WHERE username = ?";
        $stmt = $this->db->run($sql, [$user]);
        $result = $stmt->fetch();
        return $result;
    }
}

cross section of withdraw class

include_once "utilities.php";

class Withdraw extends Utilities {
    private $db;

    function __construct($db) {
        $this->db = $db;
    }   

    public function withdrawer ($username, $addr, $coin, $amount) {
        $sql = "SELECT * FROM wallet_tb WHERE  username = ?";
        $stmt = $this->db->run($sql, [$username]);
        $result = $stmt->fetch();
        $balance = $result["balance"];
        $transact_id = $result["transact_id"];
        $get = $this->getUser($username); //getUser() is from utilities class;
        return $get["email"];
}

object

    $db = new Init();
    $obj = new Withdraw($db);

    $msg = $obj->withdrawer($user, $addr, $coin, $amount);
    
    echo ($msg);

PS: the code (getUser() ) works fine if i am not fetching anything from the database

CodePudding user response:

i figured it out: parent:: did the magic.

function __construct($db) {
   $this->db = $db; // methods in the current class uses the property;
   parent::__construct($db); // this runs the contruct of the other class;
}   

i don't know if this is the best approach but it sure does work.

CodePudding user response:

Your first probkem is that because the $db property is declared "private" in the Utilities class, it can't be directly read or written to by the Withdraw class. You can declare a separate private property with the same name in the child class and the two will be unrelated.

If you want the same property visible in both classes, you can declare it "protected" in Utilities, and then don't need to declare it again in Withdraw.

Your second problem (as you discovered) is that PHP doesn't automatically call the parent constructor if you write a constructor in the child class. If the parent class's constructor does everything you need, you can simply not define one on the child class. If you do need one on the child class, be sure to call parent::__construct() with appropriate arguments, usually at the very beginning or very end of the child constructor.

Finally, it's worth considering whether inheritance is the right tool for this particular job. Inheritance implies an "is-a" relationship between the two classes, in this case "Withdraw is-a Utilities", which doesn't make much sense. If you just want to make functionality from one class available in another, it's usually more flexible and easier to understand to have an instance of one class passed to another, and simply call the public methods (known as "dependency injection"). For example:

class Withdraw {
    private Utilities $utilities;
    private DatabaseConnection $db;

    function __construct(Utilities $utilities, DatabaseConnection $db) {
        $this->utilities = $utilities;
        $this->db = $db;
    }   

    public function withdrawer ($username, $addr, $coin, $amount) {
        $sql = "SELECT * FROM wallet_tb WHERE  username = ?";
        $stmt = $this->db->run($sql, [$username]);
        $result = $stmt->fetch();
        $balance = $result["balance"];
        $transact_id = $result["transact_id"];
        $get = $this->utilities->getUser($username); //getUser() is from utilities class;
        return $get["email"];
}
  • Related