PHP将PDO对象传递到其他Main类的好方法



我是PHP OOP的新手,现在我想知道是否有更好的方法来使用数据库类,然后全面扩展它。

例如,我有三个主要类:EmployeeCustomerArticle。这些类中的每一个都有一个扩展形式的子类。到目前为止,我所做的是在这3个主要类中的每个类上进行extand和Db类。

我的DB类:

class DbController{
private $serverName;
private $userName;
private $userPass;
private $dbName;
private $charSet;
private $pdo;
protected function __construct() {
try {
$this->serverName   = "localhost";
$this->userName     = "blabla";
$this->userPass     = "***";
$this->dbName       = "blabla";
$this->charSet      = "utf8mb4";
$dsn = "mysql:host=".$this->serverName."; dbname=".$this->dbName."; charset=".$this->charSet;
$pdo = new PDO($dsn, $this->userName, $this->userPass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo = $pdo;
return $pdo;
} catch (PDOException $err) {
die($err->getMessage());
}
}

protected function getPdo(){
return $this->pdo;
}


public function __debugInfo(){
$properties = get_object_vars($this);
unset($properties['serverName']);
unset($properties['userName']);
unset($properties['userPass']);
unset($properties['pdo']);
unset($properties['dbName']);
unset($properties['charSet']);
return $properties;
}
}

主要类别之一(Employee(:

<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
include_once "DbController.cls.php";
class Employee{
public $id;
protected $name;
protected $username;
protected $scoore;
protected $dbTable = "employee";
protected PDO $pdo;
public function __construct($info = NULL) {
// pls notice that The DbController() is a protected Constructor.
$this->pdo = new DbController();
if (isset($info)) {
$this->id = $info["id"];
$this->name = $info["name"];
$this->username = $info["username"];
$this->scoore = $info["scoore"]; 
}

}
// Setters and Getters ......

则存在CCD_ 5的一个子类,称为CCD_。这个子类包含登录或注册等功能。这个子类还处理来自客户端的POST请求。

include_once "../classes/Employee.cls.php";
$_POST = json_decode(file_get_contents('php://input'), true);
class EmployeeManagement extends Employee{
public function __construct() {
if (isset($_SESSION['empID'])) {
parent::__construct();
parent::__construct($this->fetchEmpInfo($_SESSION['empID']));
} else {
parent::__construct();
}
}
public function signIn($username, $password){
$retrunArray = array('code' => 0, 'msg' =>  "No Data Returned");
$checkCredential = $this->checkCredential($username, $password);
if ($checkCredential['code'] == 1) {
try {
$getEmpID = $this->pdo->prepare("SELECT `id` FROM `employee` WHERE `username`=? AND `password`=? LIMIT 1;");
$getEmpID->execute([$username, $password]);
$empId = $getEmpID->fetch(PDO::FETCH_ASSOC)['id'];
$_SESSION['empID'] = $empId;
$retrunArray['code'] = 1;
$retrunArray['msg'] = "Erfolgreich eingeloggt";
return $retrunArray;

} catch (PDOException $err) {
$retrunArray['code'] = 0;
$retrunArray['msg'] = $err->getMessage();
return $retrunArray;
}
} else{
// In case of DB Error
return $checkCredential;
}
}
// Request Handler Begin
$employeeService = new EmployeeManagement();
header('Content-Type: application/json');
// Login:
if (isset($_POST["signIn"])) {
$signIn = $employeeService->signIn($_POST["username"],     $_POST["password"]);
echo json_encode($signIn);
}

现在我尝试在Employee构造函数中声明db类。但是我一直得到错误CCD_ 8。有干净的方法吗?

通常,您会在此类之外创建数据库对象,然后将其作为参数注入。这被称为依赖注入,是一件好事™.

然后在类特定的方法中使用该参数。所以你的员工类看起来像这样:

class Employee
{
protected $db;
public function __construct(PDO $db)
{
$this->db = $db;
}
public function find($id)
{
// or whatever your query looks like
$stmt = $this->db->query('SELECT * FROM EMPLOYEE WHERE id = :id');
// $row = ...
return $row;
}
public function getAll()
{
$stmt = $this->db->query('SELECT * FROM EMPLOYEE');
// whatever
}
}

然后要使用该类,您需要实例化一个数据库对象,然后将其传递给Employee:

$db = new PDO();
$employee = new Employee($db);
$steve = $employee->find(1);

你应该而不是这样做:

class Employee
{
public $db;
public function __construct(PDO $db)
{
$this->db = $db;
}
}
$db = new PDO();
$employee = new Employee($db);
$steve = $employee->db->query('...');

或者这个:

class Employee extends PDO
{
// ...
}
$employee = new Employee($db);
$employee->query('...');

继承不是解决问题的方法。如果继承DbController,则每个类都将实例化一个新的PDO连接。

相反,首先实例化DbController,然后调用其getPDO()方法来获得一个PDO连接对象,将其作为参数传递给其他类的构造函数。您需要将DbController方法声明更改为public,而不是private

像这样:

class DbController{
private $serverName;
private $userName;
private $userPass;
private $dbName;
private $charSet;
private $pdo;
public function __construct() {
try {
$this->serverName   = "localhost";
$this->userName     = "blabla";
$this->userPass     = "***";
$this->dbName       = "blabla";
$this->charSet      = "utf8mb4";
$dsn = "mysql:host=".$this->serverName."; dbname=".$this->dbName."; charset=".$this->charSet;
$pdo = new PDO($dsn, $this->userName, $this->userPass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo = $pdo;
// return $pdo;  No need for this. The constructor doesn't use it.
} catch (PDOException $err) {
die($err->getMessage());
}
}

public function getPdo(){
return $this->pdo;
}
}
class Employee {
private $PDO;
public function __construct(PDO $pdo) {
$this->PDO = $pdo
}
public function getEmployee($id) {
// get employee details using $this->PDO as your connection object
}
}

然后你的主程序变成类似的程序

require_once('DbController.php');
require_once('Employee.php');
$DB = new DbController();
$emp = new Employee($DB->getPDO());
$id = 'some employee reference';
$employeeDetails = $emp->getEmployee($id);

最新更新