首页 > 解决方案 > 如何连接两个类以从数据库中读取信息?

问题描述

我是 PHP PDO OOP 的新手。我正在尝试使用__constructor. 这是我的数据库类代码。

<?php
// database class
class Database
{
    // database host name
    private $db_host = "localhost";
    // database username
    private $db_user = "root";
    // database name
    private $db_name = "project_crud";
    // database password
    private $db_pass = "";

    public $conn;

    // function for create connection
    public function __construct()
    {
        try {
            $this->conn = new PDO("mysql:host=" . $this->db_host . ";dbname=" . $this->db_name, $this->db_user, $this->db_pass);
            $this->conn->exec("set names utf8");
        } catch (PDOException $e) {
            die("ERROR: Could not connect with database." . $e->getMessage());
        }
        return $this->conn;
    }
}

这是我的其他课程代码。

<?php

class Employees
{
    private $conn;

    private $db_table = "employees";

    public function getConnection()
    {
        $this->conn = $ob ;
    }

    public function readAllEmployee()
    {
        $data   = array();
        $query  = "SELECT * FROM $this->db_table";
        $stmt   = $this->conn->prepare($query);
        $stmt->execute();
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

        foreach ($result as $row) {
            $data[] = $row;
        }
        return $data;
    }
}

这是我的索引代码

<?php

include_once('database.php');
$db = new Database();

require_once("employee.php");
$obj = new Employees();
$obj->getConnection();

if (isset($_POST['action']) && $_POST['action'] == "view") {
    $output = '';
    $data = $obj->readAllEmployee();
    print_r($data);
}

现在我坚持连接到类以从数据库中读取信息。

标签: phppdo

解决方案


绝对没有理由在这里使用 OOP。你所拥有的是程序代码。您打开到 PDO 的连接并从数据库中获取一些数据。这里不涉及任何对象。

实际上,您的整个代码可以总结为以下几行(修复后):

$pdo = new PDO("mysql:host=localhost;dbname=project_crud;charset=utf8mb4", 'root', 'password', [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, //on by default since PHP 8.0
    \PDO::ATTR_EMULATE_PREPARES => false
]);

if('view' === filter_input(INPUT_POST, 'action')) {
    print_r($pdo->query('SELECT * FROM employees')->fetchAll(PDO::FETCH_ASSOC));
}

面向对象的编程意味着您应该将实体表示为类。例如,Employee可以是一个类,该类将具有某些对对象执行操作的方法。如果需要,这样的类可以由 PDO 链接组成,尽管您确实必须考虑您的类是做一件事情还是多件事情(例如,从数据库中获取并对员工对象执行操作)。

如果您决定实现此类,则可以通过以下方式传递 PDO 连接:

class Employee
{
    private PDO $pdo;
    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function getByID(int $id): ?array
    {
        $stmt =  $this->pdo->prepare('SELECT * FROM employees WHERE Id=?');
        $stmt->execute([$id]);
        return $stmt->fetch();
    }
}

然后,当您创建此类的实例时,您将 PDO 实例作为参数传递。

$emplpyee = new Employee($pdo);
$johndoe = $emplpyee->getByID(42);

现在小心!这仍然不是一个正确的 OOP。如您所见,我们的班级不充当员工。事实上,它充当了获取员工的 PDO 包装器。这是 PDO 已经提供的东西,因此可以通过以下方式重新设计该类:

/**
 * Class representing a real life employee in a company
 */
class Employee {
    private $Id;

    private $Name;

    public function getName(): ?string {
        return $this->Name;
    }
}

// Execute prepared statement to to create a single employee object. 
$stmt = $pdo->query('SELECT Id, Name FROM employees ORDER BY Id LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS, Employee::class);
$empl = $stmt->fetch();

echo $empl->getName();

// or if you want to fetch by an ID
$stmt = $pdo->prepare('SELECT Id, Name FROM employees WHERE Id=?');
$stmt->execute([1]); // pass ID of the employee
$stmt->setFetchMode(PDO::FETCH_CLASS, Employee::class);
$empl = $stmt->fetch();

echo $empl->getName();

// or if you need to fetch multiple employees
$stmt = $pdo->prepare('SELECT Id, Name FROM employees WHERE Id IN(?,?)');
$stmt->execute([1, 2]); // pass ID of the employee
$stmt->setFetchMode(PDO::FETCH_CLASS, Employee::class);
$employees = $stmt->fetchAll();
foreach ($employees as $empl) {
    var_dump($empl->getName());
}

现在我们有一个类,它有一些方法并代表一个实体。该类由创建对象并填充其属性的 PDO 实例化。无需传递 PDO 或处理类中的依赖项。每个类都有一个单一的职责。


推荐阅读