xPDO
Последнее обновление Jan 22nd, 2020 | История страницы | Улучшить эту страницу | Сообщить о проблеме
Support the team building MODX with a monthly donation.
The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.
Backers
Budget
$311 per month—let's make that $500!
Learn morexPDO - это объектно-реляционный мост, встроенный в MODX. Проще говоря, это то, как MODX подключается к базе данных и как он взаимодействует с различными таблицами.
В MODX 2.x, класс modX
непосредственно расширяет xPDO
. Хотя в ретроспективе это не лучший шаблон разработки, это означает, что всякий раз, когда у вас есть доступ к экземпляру modX
, вы можете использовать любой из методов xPDO
на нем.
Что такое xPDO?¶
xPDO (open eXtensions to PDO) - это легковесная ORB (object-relational bridge, объектно-реляционный мост) библиотека, работающая на PHP 5, которая помогает пользоваться преимуществами последних стандартов работы с базами данных в PHP, расширением PDO (PHP Data Objects). xPDO реализует очень простой, но эффективный паттерн для доступа к данным Active Record, а также гибкую модель предметной области, позволяющую отделить логику области от логики, специфичной для той или иной базы данных, когда это вам нужно.
Но xPDO - это немного больше, чем простая реализация паттерна. Это еще и способ абстрагирования бизнес-логики приложения от фактически используемых для доступа к данным в БД SQL-запросов и связанных переменных (prepared statements), а также легко описать и обеспечить реализации объектной модели для нескольких целевых платформ баз данных.
Задачей xPDO является быстрое обеспечение фундамента веб-приложения, который легко расширить до полноценной объектной модели, которая может быть оптимизирована насколько это возможно без зависимостей от конкретной платформы.
Глоссарий¶
В контексте xPDO важно знать следующие термины:
-
Packages - коллекции моделей. В ядре MODX все модели являются частью пакета
modx
, плюс есть несколько подпакетов, таких какmodx.media
иmodx.package
. Чтобы xPDO узнал о моделях в пакете, его необходимо зарегистрировать с помощью$xpdo->addPackage()
. - Models - классы, которые представляют конкретную таблицу базы данных. Это абстракция, которую вы будете использовать чаще всего: вместо непосредственного взаимодействия с SQL вы загружаете модель, настраиваете ее свойства и сохраняете.
- Schemas - XML-файлы, которые определяют различные модели, доступные в пакете, и их поля (свойства). Они используются только в разработке, во время которой они будут обрабатываться (обычно называемые «встроенными») в модельных классах и картах.
-
Maps - php-файлы, содержащие массивы, которые определяют метаданные для пакетов и схем. Они находятся в директории модели драйвера базы данных (например:
model/modx/mysql/modresource.map.inc.php
). Эти файлы обычно не обрабатываются вручную, а создаются из файла схемы.
Есть еще много вещей, которые нужно узнать о xPDO, но если вы понимаете эти 4, у вас есть прочная основа, чтобы разобраться в остальной части документации.
Пример¶
На различных страницах вы можете узнать больше о различных способах работы с данными в xPDO. Если вы больше разбираетесь в коде, приведенный ниже пример покажет вам различные взаимодействия xPDO.
if (!$modx->addPackage('education', '/path/to/model/')) {
die('Can\'t load package, try again later.');
}
// Поступить в Гарвард (или создать новую школу с таким же названием)
$school = $modx->getObject('School', ['name' => 'Harvard']);
if (!$school) {
$school = $modx->newObject('School');
$school->set('name', 'Harvard');
$school->save();
}
// Найдите 100 студентов, которые являются выпускниками и отсортируйте по фамилии
$c = $modx->newQuery('Student');
$c->where([
'school' => $school->get('id'),
'is_alumni' => true,
'start_year' => $_GET['start_year'] ?? date('Y') - 5,
]);
$c->sortby('lastname', 'ASC');
$c->limit(100);
foreach ($modx->getIterator('Student', $c) as $student) {
echo $student->get('firstname') . ' ' . $student->get('lastname') . ' started studying in ' . $student->get('start_year');
if ($graduation = $student->getOne('Graduation')) {
echo ' and graduated in ' . $graduation->get('year') . ".\n";
}
else {
echo " and has not graduated.\n";
}
}
Некоторые замечания по поводу приведенного выше кода:
- Это чисто гипотетически, нет никакого кода пакета/модели для вас, чтобы использовать.
- В строке 6 мы задаем условия для загрузки объекта
School
в виде массива. Вы также можете указать целое число, чтобы получить объект по его первичному ключу, предоставитьxPDOQuery
или предоставить необработанный SQL. Всегда четко указывайте тип условия, которое вы задаете; приведите кint
, если вы используете первичный ключ (особенно если он получен из пользовательского ввода), или предоставьте синтаксис массива. - В строке 14 мы создаем новый экземпляр
xPDOQuery
для нашей моделиStudent
. Это конструктор запросов. Имя переменной$c
, сокращенное от condition, довольно часто встречается в экземплярахxPDOQuery
.xPDOQuery
может выполнять условия, объединения, сортировку и многое другое. Для отладки сгенерированного запроса можно добавить$c->prepare(); echo $c->toSQL();
- В строке 18 мы используем данные
$_GET
без применения какой-либо очистки. К счастью для нас, xPDO использует подготовленные операторы, поэтому вы автоматически защищены от SQL-инъекций при использовании query Builder. - Линии 23, 26 и 29 используют Эхо для возврата данных. Вы никогда не должны (редко) делать это в реальном коде. В идеале вы должны предоставить данные (
$student->toArray()
) шаблону (например, chunk, с$modx->getChunk()
, который является методом modX, а не xPDO), чтобы сохранить ваши данные и разметку отдельно. - Строка 25 использует метод
getOne()
для получения связанного объекта. Отношение должно быть определено в модели. ВместоgetOne
, вы могли бы также затронуть отношения непосредственно ($student->Graduation
), который будет ленивый загружен, или (при условии, чтоGraduation
модель имеет полеstudent
, содержащий студенческий) вы могли бы использовать$modx->getObject('Graduation', ['student' => $student->get('id')])
.
Взгляните на различные подразделы, чтобы узнать больше о конкретных аспектах xPDO.
Легко понять шаблоны¶
Но xPDO-это немного больше, чем простая реализация шаблона. Это также способ абстрагирования бизнес-объектов от реальных SQL-запросов и подготовленных операторов, используемых для доступа к реляционной структуре базы данных, представляющей их, а также способ простого описания и предоставления оптимизированных реализаций объектной модели для нескольких целевых платформ баз данных.
При разработке xPDO использовались несколько паттернов проектирования, которые хорошо описаны в книге Мартина Фаулера «Архитектура корпоративных программных приложений» («Patterns of Enterprise Application Architecture»). Среди них есть следующие и не только:
- Domain Model
- Active Record
- Data Mapper
- Lazy Load
- Identity Field
- Single Table Inheritance
- Metadata Mapping
- Query Object
Перед программированием с использованием xPDO будет очено полезно ознакомиться с этими паттернами (и другими из каталога Фаулера). Понимание этих концепций поможет не только в изучении xPDO, но и многих других вещей, связанных с программированием.
Почему это было создано¶
xPDO был вдохновлен необходимостью быстро создать каркас для веб-приложения, который легко расширить в полномасштабную объектную модель, которая могла бы быть максимально оптимизирована для платформы базы данных, на которой она развертывалась, без создания зависимостей от платформы или кошмаров обслуживания. И это должно было обеспечить как можно меньший объем кода; реализация эффективной объектно-реляционной структуры персистентности в PHP требует этого.
Support the team building MODX with a monthly donation.
The budget raised through OpenCollective is transparent, including payouts, and any contributor can apply to be paid for their work on MODX.
Backers
Budget
$311 per month—let's make that $500!
Learn more