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
$280 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
$280 per month—let's make that $500!
Learn more










