php - 如何连接两个类以从数据库中读取信息?
问题描述
我是 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);
}
现在我坚持连接到类以从数据库中读取信息。
解决方案
绝对没有理由在这里使用 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 或处理类中的依赖项。每个类都有一个单一的职责。
推荐阅读
- haskell - 相当于在 `shell.nix` 中将`-p zlib` 参数传递给`nix-shell`
- sql - SQL 递归 CTE 无限循环
- cairo - 在开罗绘制图像时如何禁用线性插值/平滑/抗锯齿?
- java - 检查同一数组上的两个重复字符是否位于最后一个位置。但是其中一个字符在最后一个位置
- angular-material - 选择所有垫子选项无法正常工作
- terraform - 更新自定义中转网关路由表而不是默认路由表 - terraform
- java - android.widget.ListView.setAdapter(android.widget.ListAdapter)' 在空对象引用上
- android - 我可以在 ViewModel 类中注入 @RootContext 吗?
- asp.net-core - Autofac 无法解析 ASP。NET Core Controller 尝试传递参数进行注册时
- javascript - `button.click` 只显示点击功能但不执行点击