- PVSM.RU - https://www.pvsm.ru -

SQL-запрос на PHP (Версия 0.2)

image
Внес изменения в свою реализацию класса для генерации SQL запросов по сравнению с прошлой версией [1]. Однако прежде чем писать о них, хотелось сразу прояснить некоторые вопросы которые в первом посте остались, на мой взгляд, не раскрыты:

  1. Это не очередной QueryBuilder. Хотя синтаксис и выглядит похоже, но по сути работает это по-другому. QueryBuilder обычно выполняется в Runtime. Мой же код предварительно нужно компилировать и на выполнение запускать уже откомпилированную версию. В частности код с картинки будет скомпилирован в следующий код PHP
    if (!isset($__query58)) {
        $__query58 = new MLSQLQuery(
             '0cfd84f430c39bb567ef7cd28bf36054', 
             array(
                      'server' => '***', 
                      'database' => '***', 
                      'user' => '***', 
                      'pass' => '***', 
                      'prefix' => 'ms-', 
                      'codepage' => 'utf8'
              )
        );
    }
    $__query58->sql = ' SELECT `profile`.`iduser` AS `profile.iduser`,`user`.`name` AS `user.name` FROM `ms-Users-Profile` AS `profile`LEFT OUTER JOIN `ms-Users-User` AS `user` ON `user`.`id`=`profile`.`iduser` WHERE (`profile`.`net`='VK' OR `profile`.`net`='OK') AND `user`.`sex`='M'';
    $rows = $__query58->rows();

    При использовании переменных в качестве имен полей или значений они будут вставлены в запрос через вызовы специальных функций, которые исключат SQL-инъекцию

  2. Для чего это нужно: я планирую сделать свой ORM (само собой с блекджеком и шлюхами) и PHPSQL будет являться абстрактным слоем для работы с БД. Планируется писать запросы в виде
    select(id)->from(UsersUser)->where(sex == 'M');

    который затем будет компилировать в PHP код с промежуточной компиляцией в PHPSQL.

  3. Нет, такой подход с компиляцией файлов не будет тормозить работу. Достаточно сделать это один раз при первом обращении к файлу, а затем закешировать скомпилированный вариант и в дальнейшем работать уже с ним. Также это можно делать один раз при установке/обновлении движка через консоль. В этом случае нам вообще неважно сколько времени займет компиляция, главное чтобы итоговый файл работал быстро.
  4. Да, такой подход действительно может создавать проблемы в отладке. Потому что из-за сгенерированного кода при ошибке в коде номер строки ошибки будет соответствовать новому скомпилированному файлу, а не тому, в котором вы этот код набирали.На текущий момент я пока не придумал как это обойти. Если есть какие-то идеи — озвучьте их.
  5. Да, я в курсе что «вместо изобретения своего велосипеда лучше бы использовал что-то крутое, типа Doctrine|Eloquent|другой вариант». Но я пошел своим путем потому что 1) мне это интересно 2)мне это нравится
  6. Почему не выложил на гибхаб: потому что данный класс использует функции из других моих библиотек, которые в свою очередь требуют еще библиотек и в общем это все занимает 17 мб исходных текстов, по которым нет справки. При этом из некоторых библиотек используется одна/две простенькие функции. На текущий момент пока не вижу смысла делать рефакторинг чтобы вынести этот функционал в отдельную небольшую папку для общего доступа. Будет интерес — выложу.

Ну а теперь перейдем к изменениям:

  • Самое основное нововведение — в новой редакции все константные строки интерпретируются как имена полей. Т.е. теперь вместо field(net) == 'VK' можно писать net == 'VK'. Для имен полей с символом тире в имени можно использовать оператор исполнения в обратных ковычках: `net-soc`== 'VK'. Функция field осталась, её можно использовать если имя поля, к примеру, находится в переменной: field($fieldname).
  • Исчезли функции вида _And, _Or. Теперь в условии нужно использовать вместо них операторы && и ||. Т.е. раньше было _Or(field(net)==value('VK'),field(net)==value('OK')), в новой редакции net=='VK' || net=='OK'
  • Добавилась поддержка JOIN запросов (на стартовой картинке как раз пример с ним)
  • Добавлен низкоуровневый метод Query, который позволяет создавать любые запросы,
    которые нельзя сделать с помощью специализированных функций. По сути это просто обычное формирование запроса с помощью конкатенации строк. Однако в методе можно использовать специальные функции, которые позволяют исключить SQL-инъекции.
  • Расширилась функция field. Теперь можно написать в виде field([<имя псевдонима таблицы>,]<имя поля>)[->as(<имя псевдонима поля>)]
  • Поддержка сортировки, группировки, условий агрегации

Для тех, кому интересно, тестовый полигон для компиляции кода [2] находится по тому же адресу. Если найдете какую-то ошибку, пишите в комментариях. Пока это версия 0.2 так что ошибки весьма вероятны.

Автор: Шабанов Валерий

Источник [3]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/php-2/253511

Ссылки в тексте:

[1] прошлой версией: https://habrahabr.ru/post/320718/

[2] полигон для компиляции кода: http://phpsql.shasoft.com

[3] Источник: https://habrahabr.ru/post/327160/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best