скачать ORM v2.3 с примером использования --------------------------------------------------------------------------------------- ORM v3 в разработке^ww находится в альфа-версии. Выше выложена наша реализация ORM (далекой от идеала). Теперь я решил создать третью версию. Что хочется видеть в результате: - очень простое API (см. примеры ниже) - жадная выборка - ленивая выборка - гибкость (возможность юзать голый SQL и QueryBuilder для выборок) - небольшой размер - небольшое использование памяти - быстрота - хорошее покрытие тестами - поддержка различных БД, в первую очередь PostgreSQL, MySQL, SQLite - поддержка различных php расширений для ДБ, в первую очередь PDO - привязка к произвольной структуре БД - manual - физически один объект для объектов полученных из разных мест - автоподстановка в редакторах на всех уровнях (классы, свойства, методы) - OrmAdmin Что скорее всего не будет: - связь многие ко многим - наследование - валидаторы Зачем нужна ORM? - увеличение производительности разработчика (хорошо реализованная ORM на порядок удобней SQL) - снижение ошибок при написании программ (т.к. код получения и изменения в ORM и хорошо протестирован) - защита от SQL инъекций (невозможно случайно не экранировать, т.к. об этом заботиться ORM) Как это будет выглядеть: PHP: <? // получаем все объекты MyClass foreach(ORM()->MyClass as $myObject) { /* ... */ } // получаем объект по ID 5 $myObject = ORM()->MyClass(5); echo "$myObject->name $myObject->lastName"; // по условию foreach(ORM()->MyClass->like('name', '%waka%') as $myObject) { /* ... */ } // прозрачное объединение таблиц $list = ORM()->MyClass; $list->name = 'waka'; $list->MyClass2->name = 'waka waka'; foreach($list as $myObject) { /* ... */ } // создание таблиц $class = ORM()->add('MyClass'); $class->add('name', 'text', 255); $class->add('lastName', 'text', 255); $class->add('myObject', 'MyClass2'); $class->save(); // удаление объекта $myObject->delete(); // удаление по условию ORM()->MyClass->like('name', '%waka%')->delete(); // обновление по условию ORM()->MyClass->like('name', '%waka%')->set('name', 'waka waka')->update(); // создание объекта $object = ORM()->MyClass(); $object->name = 'waka'; $object->save(); // физически один объект ORM()->MyClass(5) === ORM()->MyClass(5); // true ?> Я намеренно отказался от конструкций new MyClass(5) для получения и new MyClass для создания т. к. нельзя гарантировать "физически один объект для объектов полученных из разных мест" У меня есть полное представление как это будет работать. Проект OpenSource, лицензия BSD. TDD. Жду от вас: 1. Желающие участвовать в разработке. 2. Вопросы 3. Предложения 4. Критика Спасибо.
Есть Doctrine. И оно тяжелое. Использую там, где с ресурсами не считаются вообще. Не для WEB. Точка. Я сказал © Д.Ф.Купер
Зачем нужна ORM? - увеличение производительности разработчика (хорошо реализованная ORM на порядок удобней SQL) - снижение ошибок при написании программ (т.к. код получения и изменения в ORM и хорошо протестирован) - защита от SQL инъекций (невозможно случайно не экранировать, т.к. об этом заботиться ORM) Мне в Doctrine много вещей не нравиться, но в топе этого списка громосткий синтаксис, много букв Я очень люблю jQuery - просто и лаконично. Если провести аналогию, моя реализация - это jQuery, Doctrine - это работать с голым DOM, а SQL - это голый HTML
уменьшения пр-ти скрипта ок кстати говоря, не всё нужно экранировать, столкнулся недавно с такой проблемой... ну ладно. реализуй мне выборку дерева категорий (id,parent_id)
PHP: <? // реализация class Tree extends ORM_Object { function getChilds() { return ORM(__CLASS__)->equals('parent', $this); } } // использование function showTree(Tree $root, $level = 0) { echo str_repeat(' ', 3*$level); echo $child->title; echo '<br />'; foreach ($root->getChilds() as $child) showTree($child, $level+1); } showTree(ORM()->Tree(1)); есть второй версии (со всеми вытекающими) 1. незначительно 2. критичные места всегда можно на замнить на SQL 3.
Практически так же. работающий пример дерева в example.php http://ti.y1.ru/orm2.zip 84 кб. база test, юзер test, пароль test (поменять в bootstrap.php) ORM2 разрабатывался в составе framework, я оставил из него только необходимое для ORM и OrmAdmin (см /acp) ORM2 допускал создание таблиц только средствами ORM, схему сохранял в базе. только PostgreSQL под PDO.
Есть желание, времени очень мало, но желание все таки есть, так что много сделать не смогу, если конечно вообще смогу на том уровне что надо, но очень бы хотелось попробывать...
Реальных задач требующих наследования в ORM не возникало. Кроме того всегда можно самому сделать "базовый" класс членом: получаем все фишки множественного наследования + меньшее связывание. (наследование в ORM так и реализуется) Если оно понадобится не сложно будет его реализовать.
Да, наследование сильно-слабая вещь ООП, лучше членом делать... Но вот многие-ко многим я бы хотел иметь...
Мы делали в прошлой версии многие-ко-многим. Но от этого были одни проблемы и не однозначности т.к. связующая таблица не представленна явно, следовательно, сложно с ней оперировать. Удобней использовать третий класс для связей многие-ко-многим.
Пришёл к выводу, что сочетание слов "небольшой размер" в употреблении к ORM это оксюморон. Я тут себе делал ORM (или AR, хз где разница у них). Желание было сделать небольшую надстройку над DbSimple с удобным интерфейсом. Лично для меня, удобство, помимо всего прочего, заключается в поведении одного и того же действия в зависимости от контекста. Вышло 42 КБ и не учитывая обращения к другим классам (собственно, к самому DbSimple и классу для работы с массивами). Не то чтобы я гений минимализма или ваще гений, но и не имбецил. За исключением некоторых глюков и пары нерешённых (философских: делать что-то или не делать ) вопросов, вышло всё, как я хотел - в том числе и миниатюрно, и удобно, и пришпандорить можно почти к любой готовой структуре. Но очевидно, что 42 КБ на самом деле это не есть миниатюрность. Так же как очевидно, что выборка вроде $list->MyClass2->name это два "select *". Даже не джоин, блин. Могу в приват ссылку кинуть, если чё-нить захотца, то бери. Там лицензия LGPL (не нравятся мне BSD, MIT и иные подобные), но коли возмёшь, то сменю те "экспортные" куски под лицензию, которая будет у твоего кода (BSD). Нафигишкин? Посмотри на Criteria - какой она страшный штука. (Не описался, юморю.) И второй вопрос. У тебя есть $list->свойство = 'вака-вака' и $list->add() это разные вещи? Возможно, я несколько шизанулся в том плане, что считаю, что следует исходить из контекста, но всё же почему не: Код (Text): $list->'lastName' = array('type' => 'text', 'length' => 255); $list->alter(); Или что-то подобное. По ходу иногда поля нужно не только добавлять, но и менять существующие. Возмёт кто-то твой ORM себе, встроит в движок (бсяшность этому способстует), а обновление движка придётся через попку делать. Штука же не редкая: люди косячат, люди ленятся вбивать нормальную длинну для полей в БД, люди забывают ставить индексы и т.д. и т.п. Ох, уж эти люди.
lexa Да, было бы интересно посмотреть твой код это решает жадная выбока да. Первое добавляет параметр в выборку, воторой добавляет поле в таблицу в моем случае это будет выглядеть так: Код (Text): <? ORM()->myClass->lastName->setType('text', 255);
Знаете, работал я тут в конторе, которая занимается созданием АСУ для клиентов. Контора старая, опытная, шишек понабивала просто тысячами себе уже. У них своя разработка, на базе котороё они делают все проекты. Ничего похожего в и-нете нету, ни халявного, ни платного (а система между тем весьма универсальна, и даже неплохо маштабируется и оптимизируется по необходимости, т.е. допиливается для производительности - это там предусмотренно). Так вот, там подобие ORM какраз есть. DataMapping используется. Обновляете объект, он потом обновляет всё в базе. Нужна выборка в 7 джойнов? Пожайлуста - там это делалось не тупым перебором в циклах, а они дошли до системы, где задавался шаблонный запрос и в итоге 7 модулей могли сделать 1 запрос и получить все данные для отоборажения. Да, конечно не всё было идиально и местами некоторые вещи делались через хаки (которые обуславливались тем, что это real time системы). Многое нельзя было сделать из-за ограниченности по версиям софта (проекты длятся по 1-2 года, некоторые по 5-6 лет и до сих пор идёт наращивание функционала). Мораль бастни такова, что без тесной взаимосвязи самого приложения с ORM не будет эффективного и быстрого механизма. Там он работал потому, что это было само приложение. Там event-driven система, модули - это по сути ORM прослойки, в которые по необходимости дописывались пользовательские события через хуки, а всё остальное делает сама система. Сделать модуль с редактированием, добавлением, удалением, JavaScript data list занимало до 2-х часов всего. С абсолютного нуля. Так что не занимайтесь чепухой. Либо вам нужно по сути спроектировать целую систему и далеко не в одиночку, либо взять готовое. А можно просто пользоваться SQL, сделать лёгкое абстрогирование и не мучать свои мозги, используя их силу для решения прикладных задачь.
Ti Она доказывает то, что ОРМ в отрыве от приложения это идиотизм, потому что PHP это не C/Java/etc, где нету такой сильной нагрузки на память и CPU в силу природы этих языков программирования и обсалютно другой логикой построения приложений и возможностях куда более широких чем в PHP. А вообще SQL есть SQL. ORM идёт лесом в любом более-менее нагруженном проекте, потому что вы явно будете использовать особенности базы данных и всёравно будете кормить ему SQL руками. В итоге "Нахера мне ОРМ, если я пишу запросы руками?! Выкину ка я эти лишние 100кб кода и будет работать быстрее.". Я это уже проходил, даже DBSimple щас ненужное излишество, от которого толку 0.
Psih Я твою позицию давно понял. Как ты еще на хардварный уровень не ушел? С твоей религией тот факт что ORM в 150 раз удобней SQL тоже идет лесом? О чем тут спорить? Недавно я поменял работу. Сейчас приходится писать SQL. Я так, простите за мой французкий, заебался. Хочу ORM. Пока не реализую написанное выше, моя душа не будет спокойна. Еще раз прошу не офтопить. Нужнен ORM миру или не нужен прошу обсуждать в другом треде.
Вопрос: Правильно ли я понимаю, что каждый метод из данного примера PHP: ORM()->MyClass->like('name', '%waka%')->set('name', 'waka waka')->update(); возвращает массив объектов? Т.е. реализация аналогичная jquery? И если да, то верно ли, что каждый метод -- это один запрос в БД?
Возращает Iterator объектов. Запрос выполняется "по первому требовнию" ORM() возращает коллекцию классов (Iterator) ORM()->MyClass коллекция объектов MyClass (Iterator) ->like('name', '%waka%') добавляет условие >set('name', 'waka waka') устанавливает значение update() - выполняет запрос UPDATE один запрос. PHP: foreach(ORM()->MyClass->like('name', '%waka%') as $myObject) ; один запрос (перед итерацией) [sql]SELECT * FROM my_class WHERE name LIKE '%waka%'[/sql]