如何使用来自父 class 的方法,其中 returns 数据库值在 PHP 中?

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

当我 运行 我的代码时,我收到错误消息 致命错误:未捕获错误:在 C:[=37= 中的 null 上调用成员函数 运行() ]................ 关于我的问题,我有三个 class

  1. 初始化
  2. 实用程序
  3. 退出 init class 持有数据库连接
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;
    }
}

公用事业横截面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;
    }
}

取款横截面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"];
}

对象

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

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

PS:如果我没有从数据库中获取任何内容,代码 (getUser()) 工作正常

我想通了: parent:: 施展了魔法。

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;
}   

我不知道这是否是最好的方法,但它确实有效。

你的第一个问题是,因为 $db 属性 在 Utilities class 中被声明为“private”,它不能直接被 Withdraw class.您可以在子class中单独声明一个同名的private属性,两者将无关。

如果您希望 same 属性 在两个 classes 中可见,您可以在 Utilities 中将其声明为“protected”,然后不要需要在Withdraw中重新声明。

你的第二个问题(正如你发现的那样)是如果你在子 class 中编写构造函数,PHP 不会自动调用父构造函数。如果父 class 的构造函数完成了您需要的一切,您就可以简单地不在子 class 上定义一个。如果您 需要子 class 上的一个,请务必使用适当的参数调用 parent::__construct(),通常在子构造函数的最开始或最后。

最后,值得考虑的是继承是否适合这项特定工作。继承意味着两个 class 之间的“is-a”关系,在本例中是“撤消 is-a 实用程序”,这没有多大意义。如果您只是想让一个 class 的功能在另一个中可用,将一个 class 的实例传递给另一个通常更灵活且更容易理解,只需调用 public方法(称为“依赖注入”)。例如:

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"];
}