Comments 100
Я просто оставлю это здесь:
php.net/manual/ru/pdo.prepared-statements.php
ru.wikipedia.org/wiki/ORM
Странно, что вы не нашли ни одной готовой
даже на хабре подобных статей было вагон и маленькая тележка.
Есть такая хорошая штука как (GitHub/Gitlab/Bitbucket/etc) и посмотрите пожалуйста ее, там всё это "добро" уже есть !
Метод setLimit() работает только на один запрос, после этого лимиты обнуляются.
$DB->setLimit (10);
// т.е. если кто-то добавит новый код, то все может поломаться и у запроса ниже уже не будет LIMIT?
$res = $DB->fetchArray ('clients', "NAME = 'John'");
Кто-то еще качает файлы по ссылке?
Если уж хотите, чтобы люди ознакомились с вашим кодом, залейте на гитхаб
Java-скриптам
Это про JavaScript или про Java приложения?
вы разные вещи смешиваете. QueryBuilder — это построитель запросов. К объектам отношения не имеет.
конечному пользователю насрать
я общаюсь в комментах it-сайта в топике, касающегося программирования, на темы с ним же, с программированием, связанные. Если вы "конечный пользователь", то пропускайте мимо глаз и ушей наши "демагогии".
какой-то вы неприятный собеседник
раньше понятия QueryBuilder и ActiveRecord отличались от нынешних
Нет, раньше query builder как подход и active record как паттерн были тем же чем они являются сегодня. Это как бы суть названий и терминов — если они часто меняются, и у них нет четкого определения — то надо придумать новый термин с четким определением и перестать юзать что-то что вводит в заблуждение людей.
Причина по которой под ActiveRecord понимают все что угодно произрастает из безграмотности людей и подмены понятий (когда "паттерн" какой-то или идею подменяют конкретной библиотекой).
и люди писали самодельные велосипеды на файлах.
в 70-х? да, было такое. только тогда небыло ни mysql ни php да и концеп SQL-я только только зараждался. И нет ничего плохого в хранении данных в файлах, просто это сегодня имеет смысл только если вам надо специализированное хранилище (и вряд-ли вы что-то такое будете на php писать, хотя можно).
А о том, что со временем и сами названия меняются — тем более.
от того что вы юзаете code igniter термин query builder своего значения не поменял ни разу. Это штука которая позволяет вам строить запрос. причем за выполнение этого запроса или за работу с result set оно уже не отвечает.
Причем, для того что бы вы могли с result set работать вам нужна какая-то информация о запросе (интроспекция) и проще всего это сделать добавив свой строитель запросов который будет эту инфу предоставлять для других компонентов вроде мэпперов каких и т.д. Ну и что бы не писать что-то типа $db->execute($query)
и т.д. можно скрестить это дело и с коннекшен менеджером.
Но это просто конкретное решение конкретной библиотеки и никакого отношения к терминологии все это не имеет.
Что до "конечного пользователя" — проблема штук типа CI ActiveRecord в том что это создает ограничения применимости решений. Иногда хочется и не через PDO поработать а через какой-то асинхронный драйвер на модных нынче свуле, и оказывается что 99% всех квери билдеров это подкопирку содранные друг к друга куски гуано которые так просто не реюзать.
$res = $DB->fetchArray ('clients'); // получаем все записи в виде массива ассоциативных массивов
if ($res)
foreach ($res as $client)
echo print_r ($client, true); // выдаем все записи на экран
Выглядит красиво, да, но стоит добавить в конструкцию новую строчку и вот уже Вы корите себя за то, что изначально не использовали фигурные скобки.
echo print_r ($client, true);
Это вообще вогнало в некий ступор. Зачем???
if ($res)
Что это? Resource или Result? Не надо сокращать даже такие, казалось бы, элементарные вещи. Ни к чему хорошему это не приведет. Сначала сокращаете error на e, а потом путаетесь между event и error, не говоря уже о переменных типа AvgPrc и прочей ереси, которая вырастает из безобидных казалось бы сокращений.
$res = $DB->fetchArray ('clients', array ("NAME" = "John", ">=AGE" => 25), array ("NAME", "AGE"), array ("ID" => "ASC", "NAME" => "DESC"));
Прочитайте про Fluent Interface
$res = $DB->fetchArray ('clients'); // получаем все записи в виде массива ассоциативных массивов
echo print_r ($client, true); // выдаем все записи на экран
Вы правда считаете, что подобное комментирование полезно?
ну у вас еще тип есть, который неплохо дополняет какое-то общее $error
или $event
. Опять же в этом случае нет смысла в суффиксах для типов (InvalidArgumentException
вместо InvalidArgument
).
passwordInput.addEventListener('click', function(event) {
var minClickAreaPercent = 0.8; // далее 80% от левого края срабатывает переключение
var toggleIsAble = (event.offsetX / this.clientWidth > minClickAreaPercent);
// какой-то код
}
В котором семантически правильней назвать аргумент функции не event (и уж тем более не e), а например mouseClick или mouseClickEvent, но да, людям лень потратить на 1\2 секунды больше на набор текста. К счастью, подобного рода проблемы не распространяются на долгоживущие проекты с постоянной командой разработки.
Я и сам раньше грешил переменными типа $fido, $fids — мне понятно, что $fido — ресурс открытый fopen на чтение, fids — на запись, но потом сам начинаешь в этом путаться, переназначать случайно эти переменные.
У меня лично проблем с идентификацией исключений нет, но именовать так переменные — не самый лучший вариант.
То есть обоснования нет, но вы склоняетесь к определенному варианту. Это нормально, вкусы у людей отличаются, но это не стоит замечания на код-ревью.
Тянуть сюда аналогию с локальными переменными или формальными параметрами функций — можно, но, имхо, это уже педантизм)
$e
.К любым гайдам и стандартам нужно подходить критически, не отключать мозг, включая линтеры и автоформатеры. Некоторым людям порой свойственно изображать педанта и часами спорить о малозначимой ерунде. Это точно хуже, чем просто плохой стиль)
Хорошо, давайте исследовать «общепринятые практики» из живых проектов на PHP: YII, Composer, WordPress, Joomla и куча встреченных мной топ-проектов на GitHub (по звездам) используют "
$e
" или что-то не менее «семантичное», вроде "ex
" или "err
". Выходит, это авторское изобретение.Выходит очередная статья, документация, книга, любая авторская работа. Если она становится популярна, как с точки размера аудитории, так и с точки зрения вклада в сообщество, то многие принимают ее за чистую монету и считают, что абсолютно все в этому труде нужно брать за эталон => в том числе берут оттуда такую информацию, которую автор возможно и не планировал донести.
Это явно прослеживается и в примере с try catch из PSR. Суть этого правила заключается в отступах, порядке и скобках, а саму переменную исключения добавили потому что без нее пример казался бы некорректным. Разумеется ее нельзя выкидывать даже для примера, поэтому по привычке добавили $e.
Именно по привычке, потому что еще раньше эту несчастную $e опубликовали в какой-нибудь известной статье, а автор этой статьи еще раньше прочитал известную книгу, где автор повествовал об обработке исключений, но решил сэкономить на печатном пространстве и сократил $exception до $e, ведь в этой книге вообще не было целей говорить о семантике и правилах хорошего тона в коде.
Ну вот PSR как раз рекомендует $e.
нет, он рекомендует расстановку пробелов и скобочек. То, что там написано $e, к стандарту не относится.
Что до абстракций типа ORM, репозиториев и критерий — все это прекрасно работает опять же в ситуации когда у тебя все выборки можно влипить в WHERE. без джойнов, подзапросов и прочих оконных функций. Чуть сложнее и абстракции эти перестают помогать (в том виде в котором они существуют в PHP) что опять же ставит вопрос «а нафига оно все надо!?» Ведь взять ту же доктрину (как бы я ее не любил) но на ее изучение нужно немало времени, в ней полно багов, это очень сложный продукт сам по себе… и тот факт что оно помогает мне только для очень простых задач меня очень расстраивает.
а потом начал загоняться по всяким там возможностям выводить типы, верифицировать запрос (даже по частям) на соответствие схеме без необходимости запуска оного
Блин, а зачем так упарываться?
Я вот объективно не видел систем такой сложности где это бы требовалось и было в хоть сколько-то окупаемом виде.
То есть вы не видели систем где требуется «что бы работало»? Статический анализ это просто один из вариантов как можно производить верификацию, это не серебрянная пуля, тесты всеравно писать придется. Но от тупых ошибок избавиться хотелось бы в компайл тайме.
Да и опять же. имея интроспекцию можно много тупого кода удалить.
Устранение проблем с ошибками схемы в среднем занимало 1-2 инциндента по 0.1-0.5 часа на 4 двухнедельных релиза.
Т.е. за год работы не более 6.5 часов
Парсинг и анализ чистых SQL из кода больше трех дней занял у разработчика насколько я помню.
Анализ запросов формируемых QueryBuilder и DQL в общем случае не взлетел и решили не продолжать после чистого SQL.
Это примитивная библиотека, которая просто упрощает взаимодействие с MySQL.
Все, о чем пишут многие — это уже ближе к ActiveRecord.
Свое видение по ActiveRecord я опубликую отдельно, в виде еще одного «велосипеда».
Для создания этой библиотеки я использую ту, про которую написана это статья.
Третий «велосипед» — это связь между серверной ActiveRecord и фронтовой JavaScript. То есть попытка сделать ActiveRecord для JavaScript с заранее сконфигурированной базой данных на сервере.
«Велосипеды» — может это и плохо, особенно в 2018 году, когда пакетов, библиотек, фреймворков сделано уже очень много. Но — это же форум разработчиков. И каждый раз изобретая очередной «велосипед» может родиться умная и конструктивная дискуссия. А отчасти ради этого и существует данный проект.
Всем удачи!
А толку? Ну то есть… смотрите. Вы написали велосипед. Причем не просто велосипед, а примерно такой же как пишут его сотни других разработчиков ежегодно (если не еженедельно). На хабре подобные велосипеды постят раз в пол года примерно (вот типа одинаковые по работе с базой), и будут продолжать постить. «Форум разработчиков» же.
Так вот, польза от этих «дискуссий» в общем только для автора велосипеда. потому что он не счел необходимым погуглить другие велосипеды и происходящие там «дискуссии», иначе одинаковых велосипедов было бы меньше.
А потому — толку для сообщества нет от слова совсем.
Вам настоятельно рекомендую разобраться с PSR и PHPDoc, то что вы выложили на гитхаб — страх и ужас. Методы то паблик, то протектед, то без указания области видимости (паблик то бишь), фигурные скобки то есть, то нету, комментарии в таком стиле — ужасны, хотя я смотрю вам уже пулреквест выкатили с phpdoc-комментариями.
Пока что ваш велосипед вызывает глазное кровотечение и физическую боль.
Во-первых, "это" не форум.
Во-вторых, здесь вы уже ничего не опубликуете.
В-третьих, это не велосипед, а деревянная палка, к которой вместо колес примотаны скотчем костыли.
Для умной и конструктивной дискуссии приходите на Тостер и задавайте вопросы о том, как правильно работать с SQL. Для начала про защиту от SQL инъекций. Воможно, годика через два, у вас и получится что-то, что будет не стыдно показать другим разрботчикам, и надеяться на "конструктивную дискуссию"
Добро бы в классе была бы структура базы и класс организовывал бы левые соединения.
Посмотрите PHP-фреймворки, из простых рекомендовал бы Yii, они придуманы именно потому, что у 90% задачи бэкенда сводятся к тому же.
PS После многих лет работы с 1С в обычных SQL-ных запросах не хватает обращения к полям связанной таблицы через точку…
То есть если у нас есть таблица sales, в котором есть поле customer, содержащие id записи таблицы customers, то для его получения можно было написать запрос вида
SELECT sales.date, sales.amount, sales.customer.name as name
FROM sales
То есть получить поле связанной таблицы без прописывания этой таблицы через JOIN в запросе. Отчасти в PHP-фреймворках это решается через модели и метод «WITH», но не так удобно. Было бы здорово увидеть реализацию подобной возможности для PHP.
SELECT s.date, s.amount, c.name FROM Sales s JOIN s.customer c
— пожалуй, самое близкое из более менее известных
Было бы здорово увидеть реализацию подобной возможности для PHP.
Doctrine и DQL.
select sales.date, sales.amount, customer.name
FROM App\Sales sales JOIN sales.customer customer
но в целом я бы не назвал это прям таким удобным (потому что в большинстве случаев я бы хотел видеть в объектой модели айдишки а не целые сущности). Основная проблема большинства квери билдеров — манипуляция строками и мутации, что делает невозможным ни верификацию типов ни прочие прикольные вещи. Про композицию вообще молчу.
Doctrine и DQL.
Это почти то, но не совсем, так как в 1С это реализовано без Join, то есть если customer является id записи другой таблицы, то обращаться к customer.name можно без строчки
JOIN sales.customer customer
но в целом я бы не назвал это прям таким удобным (потому что в большинстве случаев я бы хотел видеть в объектой модели айдишки а не целые сущности)
А зачем вам id само по себе? Что вы с ним будете делать?
В любом случае тут могут быть два подхода.
1) в случае указания в запросе customer без свойств возвращать id а не целиком модель.
2) В запросе написать customer.id
Отдать клиенту, например. А уж если ему нужны детали, то он сделает запрос на их получение по id.
1) связь может быть не по полю id, и даже не по primary key
2) тут построитель должен быть достаточно умным, чтоб не джойнить customer, а отдать ссылку на него. А если такой записи в customer нет? ну и 1 тоже справедливо
Отдать клиенту, например. А уж если ему нужны детали, то он сделает запрос на их получение по id.
Отдать клиенту вы можете customer.id и это будет даже более грамотно в случае если такой записи нет. Тогда customer.id возвратит null и у клиента не будет иллюзии, что такая запись существует
1) связь может быть не по полю id, и даже не по primary key
2) тут построитель должен быть достаточно умным, чтоб не джойнить customer, а отдать ссылку на него. А если такой записи в customer нет? ну и 1 тоже справедливо
1) Речь идет именно о связи с таблицей сущностей с уникальным primaryKey, имя которого указано в foreignKey(использование иных имен кроме id мне кажется странным и непрофессиональным, но не суть)
2) Это очень простое условие, перебираются поля, если есть обращение через точку, то добавляется join. Если такой записи нет, то как сказано выше возвращается null для всех полей customer
и это будет даже более грамотно в случае если такой записи нет.
Очень сильно зависит от нюансов. Например, записи нет, а дело в архиве (бумажном) есть.
Речь идет именно о связи с таблицей сущностей с уникальным primaryKey, имя которого указано в foreignKey(использование иных имен кроме id мне кажется странным и непрофессиональным, но не суть)
На одном из недавних проектов внешние ключи были запрещены вообще, а по соглашению в качестве имени поля первичного ключа использовалось <имя сущности/таблицы>_id
Это очень простое условие, перебираются поля, если есть обращение через точку, то добавляется join. Если такой записи нет, то как сказано выше возвращается null для всех полей customer
То есть не просто JOIN даже, а LEFT JOIN? А если задача вывести как раз отчёт по битым ссылкам?
А зачем вам id само по себе? Что вы с ним будете делать?
хранить, на чтение у меня другие штуки. ORM на чтение не нужна.
В доктрине это все есть
$sale = $em->find('Sale', 1);
echo "Customer: " . $sale->getCustomer()->getName() . "\n";
Вечная тема с PHP и MySQL