nguyenzz/design-patterns

v1.1 2024-08-07 09:22 UTC

This package is auto-updated.

Last update: 2024-09-23 08:42:25 UTC


README

1. 构建者设计模式

构建者模式是一种创建型模式,它允许您按步骤构建复杂对象。该模式允许您使用相同的代码创建不同类型和表现的对象。

例如:考虑如何创建房屋对象。要构建一栋简单的房子,你需要建造四面墙和一层,安装门和窗,然后建造屋顶。但如果你想要一个更大、更明亮的房子,有后院和其他设施(如供暖系统、水管和电线系统)呢?

最简单的解决方案是扩展基本House类,并创建一个包含所有参数组合的子类集。但最终你将拥有大量的子类。任何新的参数,比如门廊类型,都会要求进一步开发这个分级系统。

有一种不涉及子类继承的方法。你可以在基本House类中创建一个巨大的构造函数,包含所有可能的参数以控制house对象。尽管这种方法实际上消除了对子类的需求,但它又带来了另一个问题。

例如:Builder接口声明了一组方法来组装MySQL查询。所有的构建步骤都返回构建器对象本身,以允许链式调用:$ builder->select(...) -> where(...)

<?php
namespace Nguyen\DesignPatterns;

interface SQLQueryBuilder
{

    public function execinsert(string $table, array $data): SQLQueryBuilder;

    public function execselect(string $table, array $columns): SQLQueryBuilder;

    public function execwhere(string $column, string $value): SQLQueryBuilder;

    public function execorwhere(string $column, string $value, string $operator = '='): SQLQueryBuilder;

    public function execnotwhere(string $column, string $value, string $operator = '='): SQLQueryBuilder;

    public function execorderby(array $data): SQLQueryBuilder;

    public function execfind(string $table, int $id): SQLQueryBuilder;
    
    public function execupdate(string $table, array $data): SQLQueryBuilder;

    public function execdelete(string $table, string $column, string $value): SQLQueryBuilder;

    public function execlimit(int $start, int $offset): SQLQueryBuilder;

    public function execin(string $column, array $data): SQLQueryBuilder;

    public function execjoins(string $table, string $join, string $column1, string $column2): SQLQueryBuilder;

    public function execfirst(): SQLQueryBuilder;

    public function exec_alteradd(string $table, string $column, string $data_type): SQLQueryBuilder;

    public function exec_alterdrop(string $table, string $column): SQLQueryBuilder;

    public function exec_altermodify(string $table, string $column, string $data_type): SQLQueryBuilder;

    public function exec_rename(string $table, string $newname): SQLQueryBuilder;

    public function execgetSQL(): string;

    public function executeQuery(): array;

    public function executeAlterQuery(): bool;

}

每个具体Builder对应于MySQL的一个特定方言,并且可以稍微修改构建步骤。

<?php
namespace Nguyen\DesignPatterns;

class MysqlQueryBuilder implements SQLQueryBuilder
{
protected $query;

protected $table;

public function __construct()
{
    $this->query = new \stdClass();
    $this->query->select = "*";
}

public function __call(string $name, array $arguments)
{
    return $this->{"exec" . $name}(...$arguments);

}

public static function __callStatic(string $name, array $arguments)
{
    return (new static)->{"exec" . $name}(...$arguments);
}

    public function exectable(string $table): self
{
    $this->query->table = $table;
    $this->query->type = 'select';

    return $this;
}

    public function execgetSQL(): string
{
    $query = $this->query;
    $sql = "SELECT " . $this->query->select . " FROM " . $this->query->table;
    if (!empty($query->where)) {
        $sql .= " WHERE " . implode(' AND ', $query->where);
    }
    if (!empty($query->orwhere)) {
        $sql .= " OR " . implode(' OR ', $query->orwhere);
    }
    if (!empty($query->notwhere)) {
        $sql .= " WHERE NOT" . implode(' AND NOT', $query->notwhere);
    }
    if (isset($query->limit)) {
        $sql .= $query->limit;
    }
    if (isset($query->order)) {
        $sql .= $query->order;
    }
    $sql .= ";";

    return $sql;
}

public function executeQuery(): array
{
    $sql = $this->execgetSQL();
    print_r($sql);
    $db = new Database();
    try {
        $qr = $db->connect('localhost', 'root', 'abc1234', 'BT')->query($sql);
    } catch (\PDOException $e) {
        echo "Error executing query: " . $e->getMessage();
        return [];
    }
    $ar = [];
    while ($row = $qr->fetch(\PDO::FETCH_ASSOC)) {
        $ar[] = $row;
    }

    return $ar;
    }
}

下面是如何使用

<?php
require './vendor/autoload.php';
use Nguyen\DesignPatterns\MysqlQueryBuilder;
use Nguyen\DesignPatterns\Database;

$result = MysqlQueryBuilder::select(["id", "city_name", "country_id", "population"])->executeQuery();
print_r($result);

结果

Alt text

如何使用PHP包

安装

composer require nguyenzz/design-patterns:dev-main

基本使用方法

1. 使用composer自动加载器

require "../vendor/autoload.php";
use Nguyen\DesignPatterns\Database;
use Nguyen\DesignPatterns\MysqlQueryBuilder;

2. 设置数据库连接

$db = Database::connect(string $hostname, string $username, string $password, string $dbname);

3. 使用查询构建器

  1. 获取"city"表的全部数据

     $result =  MysqlQueryBuilder::table("city")->executeSelectQuery();
     print_r($result);
    
  2. 获取"city"表的"id"和"city_name"列的数据

     $result =  MysqlQueryBuilder::table("city")->select(["id", "city_name"])->executeSelectQuery();
     print_r($result);
    
  3. 查找"city"表中城市名称的数量

     $result =  MysqlQueryBuilder::table("city")->count("id")->executeSelectQuery();
     print_r($result);
    
  4. 向"city"表中添加数据

     $result = MysqlQueryBuilder::insert("city", ["6", "nguyen", "2", "453534"])->executeSelectQuery();
     print_r($result);
    
  5. 在"city"表中查找数据值

     $result = MysqlQueryBuilder::table("city")->where("city_name", "Hà Nội")->executeSelectQuery();
     print_r($result);
    
  6. 修改"city"表中的数据

     $result = MysqlQueryBuilder::update("city", ["id"=>"6", "city_name"=>"nguyen", "country_id" => "2", "population" => "323432"])->executeQuery();
     print_r($result);
    
  7. 限制从"city"表中返回的数据

     $result = MysqlQueryBuilder::table("city")->limit(1, 3)->executeSelectQuery();
     print_r($result);
    
  8. 向"city"表中添加列

     $result = MysqlQueryBuilder::_alteradd("city", "acreage", "int")->executeAlterQuery();
     print_r($result);
    
  9. 从"city"表中删除列

     $result = MysqlQueryBuilder::_alterdrop("city", "acreage")->executeAlterQuery();
     print_r($result);
    
  10. 修改"city"表中的列

     $result = MysqlQueryBuilder::_altermodify("city", "acreage", "int")->executeAlterQuery();
     print_r($result);
    
  11. 检查"city"表中数据的存在性

     $result = MysqlQueryBuilder::exists("city", "country", ["city_name" => "nguyen"])->executeQuery();
     print_r($result);