美文网首页
PHP 新手入门指南 - 重构 PDO 业务代码

PHP 新手入门指南 - 重构 PDO 业务代码

作者: chansey | 来源:发表于2017-06-21 14:59 被阅读83次

在之前的小实践中我们通过了解 PDO 完成了对数据库中表数据的读取显示。
接下来,会对之前的业务代码进行也重构优化,让程序结构更为清晰。

回顾

原先的 index.php:

// index.php
<?php

require 'functions.php';
require 'Task.php';

$pdo = connectToDb();

$tasks = fetchAllTasks($pdo);

require "index.view.php";

functions.php 中定义了相应的函数:

  • connectToDb 用于连接数据库
  • fetchAllTasks 则是读取表中的数据
// functions.php
<?php

function connectToDb()
{
    try {
        return new PDO('mysql:host=127.0.0.1;dbname=mytodo', 'root', '');
    } catch (PDOException $e) {
        die('Could not connect.');
    }
}

function fetchAllTasks($pdo)
{
    $statement = $pdo->prepare('select * from todos');

    $statement->execute();

    return $statement->fetchAll(PDO::FETCH_OBJ);
}

function dd($data)
{
    echo '<pre>';
    die(var_dump($data));
    echo '</pre>';
}

Task.php 这个类用于映射表中的行数据。

// Task.php
<?php 

class Task
{
    public $description;

    public $completed;
}

页面呈现部分 index.view.php 是这样:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <ul>
        <?php foreach ($tasks as $task) : ?>
            <li>
                <?php if ($task->completed) : ?>
                    <strike><?= $task->description; ?></strike>
                <?php else: ?>
                    <?= $task->description; ?>
                <?php endif; ?>
            </li>
        <?php endforeach; ?>
    </ul>
</body>
</html>

重构代码

我们主要重构 index.php 中的业务逻辑:连接数据库,读取表中数据。

在项目目录下新建 database/Connection.php 文件,内容如下:

// databases/Connection.php
<?php

class Connection
{
    public static function make() 
    {
        try {
            return new PDO('mysql:host=127.0.0.1;dbname=mytodo', 'root', '');
        } catch (PDOException $e) {
            die($e->getMessage());
        }
    }
}

这里将连接数据库封装到了名为 Connection 的类中,通过静态方法 make 来执行连接数据库的操作,try ... catch ... 代码块的作用是为了捕获连接数据库中存在的异常错误,出现错误则终止程序。

通过 make 方法成功执行后将会返回一个 PDO 的数据库连接实例。

了解更多有关 PHP 异常的信息,请查看 这里

接下来,在项目目录下新建 database/QueryBuilder.php,内容:

// database/QueryBuilder.php
<?php 

class QueryBuilder
{
    protected $pdo;

    public function __construct($pdo)
    {
        $this->pdo = $pdo;
    }

    public function selectAll($table)
    {
        $statement = $this->pdo->prepare("select * from {$table}");

        $statement->execute();

        return $statement->fetchAll(PDO::FETCH_CLASS);
    }
}

这是一个用于构建数据库查询语句的类,有个 selectAll 方法,这个类依赖一个 PDO 连接实例,类的构函数中传入的参数说明了这一点。selectAll 将会返回查询结果。

由于我们将 functions.php 中的代码进行了重构,重新定义了 ConnecitonQueryBuilder 类,引入这个文件也没有必要,同时,我们的读取的数据表信息以 Class 形式返回,如下:

object(stdClass)#4 (3) {
    ["id"]=>
    string(1) "1"
    ["description"]=>
    string(21) "Finish the screencast"
    ["completed"]=>
    string(1) "1"
  }

因此,Task.php 也可以去掉了。

调整后 index.php 如下:

// index.php
<?php

require 'database/Connection.php';
require 'database/QueryBuilder.php';

$pdo = Connection::make();

$query = new QueryBuilder($pdo);

$tasks = $query->selectAll('todos');

require "index.view.php";

运行程序刷新页面,程序显示的结果和重构之前一样。

还可以做得更好

我们可以将连接数据库,查构建数据库查询认为是程序启动项。所以,我们可以进一步的优化这一部分。

项目目录下新建 bootstrap.php

// bootstrap.php
<?php

require 'database/Connection.php';
require 'database/QueryBuilder.php';

return new QueryBuilder(
    Connection::make()
);

没错,我们将数据库相关的类引入和实例化放到了一起。这样我们 index.php 将关注读取特定的表数据。

最终 index.php 如下:

// index.php
<?php

$database = require 'bootstrap.php';

$tasks = $database->selectAll('todos');

require "index.view.php";

刷新页面,程序依旧能按照我们的预期结果运行。
但是最终,重构让程序结构变得更加清晰了不是吗?

相关文章

网友评论

      本文标题:PHP 新手入门指南 - 重构 PDO 业务代码

      本文链接:https://www.haomeiwen.com/subject/jfttcxtx.html