php - OOP - PHP 类中的 sql 命令

标签 php sql pdo

我有一个用过程 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/

相关文章:

sql - 使用 MSSQL 过滤 SQL 数据以获取每个备用 ID 的最新数据

php - 将可变数量的参数传递到 PDO 语句并返回 JSON 对象

php - 我可以将数组绑定(bind)到 PDO 查询中的 IN() 条件吗?

php - Magento:如何将商店设置转移到默认范围?

php - 通过引用传递;为什么原始对象没有改变?

sql - 查询索引 View 时的 WHERE 子句性能

php - 使用 SQL 将行元素分组为一列

php - PDO:PDO::MYSQL_ATTR_INIT_COMMAND 中的多个命令

php - 如何从文件中分离出 SQL 查询列表?

sql - SQL中连续序列 block 的计数