Object Relational Mapping ORM в PHP


Оглавление (нажмите, чтобы открыть):

ORM технология

Уважаемые пользователи! Мы благодарим Вас за то, что Вам интересен нашен контент, поэтому с каждым днем хотим становиться все лучше и лучше!

Большое спасибо за вашу помощь и внимательность к нам!

Здравствуйте! В этом уроке я покажу несложный пример реализации ORM технологии. Для тех, кто не в курсе, что такое ORM вот Вам цитата с википедии: «ORM (англ. Objectrelational mapping, рус. Объектно-реляционное отображение) — технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования». Чтобы было яснее приведу пример ее использования пока что, не затрагивая ее реализацию, но для начала поговорим о том, какие php-«инструменты» я использовал для работы с базой данных.

В PHP есть встроенный класс предоставляющий доступ к серверу данных – PDO. Почему я использовал его, а не стандартные функции по работе с СУБД MySQL? На то есть две причины: во-первых в PDO изначально встроены решения по проверке данных на вредоносность, которые выполняются автоматически, а во-вторых класс PDO позволяет работать с разными СУБД, что делает систему еще более гибкой. Ниже приведен код с настройками подключения к серверу баз данных.

Используя данный класс можно получить доступ к серверу БД всего на всего создав его экземпляр. Теперь я покажу Вам, как просто работать с базой данных, используя ORM технологию.

Для примера возьмем таблицу, которая содержит новости сайта и заключает в себе заголовок, дату, непосредственно текст новости.

Как Вы могли заметить, в коде, приведенном выше нет ни одного запроса, все сводиться к простейшему присваиванию и вызову методов. Вот теперь, наконец, я объясню Вам, как можно достичь такой простоты работы с сервером БД. Все сводиться к одному классу, реализующему в своих методах основные действия и автоматизирующему выполнения запросов к базе данных. В этом классе содержаться следующие атрибуты:

Благодаря функциям __set и __get в php можно перехватить событие обращения к данным класса. По средствам этих функций, в нашем ORM классе происходит запись данных в массив $attributes и получение этих данных. Код этих функций проиллюстрирован ниже.

Далее функции удаления и записи данных в БД:

При сохранении данных вызывается одна из функций изображенных ниже.

Теперь две статические функции поиска, одна из которых возвращает только первую найденную запись, а вторая массив всех записей.

Теперь можем приступить к написанию класса для работы с конкретной таблицей. Этот класс единственное, что придется писать разработчику для работы с базой данных при условии, что у него есть ORM библиотека. За примером не будем далеко ходить и просто напишем класс для работы с таблицей news, который экземпляр которого уже использовали в примере в начале урока.

Обратите внимание на то, что этот класс наследует ORM класс описанный выше. Так же в члены-данные класса также записывается название таблицы, которую класс представляет и список полей этой таблицы.

На этом все! Благодарю за внимание! В следующем уроке, я уже рассмотрю динамическую форму на PHP и ее использование данной ORM библиотеки на данном примере, который может так же оказаться весьма полезным для Вас.

Блог веб-разработчика

О разработке веб-приложений на Symfony

ORM в мире PHP

ORM (англ. Object-relational mapping, русск. Объектно-реляционная проекция) — запись объектов программы в реляционную базу данных, отображение объекта и его представления в виде набора таблиц. — Википедия: ORM

В своей работе используем PHP Framework Symfony 1.2.9 и Propel 1.3, но планируем перейти на Symfony 1.3 + Doctrine. У меня возник вопрос: «А какие еще PHP ORM разработаны?». Немного погуглив — получили следующую подборку. Многие проекты новые и ещё альфа/бета версии, но в любом случае уже есть возможность из чего выбрать.

Active Record (AR) в разных PHP Framework:
• Yii Active Record
• CakePHP

7 Responses to “ORM в мире PHP”

ORM (реляционный AR) имеется также в Yii, CakePHP.

А, позвольте узнать, с чем связаны планы перехода на Доктрин? Чем он так лучше Пропела?

Тем, что сейчас разработчик Doctrine работает на Sensiolabs, и они конечно PR его :). К тому же проект развивается в отличие от Propel, да и обещают вообще не использовать Propel в Symfony 2. Вот так постепенно хочу перейти на Doctrine. Конечно интересует вопрос производительности — заодно и проверю это.

Ну судя по нововведениям препеля 1.4 из него потихоньку делают доктрин ��

Что касается производительности — чуда ждать не стоит — доктрина берёт возможностями…

propel 1.4 рулит, добавили много необходимых вещей, задумался по поводу перехода на доктрину.

Введение в ORM (Object Relational Mapping)

Что такое ORM?
ORM или Object-relational mapping (рус. Объектно-реляционное отображение) — это технология программирования, которая позволяет преобразовывать несовместимые типы моделей в ООП, в частности, между хранилищем данных и объектами программирования. ORM используется для упрощения процесса сохранения объектов в реляционную базу данных и их извлечения, при этом ORM сама заботится о преобразовании данных между двумя несовместимыми состояниями. Большинство ORM-инструментов в значительной мере полагаются на метаданные базы данных и объектов, так что объектам ничего не нужно знать о структуре базы данных, а базе данных — ничего о том, как данные организованы в приложении. ORM обеспечивает полное разделение задач в хорошо спроектированных приложениях, при котором и база данных, и приложение могут работать с данными каждый в своей исходной форме.

Парадигма «несоответствия»
Говоря конкретнее, использование ORM решает проблему так называемой парадигмы «несоответствия», которая гласит о том, что объектные и реляционные модели не очень хорошо работают вместе. Реляционные базы представляют данные в табличном формате, в то время как объектно-ориентированные языки представляют их как связанный граф объектов. Основные проблемы и несоответствия возникают во время сохранения этого графа объектов в реляционную базу или его загрузки:

    реляционная модель может быть намного детальнее, чем объектная, т.е. для хранения одного объекта в реляционной базе данных используется несколько таблиц;


реляционные СУБД не имеют ничего похожего на наследование — естественную парадигму объектно-ориентированных языков программирования;

в СУБД определен только один параметр для сравнения записей — первичный ключ. В то время как ООП предоставляет как проверку идентичности объектов (a==b), так и их равенства (a.equals(b));

для связи объектов СУБД использует понятие внешних ключей, в объектно-ориентированных языках связь между объектами может быть только однонаправленной. Если же нужно организовать двунаправленные отношения, то придется определить две однонаправленные ассоциации. Кроме того, нет возможности определить кратность отношения, глядя на модель предметной области;

  • принцип доступа к данным в ООП кардинально отличается от доступа к данным в БД. Для доступа к данным в ООП используются последовательные переходы от родительского объекта к свойствам дочерних элементов и инициализации объектов по необходимости. Такой подход считается не эффективным способом извлечения данных из реляционных баз данных. Как правило, количество запросов к БД должно быть сведено к минимуму, необходимые сущности должны по возможности загружаться сразу с использованием JOIN-ов.
  • Принцип работы ORM
    Ключевой особенностью ORM является отображение, которое используется для привязки объекта к его данным в БД. ORM как бы создает «виртуальную» схему базы данных в памяти и позволяет манипулировать данными уже на уровне объектов. Отображение показывает как объект и его свойства связанны с одной или несколькими таблицами и их полями в базе данных. ORM использует информацию этого отображения для управления процессом преобразования данных между базой и формами объектов, а также для создания SQL-запросов для вставки, обновления и удаления данных в ответ на изменения, которые приложение вносит в эти объекты.

    Преимущества и недостатки использования
    Использование ORM в проекте избавляет разработчика от необходимости работы с SQL и написания большого количества кода, часто однообразного и подверженного ошибкам. Весь генерируемый ORM код предположительно хорошо проверен и оптимизирован, поэтому не нужно в целом задумывается о его тестировании. Это несомненно является плюсом, но в тоже время не стоит забывать и о минусах. Основной из них — это потеря производительности. Это происходит потому, что большинство ORM предназначены для обработки широкого спектра сценариев использования данных, гораздо большего, чем любое отдельное приложение когда-либо сможет использовать. Вопрос о целесообразности использования ORM по большому счету затрагивается только в больших проектах, которые сталкиваются с высокой нагрузкой, здесь приходится выбирать что более приоритетно — удобство или производительность? Конечно, работа с БД посредством грамотно написанного SQL-кода будет намного эффективнее, но не стоит забывать и о таком параметре, как время — то, что с легкостью пишется с использованием ORM за неделю, можно реализовывать ни один месяц собственными усилиями. Кроме того, большинство современных ORM позволяют программисту при необходимости самому задавать код SQL-запросов. Без сомнений, для небольших проектов использование ORM будет куда более оправдано, чем разработка собственных библиотек для работы с БД.

    ORM. Коротко и ясно

    Один из наиболее часто задаваемых вопросов на форуме касается использования Object Relational Mapping (коротко — технология преобразования объектов в реляционные модели БД). Работа с БД всегда актуальна, поэтому любые способы ее облегчить/ускорить/стандартизировать достойны внимания.

    Актуально ли?

    Для начала определимся с основными целями ORM. С одной стороны, необходимо организовать работу с БД, учитывая различные варианты взаимоотношения реляционных таблиц («один-к-одному», «один-ко-многим», «много-ко-многим») и необходимость объединения данных разных таблиц в одну выборку (или наоборот, сохранения данных одного объекта в несколько таблиц). С другой — все это должно быть максимально прозрачно и просто для программиста. Можно использовать возможности Query Builder‘а, но в этом случае приходится вручную объединять таблицы, да и читается такой код не очень.

    Пример 1. Выбрать информацию о статье с > Query Builder:

    Пример 2. Добавить статью, вывести ее id.
    Query Builder:

    Согласитесь, ORM выглядит намного более естественно. Поля таблицы доступны как свойства объекта, связанные через внешние ключи таблицы можно получить как свойства объекта, редактирование записи таблицы происходит «вживую», прямо над объектом. Однако все это само собой не появится.

    Строим ORM

    Вы могли заметить, что в приведенных выше примерах создавался некий объект (ORM::factory(‘article’)). Это экземпляр модели Article_Model, в которой и необходимо реализовать используемые в дальнейшем способы работы с БД. Звучит страшно, но на самом деле большая часть работы уже проделана в классе ORM (system/libraries/ORM.php), который Article_Model расширяет. ORM реализует паттерн Active Record, описывающий методы взаимодействия объекта и записей в БД. Нам в принципе остается только построить схему взаимоотношений таблиц, чтобы ORM-классы могли с ее помощью извлекать данные. Поэтому зачастую модели состоят только из перечисления внешних ключей.

    Свойства носят говорящие названия, по описанию модели понятно, что на одну статью приходится один автор и несколько (т.е. от нуля до бесконечности) комментариев. Для того, чтобы можно было отследить связи в обратную сторону, создаем модели для авторов и комментариев.

    Существует 4 вида связей, они описывают одностороннее взаимодействие (т.е. то, как текущая модель относится к другим):

    • has_one — модель связана с одной моделью (связь «один-к-одному»), например статья-автор.
    • has_many — модель может содержать несколько других моделей (связь «один-ко-многим»), например статья-комментарии.
    • belongs_to — модель является частью другой модели (обратная сторона связи «один-ко-многим»), комментарии-статья.
    • has_and_and_belongs_to_many — модель может быть включена в другие модели, но и сама может содержать несколько таких моделей. Например, использованные нами категории статей связаны со статьями связью «много-ко-многим».
    Мастер Йода рекомендует:  Java & Android digest #1. Spring и написание собственных драйверов

    Так как таблица может быть связана с другой по нескольким полям, можно использовать псевдонимы:

    В этом случае поля $article->author и $article->redactor будут объектами User_Model, а таблица users связана с таблицей articles через внешние ключи author_id и redactor_id.

    Учтите, что такое удобство использования взамен ставит перед нами некоторые ограничения:

    • Имена моделей в единственном числе (Comment_Model, а не Comments_Model).
    • Имена таблиц во множественном числе (Users, а не User). Может быть отменено установкой свойства модели $table_names_plural равным FALSE, но ведь лучше придерживаться правил
    • Первичный ключ должен называться id и быть автоинкрементным. Конечно, это не всегда возможно, поэтому можно установить имя ключа в свойстве $primary_key (так мы сделали в статье «Представьтесь» с моделью User_Detail_Model, которая была связана с User_Model связью «один-к-одному»).
    • Имена внешних ключей образуются путем добавления суффикса _id к имени соответствующей модели (author_id для указания автора статьи).
    • Для связей много-ко-многим в реляционных БД используют т.н. «слабые сущности» — это таблицы, состоящие из первичных ключей связанных таблиц (например, для связи категорий и статей придется создать таблицу с полями article_id и category_id). Имена этих таблиц должны состоять из имен связанных таблиц, разделенных знаком подчеркивания (имена ставятся по алфавиту), в случае с категориями и статьями получим таблицу articles_categories.

    Вообще стоит обратить внимание на случаи, когда используются термины в множественном числе, а когда в единственном. Во множественном числе пишутся названия таблиц (users, articles, comments) и названия полей при указании связи «много-ко-многим» и «один-ко-многим» ($has_many = array(‘comments’);, $has_and_belongs_to_many = array(‘categories’);). ORM определяет множественные и единственные числа с помощью хэлпера Inflector, поэтому если возникнут проблемы с названиями таблиц или связей можете смело смотреть, какой результат вернет inflector::plural() или inflector::singular().


    Методы ORM

    Давайте посмотрим, что можно сделать с ORM.
    Создание. Два варианта — конструктор new или через ORM::factory(). Принципиально разницы никакой:

    Также можно в качестве дополнительного параметра указать значение первичного ключа, чтобы модель создалась с учетом какой-либо записи в БД:

    Также можно создать пустой объект без указания id и затем загрузить в него какую-либо запись в таблице:

    Для указания условий выборки можно использовать методы Query Builder‘а:

    Если объекту соответствует один экземпляр другой таблицы, можно использовать метод with() для объединения таблиц при получении объекта. Например, загрузить информацию о статье (article) вместе с информацией об авторе (author):

    После создания модели становятся доступны поля соответствующей таблицы через свойства объекта:

    Связанные таблицы также доступны через свойства, и так как они в свою очередь являются экземплярами моделей ORM, к ним также можно применять методы ORM и Query Builder‘а:

    Изменив какие-либо поля таблицы, можно их сохранить с помощью метода save(). При этом в объект заново загружается запись из БД (чтобы заполнить автоинкрементный ключ и поля, значения которых указаны по умолчанию).

    Обратите внимание, что в таблице authors изменения не вступят в силу, если сделать только $article->save(). Необходимо вызывать save() для всех моделей, в таблицы которых мы хотим внести изменения. В случае со связями «много-ко-многим» все чуть-чуть сложнее:

    Object Relational Mapping: ORM в PHP

    Want to be notified of new releases in DenBeke/ORM ?

    Launching GitHub Desktop .

    If nothing happens, download GitHub Desktop and try again.

    Launching GitHub Desktop .

    If nothing happens, download GitHub Desktop and try again.

    Launching Xcode .

    If nothing happens, download Xcode and try again.

    Launching Visual Studio .

    Permalink

    Simple ORM implementation for PHP

    When working with SQL databases, there is always the same monkey work that has to be done, like selecting using the table parameters, putting the result back in to a class, .

    ORM (object-relational mapping) solves this problem, you can just call some methods on classes, using the properties defined in your classes.

    This implementation is naive and very simple, but can spare you a lot of time and work.

    Since writing queries is a task I don’t always enjoy, this ORM packages depends on a query builder: Pixie (by Muhammad Usman).

    Dependencies are installed through Composer:

    You can of course also install this package using Composer:
    Add «denbeke/orm»: «dev-master» to your requirements and add the following code to the root of the composer.json file to add the Github repo:

    Before you can do anything you must call the \DenBeke\ORM\ORM::init() function (you must do this once in your application). An exception will be thrown if you call a method on an uninitialized ORM class.
    \DenBeke\ORM\ORM::init() takes an associative PHP array as argument. This array must contain some basic database configuration.

    The $db_config array will be passed to Pixie query builder. This means you can use all Pixie configuration options.

    Creating an «ORM-ready» class is very simple, just inherit from \DenBeke\ORM\ORM .


    After writing the code, you must also add a table person to the database, with the fields id , name , city .
    As you may have noticed, the table name is derived from the Class name (without namespaces and converted to lowercase!) and the column names are just the names of the PHP fields.

    The ORM implements a default constructor which takes an associative array or an stdClass and assigns the values from the input to the fields of the new object.

    Once the class inherits from \DenBeke\ORM\ORM you can access all the ORM methods. Starting with the get methods.

    The predefined get() method fetches all records of the given type from the database.
    If we have 3 records in the table person we can get all of them using the get() function:

    In this example $persons is an array of size 3, containing objects of type Person .

    Whenever a class has a field, the caller can get records from the database by those fields. In this example the class Person has the fields id , name , city . So you can call the following functions:

    • Person::getById($id);
    • Person::getByName($name);
    • Person::getByCity($city);

    Those static functions will return an array of Person elements, where the input parameter matches the table column.

    Work In Progress

    You can supply options to the get() and getBy*() methods. The options parameter is an associative array.

    You can order your results by supplying the orderBy option. orderBy should be an array, containing the the database column/field to order by, and an optional direction ( ASC or DESC’, default ASC`).

    If you have e.g. Bob, John, Alice in your database, the following operation will return Alice, Bob, John.

    Adding AND clause to the getBy* method can be done using the andWhere option.

    Adding OR clause to the getBy* method can be done using the orWhere option.

    Adding records to the database is quite simple, just create an instance of the class and call the add() method on it.

    Updating a record is as easy as adding records.
    Just alter a field and call the update() method.

    Deleting records can be done using the remove() method.

    PHP: Пример использования ORM Doctrine

    В данном посте рассмотрим простенький пример использования ORM, а именно, Doctrine. Если кто не в курсе, то ORM (Object-Relational Mapping, объектно-реляционная проекция) — такая штука, которая обеспечивают классам прозрачный доступ к базе данных. Правда не всяким классам, а тем, которые представляют описание нашей модели данных. В общем мне бы пару лет назад узнать о такой штуке, может быть я и не забросил изучение php, и вообще, много чего полезного сделал :D. Если кто-то знаком с паттернами проектирования, то можно сказать, что Doctrine соответствует шаблону Active Record. К своему стыду, сам я не знаком с ними, поэтому ничего конкретней сказать не могу пока что.

    Кстати, мы уже затрагивали мельком тему ORM, но только для python.

    Далее будет рассмотрен пример написания модуля на php с использованием ORM Doctrine для отправки личных сообщений между пользователей.

    Для начала определимся с нашей таблицей. Я решил использовать всего одну табличку, и для каждого сообщения так же хранить только одну запись в БД. И так, поля таблицы выглядят у меня примерно следующим образом:

    • id — id сообщения;
    • uid_from — id отправившего пользователя;
    • uid_to — id получателя;
    • title — заголовок сообщения;
    • text — текст сообщения;
    • flag_unread — флаг нового сообщения;
    • flag_del_from — признак удалённого сообщения из исходящих;
    • flag_del_to — признак удалённого сообщения из входящих;
    • date — дата отправки в формате unix timestamp;

    На этом этап проектирования у меня закончился. Теперь перейдём к технической стороне вопроса.

    Легкий ORM для PHP и MySQL

    В статье приводится реализация объектно-реляционного отображения, выполненная в виде небольшой библиотеки с простым и гибким интерфейсом. Код библиотеки доступен в виде одного php-файла. В качестве интерфейса к базе данных используются удобные функции PHP для работы с MySQL.

    Объектно-реляционное отображение (англ. object-relational mapping или ORM) — техника программирования, которая позволяет разработчику абстрагироваться от механизмов работы хранилища данных и писать код в терминах логики конкретного приложения. В частности, заменять написание SQL-запросов вызовом специальных функций/методов. 1

    Поиск по параметрам

    Самая частая задача при разработке веб-приложений — это построение списка на основании некоторых условий. Такой список может быть разбит на страницы и определенным образом отсортирован.

    В качестве примера рассмотрим получение списка товаров для страницы каталога в интернет-магазине, относящейся к определенному производителю.


    Предположим, товары хранятся вот в такой таблице:

    Страница каталога снабжена формой поиска, позволяющей ограничивать список товаров по некоторым параметрам:

    В этом случае код, необходимый для получения данных товаров, будет выглядеть следующим образом:

    $query = array (
    «manufacturer_ >,
    ‘where’ => $_GET ,
    ‘orderby’ => ‘[ord]’ ,
    ‘limit’ => [ ‘p’ , [ ‘N’ , 20 ] ] ,
    ) ;
    $P = new Products;
    $products = $P -> find ( $query ) ;

    Методу find() передается массив с условиями поиска: конкретные значения параметров, указания по сортировке и LIMIT, а также ограничения выборки, задаваемые вручную.

    Ключ where этого массива содержит значения параметров поиска, из которых по определенным правилам формируются условия конечного SQL-запроса (см. конфигурация параметров поиска). При вставке в запрос значения параметров автоматически экранируются 2 , лишние ключи (для которых в конфигурации нет соответствующего параметра) просто игнорируются.

    Остальные условия поиска будут подробно рассмотрены в соответствующих разделах статьи (произвольные условия, LIMIT, сортировка).

    Класс Products унаследован от специального абстрактного класса библиотеки и содержит в своем определении отображение параметров поиска (читай — полей формы) на структуру базы данных:

    Class Products extends _List <

    public $tables = array (
    «FROM products p» ,
    // здесь могут быть также JOIN с другими таблицами
    ) ;

    public $columns = array (
    ‘id’ => array (
    ‘sql’ => «p.id» ,
    ‘sort’ => ‘* DESC’ ,
    ) ,
    ‘price_final’ => array (
    ‘sql’ => «price * (100 — discount) / 100» ,
    ‘type’ => ‘[min,max]’ ,
    ‘sort’ => TRUE
    ) ,
    ‘title’ => array (
    ‘type’ => ‘LIKE%’ ,
    ‘sort’ => TRUE
    ) ,
    ‘has_discount’ => array (
    ‘sql’ => «discount > 0» ,
    ‘type’ => ‘on-off’
    ) ,
    ) ;

    Конфигурация параметров поиска

    Теперь обратимся к массиву $columns и рассмотрим конфигурацию каждого из полей детально.

    Поле, являющееся уникальным идентификатором записи в главной таблице, обязательно должно присутствовать и следовать в списке первым. Именно поэтому id упоминается в конфигурационном массиве, хотя его нет в форме.

    Ключ type определяет, как конкретно указанное SQL-выражение будет сопоставлено значению соответствующего параметра (эти значения входят в условия для построения списка (массив $query) и передаются в ключе where). Сопоставление бывает четырех видов.

    Равенство

    type, не установленный вовсе (как в случае с id) или равный FALSE в результате даст условие со знаком «равно», а если значения параметра является не скалярной величиной, а массивом, то IN.

    Например, если бы $_GET содержал в ключе id число 10, получилось бы условие

    а если бы — массив array ( «Атос» , «Д’Артаньян» ) , то 3

    Сопоставление типа LIKE

    Другой вариант сопоставления параметра содержит конфигурация поля title:

    Такая конфигурация даст условие вида

    где ‘параметр’ — это экранированный $_GET [ ‘title’ ] 4 .

    Если $_GET [ ‘title’ ] является массивом, условие будет составлено для каждого из его элементов, и затем все они объединены через OR (получится как бы IN для LIKE):

    Аналогичным образом можно использовать ‘%LIKE’ и ‘%LIKE%’ .

    Интервальное сопоставление

    Конфигурация поля price_final является примером интервального сопоставления:

    Указанные ключи параметра ограничивают выборку: первый — снизу, второй — сверху. Условие в данном случае примет вид:

    Вместо min и max можно указывать любые другие имена ключей, нужно лишь следить за тем, чтобы они совпадали с именами полей формы.

    Можно указать только один ключ (например, ‘[min,]’ ), в этом случае будет возможность ограничить выборку только с одной стороны.

    Если квадратные скобки заменить на круглые — ‘(min,max)’ — нестрогое неравенство заменится на строгое (так же, как обозначают интервалы в математике). При этом они не обязательно должны быть одинаковыми: с одной стороны неравенство может быть строгим, а с другой — нет.


    Сопоставление типа «включено/выключено»

    Для такого сопоставления SQL-выражение просто вставляется в запрос в неизменном виде, но лишь если соответствующий параметр присутствует в запросе и отличен от FALSE.

    Для поля has_discount с конфигурацией

    в запрос попадет условие WHERE ( discount > 0 ) .

    Это сопоставление лучше всего подходит для полей формы типа checkbox.

    Произвольные условия

    Ограничения списка могут не только формироваться на основании параметров поиска, но и быть прямо указаны вручную.

    В рассматриваемом примере страница каталога относится к какому-то конкретному производителю. В этом случае условие на manufacturer_id должно выполняться всегда — независимо от содержимого $_GET:

    Таких произвольных условий может быть сколько угодно. Все они войдут запрос непосредственно в том виде, в котором указаны, без изменений.

    Разбивка на страницы, LIMIT, получение общего количества строк

    Для разбивки на страницы в условия для построения списка нужно включать элемент limit. В случае, если номер страницы передается в GET-параметре p, а количество записей на странице может содержаться в параметре N, код может выглядеть следующим образом: 5

    То же самое можно записать в сокращенной форме (как это и сделано в примере):

    При такой форме записи имена ключей в limit относятся к массиву с параметрами поиска (where).

    Запись вида [ ‘p’ , [ ‘N’ , 20 , 100 ] ] устанавливает для количества записей ограничение сверху.

    Можно указывать числовые значения явно: ‘limit’ => ‘0, 20’ или ‘limit’ => 100 . Такая запись перейдет в LIMIT запроса в неизменном виде.

    Общее количество строк без учета LIMIT можно получить, передав методу find() необязательный второй аргумент — переменную, в которую это количество будет записано: 6

    Сортировка

    Указывать сортировку в условиях запроса следует в ключе orderby. При этом можно ссылаться на элементы массива $columns. Например:

    Фрагмент <*price_final DESC*>заменится на соответствующее SQL-выражение из массива $columns.

    Чтобы дать возможность управлять сортировкой через параметры GET-запроса страницы, в ключ orderby нужно поместить специальную метку:

    Здесь ord — ключ массива $_GET, содержащий текущие параметры сортировки.

    Соответственно, адрес страницы должен иметь вид . &ord=(имя поля из конфигурации) (направление) . Например, . &ord=price_final DESC . Метка в orderby заменится SQL-выражением для выбранного поля 7 , в результате запрос примет вид:

    Можно комбинировать метку и постоянные части:

    А также задавать сортировку по умолчанию для случая, если она не указана через GET-параметр:

    Получение и обработка данных

    Набор полей списка

    Каждому параметру поиска соответствует одноименное поле в результирующем массиве данных. Взглянем еще раз на конфигурацию 8 :

    Вот как примерно выглядит результат работы метода findIds():

    [5] => Array
    (
    [id] => 5
    [price_final] => 35000
    [title] => Телевизор
    [has_discount] => 1
    )

    [4] => Array
    (
    [id] => 4
    [price_final] => 1500
    [title] => Совок
    [has_discount] => 0
    )
    .

    Если поле нужно в качестве параметра поиска, но среди конечных данных не требуется, его можно исключить из результирующего массива, поместив в начало ключа специальную последовательность @@:


    При такой конфигурации элемент has_discount среди полученных данных будет отсутствовать.

    Получение данных одиночной сущности

    Для получения данных одиночной сущности по её идентификатору служит метод getSingle():

    Поля, которые для списка не требутся и нужны только для случая одиночной сущности, можно выделить явным образом. Их объявление должно начинаться с последовательности @: :

    Поле p.text при поиске и работе со списками запрашиваться из БД не будет, что даёт определенный выигрыш в быстродействии.

    Пост-обработка данных

    К каждой строке, полученной из БД, могут быть применены дополнительные преобразования. Для этого нужно определить метод processData ( ) . Например:

    Каждой записи результирующих данных добавится ключ url

    [5] => Array
    (
    [id] => 5
    [price_final] => 35000
    [title] => Телевизор
    [has_discount] => 1
    [url] => /products/5.html
    )

    [4] => Array
    (
    [id] => 4
    [price_final] => 1500
    [title] => Совок
    [has_discount] => 0
    [url] => /products/4.html
    )
    .

    Получение специальных данных

    Периодически бывает нужно получить не просто список сущностей со всеми полями, а какой-то специальный набор их данных. Для этого служит метод getSpecialData ( ) .

    На вход метод принимает набор SQL-выражений для будущих колонок результата, а также массив с условиями поиска (аналогичный тому, что используется для методов find ( ) и find >( ) ).

    Например, для заданных условий поиска получить ценовой диапазон и количество товаров со скидкой от 50% можно с помощью следующего кода:

    Здесь &price_final — ссылка на SQL-выражение в массиве $columns .

    Содержимое $special_data будет примерно следующим:

    Array
    (
    [0] => Array
    (
    [sale_count] => 35
    [price_min] => 1000
    [price_max] => 12500
    )

    Если результат заведомо состоит из одной строки, удобно использовать разыменовывание массива:

    Другой пример — получение всех производителей (точнее, их идентификаторов), товары которых удовлетворяют определенным условиям:

    Здесь методу передается одна колонка вместо массива, что является инструкцей вернуть вместо табличного результата колоночный:

    Связанные сущности

    Под связанной понимается сущность другого рода, на которую через уникальный идентификатор ссылается некоторое поле данной сущности.

    Например, у каждого товара есть производитель, >manufacturer_id . Производителям соответствует свой собственный класс Manufacturers , также унаследованный от _List , где описывается вся логика работы с ними: набор полей, параметры поиска, пост-обработка данных и т.д.

    Чтобы этой логикой пользоваться в классе товаров, нужно установить его связь с классом производителей. Это делается через соответствующее поле (в данном случае — manufacturer_id ), которому в конфигурации устанавливается свойство related :

    class Products extends _List <
    public $columns = array (
    .
    ‘manufacturer_id’ => array (
    ‘related’ => array ( ‘manufacturer’ => ‘Manufacturers’ )
    // ‘имя ключа’ => ‘класс’ (объяснение см. далее по тексту)
    ) ,
    ) ;
    .
    >

    class Manufacturers extends _List <
    public $tables = array (
    «FROM manufacturers m» ,
    ) ;

    public $columns = array (
    «id» ,
    «title» ,
    «country_id» ,
    ) ;

    function processData ( $row ) <
    $row [ ‘url’ ] = «/manufacturers/$row[id].html» ;
    return $row ;
    >
    .
    >

    Установление такой связи даёт две важных возможности.

    Поиск по свойствам связанных сущностей

    Среди параметров поиска могут быть относящиеся именно к производителям, а не только к самим товарам.

    При передаче методу find ( ) в составе $query [ ‘where’ ] они должны быть сгруппированы в подмассив manufacturer (имя подмассива указывается в конфигурации в качестве ключа в related — см. выше).


    Например, включать в форму поиска поле для указания страны производителя нужно с атрибутом name=»manufacturer[country_id]» :

    При этом сам вызов find ( ) не меняется никак:

    Единственное, что требуется — составить форму так, чтобы параметры поиска, относящиеся к производителю, приходили в подмассиве $_GET [ ‘manufacturer’ ] .

    Получение данных связанных сущностей

    У каждой записи из $products автоматически появится подмассив manufacturer :

    [5] => Array
    (
    [id] => 5
    [price_final] => 35000
    [title] => Телевизор
    [has_discount] => 1
    [url] => /products/5.html
    [manufacturer] => Array
    (
    [id] => 3
    [title] => SONY
    [country_id] => 7
    [url] => /manufacturers/3.html
    )
    )

    [4] => Array
    (
    [id] => 4
    [price_final] => 1500
    [title] => Совок
    [has_discount] => 0
    [url] => /products/4.html
    [manufacturer] => Array
    (
    [id] => 1
    [title] => Полимербытхимпром
    [country_id] => 1
    [url] => /manufacturers/1.html
    )
    )
    .

    Добавление, изменение и удаление записей

    write()

    Для добавления записей и изменения их данных служит метод write(). В качестве аргументов он принимает массив полей записи и её идентификатор:

    Если идентификатор не указывать, будет добавлена новая запись, а в ответ возращен ее идентификатор:

    При записи данные экранируются (используется mysql_write_row()), однако никаких проверок метод в себя не включает. Для этого рекомендуется использовать специальный инструмент для проверки правильности заполнения веб-форм.

    delete()

    Метод delete() в качестве аргумента принимает уникальный идентификатор (автоматически экранируется) и просто удаляет соответствующую запись из таблицы, возвращая TRUE в случае успеха:

    Дополнительные сведения и возможности

    В основе данной библиотеки лежит подход к построению списков, сущность которого заключается в следующем: сначала из БД с учетом условий, сортировки и LIMIT извлекаются уникальные идентификаторы строк, после чего для этих строк запрашиваются остальные данные. Обоснованию и разъяснению этого подхода посвящена отдельная статья.

    Чтобы вместо полных данных строк получить только их идентификаторы, нужно воспользоваться методом findIds(), интерфейс которого полностью аналогичен таковому метода find():

    Для получения полных данных списка на основе уникальных идентификаторов служит метод getList(): 9

    getList() может также принимать строку SQL-запроса, минуя стадию получения идентификаторов: 10

    При наличии режимов сортировки, описываемых сложными SQL-выражениями, бывает удобно пользоваться

    1. ▲ В классической реализации объектно-реляционного отображения каждой строке базы данных соответствует экземпляр объекта. Предлагаемая реализация не является классической: каждой строке здесь соответствует просто ассоциативный массив данных.

    2. ▲ Используется функция mysql_escape().

    3. ▲ Каждое из условий заключается в круглые скобки, чтобы ограничить действие оператора OR, если таковой встретится в выражении. То же самое касается произвольных условий (см. соответствующий раздел).

    4. ▲ Следует отметить, что в конфигурации поля title отсутствует ключ sql. В таких случаях в качестве SQL-выражения используется непосредственно имя параметра.

    5. ▲ Нумерация страниц начинается с единицы.

    6. ▲ Если переменная для записи общего количества строк передана, будет выполнен отдельный запрос вида SELECT COUNT ( * ) . Вопреки распространенной практике, такой вариант обладает более высокой производительностью, чем использование SQL_CALC_FOUND_ROWS. Подробнее см. https://sqlinfo.ru/forum/viewtopic.php?p >

    7. ▲ Если GET-параметр сортировки не соответствует ни одному из ключей массива $columns, он будет просто проигнорирован.

    8. ▲ Конфигурация в примере имеет полную форму записи. Можно использовать также сокращенные формы:

    public $columns = array (

    // все нижеуказанные варианты записи равнозначны

    ‘column’ => [ // полная запись
    ‘sql’ => ‘table.column’ ,
    ] ,


    ‘column’ , // если среди всех задействованных таблиц нет колонок с одинаковыми именами,
    // указывать таблицу в явном виде необязательно
    .
    ) ;

    9. ▲ Метод find(), собственно говоря, состоит из вызова findIds() и getList().

    10. ▲ Из-за этой возможности важно проверять пользовательские данные в случае, если они передаются методу напрямую. Например, для $P -> getList ( $_GET [ ‘ids’ ] ) важно убедиться, что в GET-запросе передается именно массив чисел, а не строка, иначе возможна SQL-инъекция.

    PHP Object Relational Mapping Framework

    I would like to know which one of the following is the best choice for O/R mapping in PHP:

    We are going to use PHP only for Web Service implementation. We have a Java background so a framework which is inspired by Hibernate would be easier for us to use as long as it’s a good, well documented and more or less easy to use O/R mapping library.

    2 Answers 2

    Like Jensgram already notes, it is hard to tell which option suites your needs.

    That said, I have experience with Kohanaphp and it’s integrated ORM. I must say it works perfect, but it has limited functionality if you compare it to Doctrine2. If you need advanced options like inheritance mapping and proxy classes Doctrine is the way to go. Like Doctrine 2 introduction says:

    Object relational mapper (ORM) for PHP that sits on top of a powerful database abstraction layer (DBAL). One of its key features is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL), inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility without requiring unnecessary code duplication.

    As it says, it is inspired on Hibernate HQL. I don’t have experience with the other options you mention, so I can’t say anything usefull about those.

    Что самое легкое в использовании рамки ORM для PHP?

    Я ищу активную запись Ruby для PHP. Что-то настолько простое, что я просто определяю свои поля, расширяю базовый класс ORM, и я получаю операции ACID бесплатно. Я должен получать утилизаторы и сеттеры по умолчанию без написания кода, но переопределение по умолчанию getter или setter так же просто, как объявление get $ fieldName или установка функций $ fieldName с поведением, которое я хочу. Symphony позволяет создавать около 5 файлов на объект, и все определенные объекты всегда загружаются, насколько я могу судить. Что является лучшей альтернативой? Почему это лучше? Можете ли вы привести простые примеры в свои ответы, пожалуйста?

    Доктрина – это еще один ORM, на который я смотрел, помимо симфонии. Также вам нужно создать файлы yaml, которые описывают ваши структуры данных. База данных уже определяет этот материал. Что будет просто читать мои таблицы defs без необходимости генерировать и хранить файлы конфигурации везде?

    Я большой поклонник Doctrine, который является полнофункциональным ORM, который заменит Propel на ORM по умолчанию Symfony.

    У вас есть ваш основной материал ORM, который вы ожидаете вместе с полнофункциональным построителем запросов, который, как мне показалось, замечательный.

    Он поставляется с полным набором инструментов командной строки для управления вашими базами данных. Например, вы можете создавать свои схемы и светильники в YAML, иметь Doctrine, создавать классы на основе вашей схемы, создавать базу данных, создавать схему на основе моделей, а затем заполнять базу данных вашими светильниками все с помощью единого ./doctrine build-all-reload .

    Он также включает поддержку миграции баз данных и недавно обновил миграцию, чтобы автоматически различать и генерировать ваши модели миграции.

    В соответствии с жалобами вашей доктрины вы можете запустить команду ./doctrine generate-models-db или ./doctrine generate-yaml-db чтобы автоматически создавать модели и файлы yaml соответственно из текущей настройки базы данных.

    Другие тонкости включают « Behaviors », что значительно облегчает жизнь при реализации определенных, ну, поведения в вашей схеме. Например, вы можете добавить поведение «Timestampable» в ваш файл класса. Doctine автоматически добавляет столбец «created_at» и «updated_at», заполняет их, и каждый запускаемый объект $object->save() автоматически обновляет столбец «updated_at». Более сложное поведение включает i18n, управление версиями таблиц и деревья (хотя на самом деле это только NestedSet).

    Лично я был чрезвычайно влюблён в Доктрину и восторженно рассказывал об этом каждый шанс получить.

    Я использую малоизвестный слой orm, называемый redbean. вы можете найти его здесь: https://www.redbeanphp.com . его абсолютно уникальный в том смысле, что он просто создает таблицы столбцов и индексов самостоятельно без каких-либо файлов конфигурации. Я нахожу, что это огромный развал!

    Я создал свой собственный, без раздувания. (Хотя мне нужно обновить мои источники на месте)

    Я создал его именно с учетом указанных вами соображений: нет десятков xml-файлов, нет огромных фреймворков, просто простых конструкторов с базой данных для свойств mappigns, и это ваш основной материал CRUD / Find / Join. Для большинства вещей, которые я делаю, мне даже не нужно писать пользовательские запросы.

    Я написал все это раньше на моем сайте , не забудьте проверить основные примеры, чтобы получить представление об этом.

    Следующая версия, которую я выпущу, включает в себя однострочное соединение для присоединения к join on join (чтобы пройти «путь» через вашу базу данных), настройки базы данных ini, поддержку кросс-базы данных, супер-простую абстракцию базы данных и стандартный логгер, который падает вернитесь к SQLite, если ваша база данных не работает.

    Просто дайте крик, если вы заинтересованы в обновлениях, я тогда буду спешить.

    О да, и не забывайте, есть также красивый визуальный генератор эшафотов, называемый Pork.Generator . Он пытается проанализировать структуру вашей базы данных и найти 1: 1 1: многие и многие: многие отношения и может автоматически генерировать классы для вас �� отношения, найденные в базе данных https://www.schizofreend.nl/images/demo3. JPG

    Zend_Db_Table и Zend_Db_Table_Row довольно хороши в том, что вы описываете. Вам не нужен какой-либо файл конфигурации, большинство метаданных «обнаружено» из самой базы данных.

    Технически эти классы не реализуют шаблон ActiveRecord. Вместо этого они реализуют шаблоны данных Data Gateway и Row Data Gateway . Вместе они предлагают аналогичную ценность, как ActiveRecord, и в некотором смысле более гибкие, чем ActiveRecord.

    Но, как и в случае любой ORM, неизбежно возникают некоторые SQL-запросы и операции, которые невозможно выполнить через интерфейс OO. ORM не может служить универсальным магазином.


    Сноска: Я работал над проектом Zend Framework чуть больше года, особенно на компоненте Zend_Db. Но я больше не работаю для них.

    Проверьте поддерживаемую структуру. Хотя я предпочитаю генерировать код по сравнению с ActiveRecord (отражение во время выполнения), я обнаружил, что поддерживаемая среда проста в использовании, особенно с точки зрения возможностей ORM.

    Если вам нужна структура, основанная на генерации кода, попробуйте QCodo. Что бы вы ни говорили о доктрине, я могу сказать для Qcodo. Это полноценная платформа, имитирующая .NET / Delphi. Однако вы можете просто создать функцию генерации кода и найти способы отделить ваш сгенерированный класс от остальной части фреймворка. Таким образом, вы можете вставлять сгенерированные классы в другие структуры.

    Другим вариантом, который следует за реализацией Ruby DataMapper, является phpDataMapper . Очевидно, это Data Mapper вместо ActiveRecord :).

    Я бы рекомендовал Учение с Symfony. Несмотря на то, что вам нужно узнать больше, вы обнаружите, что у вас есть функции, которые вам понадобятся после того, как проект будет расти (CRUD, Form framework, Record Templates, DQL, Plugin support, Behaviors). Оба проекта имеют очень активное сообщество, и вы не должны заходить в тупик, потому что большинство ваших вопросов уже были услышаны в официальных учебниках или на форуме.

    Если вам не нравятся определения базы данных в YAML, вы всегда можете использовать ORM Designer или MySQL Workbench.

    Я рекомендую QCubed . Это невероятно мощная инфраструктура ORM, основанная на PHP5, которая фокусируется на разработке кода, разработке пользовательских интерфейсов и быстрой разработке приложений. Взгляните на обучающие видео: https://qcu.be/content/video-screencasts

    • Генерирует / изменяет базы данных / таблицы / поля / различные атрибуты таблицы / поля на лету.
    • Не требуется установка.
    • Не имеет конфигурации вообще.
    • Нужно только включить библиотеку и указать параметры ссылки db для начала работы.
    • Он имеет встроенную поддержку локализации.
    • Он имеет различные уровни кеша и позволяет расширить механизм кеша.
    • Он одновременно работает со многими различными подключениями к базе данных.
    • Он может устанавливать отношения между таблицами, расположенными на других серверах баз данных.
    • Он извлекает атрибуты таблицы / поля, используя комментарии класса и переменных doc.
    • Он работает только с объектами. т.е. вы должны иметь определенный класс и иметь экземпляр класса для сохранения нагрузки или т. д.
    • У него нет сайта, но есть папка с примерами.

    Мне нравится Idiorm и Paris, и они используют их как в крошечных проектах. Idiorm – это реальный ORM, тогда как Париж является активной реализацией записи. Вы можете использовать тот, который вы бы предпочли.

    Существует также вилка под названием Гранада , которая построена над Идиормом и Парижем, и добавляет поддержку, такую ​​как нетерпеливая загрузка и т. Д.

    Объектный реляционный сопоставитель (ORM) для PHP, который находится поверх мощного уровня абстракции базы данных (DBAL). Одной из его ключевых особенностей является возможность записи запросов к базе данных в проприетарном объектно-ориентированном диалекте SQL под названием Doctrine Query Language (DQL), вдохновленном Hibernates HQL. Это дает разработчикам мощную альтернативу SQL, которая поддерживает гибкость, не требуя ненужного дублирования кода.

    Объявление класса ORM-объектов

    Объектом ORM считается экземпляр класса, наследника RS::Orm::AbstractObject.

    Пример простейшего объекта, описывающего пользователя:

    Согласно принятым в ReadyScript правилам, например, в поле «id» после объявления массива в конструкторе RS::Orm::Type::Integer будут вызваны методы: setPrimaryKey(true), setAutoincrement(true), таким образом в современной IDE всегда можно узнать полный список возможных ключей массива, просто посмотрев методы соответствующего класса с префиксами set и add.

    Cведения, описывающие поля объекта должны располагаться в методе _init. Данный метод вызывается только один раз для одного класса объектов в течении срока жизни скрипта. Вызов происходит при первом обращении к объекту поля ($orm[‘__field’]). Таким образом для загрузки объекта и простого чтения значения свойства ($orm[‘field’]), _init не вызывается.

    Для хранения списка полей используется объект класса RS::Orm::PropertyIterator. Таким образом все объекты класса User будут использовать один экземпляр класса RS::Orm::PropertyIterator. Заданные у объекта поля являются по сути колонками в таблице БД. При сохранении ORM-объекта данные будут соответственно названиям полей раскинуты по колонкам таблицы, при загрузке ORM-объекта все произойдет с точностью до наоборот. Некоторые поля можно не связывать с БД, для этого достаточно объявить у поля свойство runtime => true (RS::Orm::Type::AbstractType::setRuntime)

    В случае, если необходимо инициализировать значения переменных объекта по-умолчанию, необходимо перегрузить метод _initDefaults. Этот метод в отличие от метода _init вызывается при создании каждого объекта.

    Наследование и расширение объектов ORM

    В ООП принято общие свойства и общее поведение (группы методов) выносить в родительские классы, а более частное поведение реализовывать в наследниках. Применительно к ORM-объектам мы можем определить в родительских классах помимо методов, еще и общие поля. Например, у многих объектов есть поле id, так зачем же его описывать в каждом объекте? Гораздо эффективнее объявить его единожды. В ReadyScript имеется класс RS::Orm::OrmObject, который содержит в себе объявление поля id, который рекомендуется использовать в качестве родительского в изложенном выше случае.

    Пример наследования объектов и расширения списка полей объектов:

    В данном примере класс MyObject расширяет класс OrmObject, добавляя ещё одно поле name, которое будет связано с одноименным полем в таблице БД.

    Расширять список свойств ORM-объектов можно также с помощью обработки события orm.init. Этот вариант удобно использовать, когда необходимо из одного модуля изменить состав полей ORM-объекта другого модуля.

    Возможные типы полей

    Каждый объект RS::Orm::Type. ,характеризующий поле, имеет соответствующий тип в MySql. В системе присутствуют как простые типы, имеющие прямую связь с базой, например(в скобках указано название типа в БД): RS::Orm::Type::Varchar (VARCHAR), RS::Orm::Type::Blob(BLOB), RS::Orm::Type::Integer (INT), и.т.д., так и сложные типы, которые выполняют ряд действий перед сохранением и возвращают для записи в базу простое значение. К сложным полям относятся: RS::Orm::Type::File, RS::Orm::Type::Image, RS::Orm::Type::User, и др. Сложные поля могут также иметь сложное отображение в автоматически сгенерированных формах.

    Type Name Latest commit message Commit time
    Failed to load latest commit information.
    Тип в PHP Тип в MySQL Описание
    RS::Orm::Type::Varchar VARCHAR Испльзуется для хранения строковых значений
    RS::Orm::Type::Integer INT Испльзуется для хранения целочисленных значений
    RS::Orm::Type::Real FLOAT Испльзуется для хранения чисел с плавающей точкой
    RS::Orm::Type::Blob BLOB Испльзуется для хранения бинарных данных до 64 Kb
    RS::Orm::Type::Mediumblob MEDIUMBLOB Используется для хранения бинарных данных до 16 Mb
    RS::Orm::Type::Text MEDIUMTEXT Используеся для хранения текстовых данных
    RS::Orm::Type::Enum ENUM Используеся для хранения значений из заранее известного списка
    RS::Orm::Type::Richtext MEDIUMTEXT Используеся для хранения текстовых данных, отображается в форме в оболочке WYSIWYG редактора
    RS::Orm::Type::User INT Сложное поле. Используется для хранения ID пользователя. Отображается в форме в виде поля с поиском пользователя по логину, фамилии, e-mail’у
    RS::Orm::Type::Color VARCHAR Используеся для хранения значений цвета. Отображается в форме в виде поля с возможностью выбрать цвет из диалога
    RS::Orm::Type::CurrentSite INT Исользуется для хранения ID сайта.
    RS::Orm::Type::Datetime DATETIME Использется для хранения даты и времени
    RS::Orm::Type::Decimal DECIMAL Используется для хранения денежных велечин, цен
    RS::Orm::Type::File VARCHAR Сложное поле. Используется для хранения имени файла. Отображается в форме в виде поля для загрузки файла
    RS::Orm::Type::Image VARCHAR Сложное поле. Используется для хранения информации об изображении. Отображается в форме в виде поля для загрузки файла-изображения
    RS::Orm::Type::Timestamp TIMESAMP Используется для хранения временной метки
    RS::Orm::Type::Hidden Runtime поле. Отображается в форме в виде скрытого элемента input[type=»hidden»]
    RS::Orm::Type::Mixed Runtime поле. Используется для хранения временных значений у объекта
    RS::Orm::Type::ArrayList Runtime поле. Используется для промежуточного хранения массивов
    RS::Orm::Type::Captcha Runtime поле. Отображается в форме в виде Капчи (картинки с цифрами) и формы для ввода этих цифр
    RS::Orm::Type::UserTemplate Runtime поле. Используется для отображения произвольного шаблона в форме

    Синхронизация структуры БД

    При описании класса объектов ORM, задаются все сведения, описывающие поля в базе данных. Это делается для того, чтобы объект мог создавать и обновлять структуру соответствующей таблицы в БД. Во время синхронизации недостающие поля будут добавлены в таблицу БД запросом ALTER TABLE. В случае, если во время синхронизации в таблице БД присутствуют поля, не объявленные в ORM-объекте, эти поля останутся нетронутыми.

    Используя метод RS::Orm::AbstractObject::addIndex можно также описывать простые или составные индексы, которые также будут синхронизироваться с базой данных. Индексы, не присутствующие в описании ORM-объектов будут удалены при синхронизации, т.к. наличие «лишних» индексов может негативно сказаться на производительности системы.

    Мастер Йода рекомендует:  Как оценить труд программистов
    Добавить комментарий