Строитель(builder)

Строитель — это порождающий паттерн проектирования, который позволяет создавать сложные объекты пошагово. Строитель даёт возможность использовать один и тот же код строительства для получения разных представлений объектов.


Паттерн предлагает разбить процесс конструирования объекта на отдельные шаги (например, построитьСтены, вставитьДвери и другие). Чтобы создать объект, вам нужно поочерёдно вызывать методы строителя. Причём не нужно запускать все шаги, а только те, что нужны для производства объекта определённой конфигурации.

<?php
 
interface SQLQueryBuilder
{
    //SELECT * FROM table WHERE id = 2
 
    public function select( array $fields) :SQLQueryBuilder;
    public function from( string $table) :SQLQueryBuilder;
    public function where( string $field, string $operator = "", string $value = ""): SQLQueryBuilder;
    public function limit( int $start, int $offset) :SQLQueryBuilder;
 
    public function getQuery() : string;
 
 
}
 
class MysqlQueryBuilder implements SQLQueryBuilder
{
    private $query;
 
    public function init() {
        $this->query = new stdClass();
    }
 
    public function select( array $fields) :SQLQueryBuilder
    {
        $this->init();
        $this->query->base = "SELECT ".implode(", ", $fields);
 
        return $this;
    }
    public function from( string $table) :SQLQueryBuilder
    {
        $this->query->base .= " FROM ".$table;
        return $this;
    }
    public function where( string $field, string $operator = "", string $value = ""): SQLQueryBuilder
    {
        if(func_num_args() == 2) {
            $this->query->where[] = $field. " = ". $operator;
        }
        else {
            $this->query->where[] = $field. " ". $operator. " ". $value;
        }
 
        return $this;
    }
    public function limit( int $start, int $offset) :SQLQueryBuilder
    {
        $this->query->limit = " LIMIT " . $start . ", " . $offset;
 
        return $this;
    }
 
    public function getQuery() : string
    {
        $sql = "";
        $sql .= $this->query->base;
 
        if(!empty($this->query->where)) {
            $sql .= " WHERE ".implode(" AND ", $this->query->where);
        }
 
        if(!empty($this->query->limit)) {
            $sql .= $this->query->limit;
        }
        $sql .= ";";
 
        return $sql;
    }
}