我有一个用过程 PHP 编写的网站,现在我正在(至少部分)OOP 风格对其进行重新编码,以便我可以开始学习它。这是一个简单的页面,显示数据库中的多个学习类(class)(标题、描述等)。管理员可以添加或删除任何内容,因此它必须是动态的。 首先我运行了一行代码:
$courses=$pdo->run("SELECT id,title,description FROM courses WHERE status=1 ORDER BY id")->fetchAll(PDO::FETCH_CLASS, 'Course');
$cmax = count($courses);
并回应例如$courses[3]->description
但我觉得我什么也没做,只是在使用多维数组时假装 OOP。同样,对于网站的目的来说这是可以的,但我的问题是,为了习惯 OOP 逻辑,我可以这样做吗:我正在生成一个下拉菜单,其中仅包含数据库中的标题和 ID,单击其中一个后,我才创建对象(以获取描述、日期、教师等):
$obj = new Course($pdo,$userSelectedID);
echo $obj->getTitle($pdo);
$obj->showDetails($pdo); // etc
类(class):
class Course {
protected $id;
protected $title;
protected $description;
public function __construct($pdo,$id) {
$this->id=$id;
}
public function getTitle($pdo) {
$this->title=$pdo->run("SELECT title FROM courses WHERE id=?",[$this->id])->fetchColumn();
return $this->title;
}
public function getDescription($pdo) {
$this->description=$pdo->run("SELECT description FROM courses WHERE id=?",[$this->id])->fetchColumn();
return $this->description;
}
public function showDetails($pdo) {
echo "<h3>".$this->getTitle($pdo)."</h3>".$this->getDescription($pdo);
}
}
这是一个错误的做法吗?在类中运行sql命令可以吗?特别是当我已经不得不使用一些数据库数据来生成下拉菜单时。我希望我的问题有意义。
PS:我听说每次都传递 PDO 对象并不是最佳实践,但我还没有使用推荐的实例来做到这一点(?)
最佳答案
一个好的方法是为数据库中的每个表创建模型类。 模型包含与表列相对应的私有(private)属性,以及关联的 getter 和 setter。 对于您的类(class)表:
class Course {
protected $id;
protected $title;
protected $description;
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getTitle() {
return $this->title;
}
public function setTitle($title) {
$this->title = $title;
}
public function getDescription() {
return $this->description;
}
public function setDescription($description) {
$this->description = $description;
}
}
然后,您就有了数据访问对象的概念。您可以创建一个抽象类,该类将由您的数据访问对象扩展:
abstract class AbstractDAO {
protected $pdo;
public function __construct($pdo)
{
$this->pdo = $pdo;
}
abstract public function find($id);
abstract public function findAll();
abstract protected function buildModel($attributes);
}
对于您的类(class)表:
class CourseDAO extends AbstractDAO {
public function find($id) {
$statement = $this->pdo->prepare("SELECT * FROM courses WHERE id = :id");
$statement->execute(array(':id' => $id));
$result = $statement->fetch(PDO::FETCH_ASSOC);
return $this->buildModel($result);
}
public function findAll() {
$statement = $this->pdo->prepare("SELECT * FROM courses");
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$courses = [];
foreach($results as $row)
$courses[] = $this->buildModel($row);
return $courses;
}
public function findByTitle($title)
{
...
}
public function create(Course $course)
{
...
}
protected function buildModel($attributes) {
$course = new Course();
$course->setId($attributes['id']);
$course->setTitle($attributes['title']);
$course->setDescription($attributes['description']);
return $course;
}
}
现代框架会自动执行此操作,但我认为在使用 Eloquent 或 Doctrine 等强大工具之前了解它的工作原理是很好的
关于php - OOP - PHP 类中的 sql 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53223696/