Про xPDO
Эта заметка назревала уже очень давно, полгода минимум. Вокруг замечательного MODX Revolution сломано много копий. Ходят слухи, что он «тормозной», «прожорливый» и «неповоротливый». И главным виновником всегда называют xPDO.
Конечно, это чушь и цель заметки — развенчание мифов. Закрыть, наконец, вопрос с «тормозами» и «прожорливостью». Показать, насколько Revolution удобен и гибок, что он позволяет работать как через ORM xPDO, так и без него — через обычный PDO.
Вы можете работать с MODX разными путями, вам не навязывают xPDO. Не нравится — не пользуйтесь, пишите вручную SQL запросы.
Со вступлением покончено, идем дальше.
Для того, чтобы разобраться с вопросом нам потребуется файл тестирования. Создаем, например, test.php в корне сайта и пишем туда вот это:
Запускаем файл, и видим:
Данные цифры реальны только при включенном php-apc. Если отключить — потребление памяти и времени будет в 2 раза выше:
Все команды мы добавляем в этот тестовый файл и в интересующем месте вызываем getStatus('текстовая метка');.
Как принято обращаться к Mysql на PHP? Очень просто:
Понятно, что это устарелая методика. Понятно, что только самоубийца будет сейчас писать такие запросы, ибо вы обязательно пропустите пару-тройку инъекций и ваш сайт поломают. Да и муторно это. Поэтому, умные люди придумали PDO.
Как через него можно работать в MODX? Еще проще:
Нужно знать, что тот запрос написан для mySQL и с MsSQL, например, может и не работать из-за разницы этих БД. Понятно, что язык там один — SQL, но есть разные ньюансы. А MODX поддерживает MsSQL.
Как же написать наш супер-пупер компонент с разными крутыми запросами, чтобы работало сразу на всех БД, которые умеет MODX? А вот тут нам на помощь приходит xPDO.
Нужно понимать, что разница во времени обусловлена генерацией запроса для MySQL методом $modx->newQuery(), что не влияет на скорость выборки. Это значит, что если выбирать много данных, то разница небольшая.
При этом, конечно, вы можете и сами написать драйвер для любой БД и подключить его в свой код. Вы можете сделать корпоративное веб-приложение, к примеру, для госучреждений, которые традиционно работают с целым зоопарком различного ПО. И оно будет поддерживать все БД, которые вам нужны — запросы не придется переписывать каждый раз.
То есть, наш запрос стал гораздо более универсальным и абстрактным. Это, конечно, кушает больше ресурсов, но вас никто не заставляет делать именно так. Есть PDO, его никто не спрятал — пишите все запросы на нем и у вас будет мега-скорость.
Подчеркиваю красным — MODX не заставляет вас использовать свой xPDO, это только лично ваш выбор. Вы можете писать скрипты для любых ситуаций через чистый PDO и радоваться скорости. Однако, ваши запросы не будут универсальны, но это надо далеко не всем.
Первую причину мы уже выяснили — это универсальность. Вы пишите свой код и не заморачиваетесь, с какими БД он будет работать.
Остальные причины — это удобство, безопасность и целостность данных.
Конечно, за удобство нужно платить, и в данном случае мы платим производительностью. А за автоматическую коробку передач на автомобилях мы платим повышенным потреблением бензина, масла и более дорогими гарантийными техосмотрами. То есть, рублем.
Лично я придерживаюсь мнения, что серверы и компютеры ушли настолько вперед, что экономить на ОЗУ или процессорах просто нерентабельно. Время программиста стоит гораздо дороже.
Сколько вы тратите на хостинг в месяц? Лично я, около 1000 рублей — это 2 часа моей работы на заказ. Поэтому, каждый решает для себя, что лучше — писать код долго, муторно и экономить на железе, или же быстро и удобно — но с дополнительными тратами на сервер.
Напоминаю, что в MODX Revolution возможны оба варианта — выбор за вами. Оптимальный, как обычно, посередине.
Например, я после разработки сайта оптимизирую его узкие места, в том числе, переписывая работу с БД на PDO, где нужно.
Итак, в чем же удобство? А удобство в том, что xPDO предоставляет нам наши данные в виде объектов, с различными методами.
Получая ресурс через $modx->getObject(), вы не просто достаете данные из таблицы — вы получаете экземпляр класса modResource, который обладает уникальными методами, при этом наследуя дополнительные от родителя — xPDOSimpleObject, типа set(), get(), save(), remove(), toArray().
Об этом всегда нужно помнить.
Например:
А потом почитайте подробнейшее руководство по работе с объектами и их связями на английском или на русском. Прикинули, как работать со всем этим багатствов ручками, прописывая постоянные SELECT, UPDATE, INSERT и DELETE? Проще сразу застрелиться.
С xPDO вы поднимаетесь на совершенно иной уровень работы. Если посмотреть в исходники MODX, то можно увидеть, сколько там различных проверок и наворотов при, казалось бы, простых действиях. Например, при изменении какого-то поля ресурса, присланные данные приводятся к виду, который требует модель это объекта. Если вы пришлете в поле parent строку «15», то она превратится в целое 15, понятно?
Внимательная система делает огромное количество работы за вас, предоставляя вам возможность просто творить, не думая о типах данных и SQL инъекциях. Вы мыслите иными категориями: объектом, его методами и связями с другими объектами.
При удалении ресурса будут удалены все объекты, подчиненные ему, типа значений ТВ параметров. Если вы удаляете контекст — будут удалены все ресурсы и значения ТВ параметров этого контекста. Вам не нужно за этим следить самому.
Вот вам безопасность и целостность данных. Если вы правильно написали модель своего расширения, расписали все связи — xPDO сам позаботится о актуальности данных. Понятно, что в объектах MODX все прописано как надо.
Это и есть ORM, если кратко. Методы getObject(), getCollection() и другие нужно применять не от балды, а строго осознавая, что сейчас вам нужны именно объекты, а не просто данные из таблицы БД.
Например, вы знаете, что вместо getCollection() можно применять getIterator(), который достает не сразу все подходящие объекты, за раз, а по очереди — в цикле? Экономия памяти, между прочим.
Если вам нужно вывести 100 товаров на странице, очевидно, что лучше использовать PDO — будет быстрее и вы не производите никаких манипуляций, только показываете содержимое таблицы БД. А вот если нужно выбрать 10 ресурсов и изменить у них родителя — тут удобнее xPDO.
То есть, нужно понимать, что именно вы делаете.
MODX Revolution, как и xPDO — это огромный чемодан с инструментами на все случаи жизни. Это фреймворк, который по старой привычке косит под CMS. И конечный результат зависит только от умений и знаний программиста.
Хотите мега скорости — используйте PDO, или даже другой фреймворк. Хотя, чистый PHP будет гораздо быстрее. Но даже он не сравнится со статичным HTML. Намек ясен?
Хотите удобство — покупайте сервер получше и пишите с удовольствием, оперируя объектами и прибегая к PDO в нагруженных задачах, типа одновременной выборки 1000 ресурсов.
Подходить к ORM с мерками прямых запросов в БД просто нельзя — это разные вещи, для разных задач. Вы не просто работаете с БД — вы работаете с объектом своей системы, который имеет связи с другими объектами.
MODX кушает от 2,5 до 6 мегабайт ОЗУ, и тратит 2-4 десятитысячных секунды на инициализацию. Все остальное время и память — на вашей совести.
Надеюсь, после этой заметки у многих прояснится в голове.
Конечно, это чушь и цель заметки — развенчание мифов. Закрыть, наконец, вопрос с «тормозами» и «прожорливостью». Показать, насколько Revolution удобен и гибок, что он позволяет работать как через ORM xPDO, так и без него — через обычный PDO.
Вы можете работать с MODX разными путями, вам не навязывают xPDO. Не нравится — не пользуйтесь, пишите вручную SQL запросы.
Со вступлением покончено, идем дальше.
Подготовка
Для того, чтобы разобраться с вопросом нам потребуется файл тестирования. Создаем, например, test.php в корне сайта и пишем туда вот это:
// Функция для вывода времени и потребления памяти
function getStatus($text = '') {
global $memory_start;
static $microtime_start = null;
if ($microtime_start === null) {$time = 0;}
else {$time = microtime(true) - $microtime_start;}
$memory = memory_get_usage();
if (!empty($memory_start)) {
$memory2 = number_format(($memory - $memory_start) / 1024, 2,","," ");
$memory2 = " ($memory2 Кб.)";
} else {$memory2 = '';}
$memory = number_format($memory / 1024, 2,","," ");
echo $text.'
<small>время: '.$time.' сек.
память: '.$memory.' Кб.'.$memory2.'</small>
';
$microtime_start = microtime(true);
}
getStatus('Старт');
// Подключаем MODX
define('MODX_API_MODE', true);
require 'index.php';
getStatus('MODX подключен');
// Включаем обработку ошибок
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
getStatus('MODX готов к работе');
// Потребление памяти на момент готовности MODX
$memory_start = memory_get_usage();
Да, мы будем работать в MODX_API_MODE, чтобы избежать нагруженных шаблонов и прочей возможной шелухи на рабочем сайте. Нас ведь интересует работа фреймворка, да?Запускаем файл, и видим:
Старт время: 0 сек. память: 312,00 Кб. MODX подключен время: 0.017445087432861 сек. память: 2 510,34 Кб. MODX готов к работе время: 0.00021815299987793 сек. память: 2 520,45 Кб.Все понятно? Запуск и подготовка к работе всего MODX Revolution занимает 2,5 мегабайта памяти и 2 десятитысячных секунды. Все остальное — это время, которое тратит программист.
Данные цифры реальны только при включенном php-apc. Если отключить — потребление памяти и времени будет в 2 раза выше:
Старт время: 0 сек. память: 324,34 Кб. MODX подключен время: 0.037600021362305 сек. память: 5 038,35 Кб. MODX готов к работе время: 0.00060105323791504 сек. память: 5 090,96 Кб.Все дальнейшие цифры и тесты я буду приводить с php-apc. Это фактически стандарт для хостингов, он включен по умолчанию на MODX Cloud и, возможно, войдет в ядро PHP 6.
Все команды мы добавляем в этот тестовый файл и в интересующем месте вызываем getStatus('текстовая метка');.
3 способа работы с БД
Как принято обращаться к Mysql на PHP? Очень просто:
mysql_connect('localhost','root','rootpassword');
mysql_select_db('modx');
$sql = "SELECT * FROM `modx_site_content` WHERE id > 0 LIMIT 100";
$res = mysql_query($sql);
$arr = array();
while ($row = mysql_fetch_assoc($res)) {
$arr[] = $row;
}
getStatus('Выборка '.count($arr).' ресурсов стандартными функциями Mysql');
Вот так мы получили массив с записями из таблицы. Не очень удобно, да? Зато офигенно быстро: 0,0023038387298584 сек. и 3 873,64 Кб. (1 019,61 Кб.). В скобочках память, скушанная именно этой операцией. Без скобочек — общая, львинную долю которой отожрал MODX.Понятно, что это устарелая методика. Понятно, что только самоубийца будет сейчас писать такие запросы, ибо вы обязательно пропустите пару-тройку инъекций и ваш сайт поломают. Да и муторно это. Поэтому, умные люди придумали PDO.
Как через него можно работать в MODX? Еще проще:
$sql = "SELECT * FROM {$modx->getTableName('modResource')} WHERE id > ? LIMIT 100";
$q = $modx->prepare($sql);
$q->execute(array(0));
$arr = $q->fetchAll(PDO::FETCH_ASSOC);
getStatus('Выборка '.count($arr).' ресурсов через PDO');
Результаты: 0,0021560192108154 сек. и 3 989,02 Кб. (1 134,99 Кб.). Разница в районе погрешности, мы так же пишем прямые запросы в БД, ограниченные только нашей фантазией. Однако уже видно прелести PDO: более простой и удобный код и подготовленные выражения, которые защитят нас от инъекций.Нужно знать, что тот запрос написан для mySQL и с MsSQL, например, может и не работать из-за разницы этих БД. Понятно, что язык там один — SQL, но есть разные ньюансы. А MODX поддерживает MsSQL.
Как же написать наш супер-пупер компонент с разными крутыми запросами, чтобы работало сразу на всех БД, которые умеет MODX? А вот тут нам на помощь приходит xPDO.
$q = $modx->newQuery('modResource');
$q->where(array('id:>' => 0));
$q->limit('100');
if ($q->prepare() && $q->stmt->execute()) {
$arr = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
}
getStatus('Выборка '.count($arr).' ресурсов через xPDO');
Результаты: 0.00597095489502 сек. и 10 845,90 Кб. (2 398,56 Кб.). Ресурсов ушло больше в 2 раза, но наш запрос теперь и поддерживает 2 базы данных (Mysql и MsSQL), а если кудесники MODX добавят поддержку других БД — то newQuery построит и подготовит запрос и для них.Нужно понимать, что разница во времени обусловлена генерацией запроса для MySQL методом $modx->newQuery(), что не влияет на скорость выборки. Это значит, что если выбирать много данных, то разница небольшая.
Выборка | PDO | xPDO |
---|---|---|
500 ресурсов | 0.011471033096313 сек. 7 083,84 Кб. (3 994,36 Кб.) | 0.017184972763062 сек. 7 849,96 Кб. (4 759,93 Кб.) |
1000 ресурсов | 0.037826061248779 сек. 11 446,41 Кб. (8 357,57 Кб.) | 0.046993970870972 сек. 12 465,15 Кб. (9 375,13 Кб.) |
При этом, конечно, вы можете и сами написать драйвер для любой БД и подключить его в свой код. Вы можете сделать корпоративное веб-приложение, к примеру, для госучреждений, которые традиционно работают с целым зоопарком различного ПО. И оно будет поддерживать все БД, которые вам нужны — запросы не придется переписывать каждый раз.
То есть, наш запрос стал гораздо более универсальным и абстрактным. Это, конечно, кушает больше ресурсов, но вас никто не заставляет делать именно так. Есть PDO, его никто не спрятал — пишите все запросы на нем и у вас будет мега-скорость.
Подчеркиваю красным — MODX не заставляет вас использовать свой xPDO, это только лично ваш выбор. Вы можете писать скрипты для любых ситуаций через чистый PDO и радоваться скорости. Однако, ваши запросы не будут универсальны, но это надо далеко не всем.
Зачем еще нужен xPDO?
Первую причину мы уже выяснили — это универсальность. Вы пишите свой код и не заморачиваетесь, с какими БД он будет работать.
Остальные причины — это удобство, безопасность и целостность данных.
Конечно, за удобство нужно платить, и в данном случае мы платим производительностью. А за автоматическую коробку передач на автомобилях мы платим повышенным потреблением бензина, масла и более дорогими гарантийными техосмотрами. То есть, рублем.
Лично я придерживаюсь мнения, что серверы и компютеры ушли настолько вперед, что экономить на ОЗУ или процессорах просто нерентабельно. Время программиста стоит гораздо дороже.
Сколько вы тратите на хостинг в месяц? Лично я, около 1000 рублей — это 2 часа моей работы на заказ. Поэтому, каждый решает для себя, что лучше — писать код долго, муторно и экономить на железе, или же быстро и удобно — но с дополнительными тратами на сервер.
Напоминаю, что в MODX Revolution возможны оба варианта — выбор за вами. Оптимальный, как обычно, посередине.
Например, я после разработки сайта оптимизирую его узкие места, в том числе, переписывая работу с БД на PDO, где нужно.
Итак, в чем же удобство? А удобство в том, что xPDO предоставляет нам наши данные в виде объектов, с различными методами.
Получая ресурс через $modx->getObject(), вы не просто достаете данные из таблицы — вы получаете экземпляр класса modResource, который обладает уникальными методами, при этом наследуя дополнительные от родителя — xPDOSimpleObject, типа set(), get(), save(), remove(), toArray().
Об этом всегда нужно помнить.
Например:
$res = $modx->getObject('modResource', 1); // Получаем объект ресурса #1
print_r($res->toArray()); // Печатаем данные самого объекта
echo $res->getTVValue('tvname'); // Выводим данные связанного ТВ параметра по его имени
$res->set('pagetitle', 'Страница 55'); // Меняем заголовок страницы
$res->save(); // Фиксируем изменения
$res->remove(); // Удаляем ресурс
Попробуйте переписать это на PDO, как будет время и сравните, сколько у вас выйдет строк.А потом почитайте подробнейшее руководство по работе с объектами и их связями на английском или на русском. Прикинули, как работать со всем этим багатствов ручками, прописывая постоянные SELECT, UPDATE, INSERT и DELETE? Проще сразу застрелиться.
С xPDO вы поднимаетесь на совершенно иной уровень работы. Если посмотреть в исходники MODX, то можно увидеть, сколько там различных проверок и наворотов при, казалось бы, простых действиях. Например, при изменении какого-то поля ресурса, присланные данные приводятся к виду, который требует модель это объекта. Если вы пришлете в поле parent строку «15», то она превратится в целое 15, понятно?
Внимательная система делает огромное количество работы за вас, предоставляя вам возможность просто творить, не думая о типах данных и SQL инъекциях. Вы мыслите иными категориями: объектом, его методами и связями с другими объектами.
При удалении ресурса будут удалены все объекты, подчиненные ему, типа значений ТВ параметров. Если вы удаляете контекст — будут удалены все ресурсы и значения ТВ параметров этого контекста. Вам не нужно за этим следить самому.
Вот вам безопасность и целостность данных. Если вы правильно написали модель своего расширения, расписали все связи — xPDO сам позаботится о актуальности данных. Понятно, что в объектах MODX все прописано как надо.
Это и есть ORM, если кратко. Методы getObject(), getCollection() и другие нужно применять не от балды, а строго осознавая, что сейчас вам нужны именно объекты, а не просто данные из таблицы БД.
Например, вы знаете, что вместо getCollection() можно применять getIterator(), который достает не сразу все подходящие объекты, за раз, а по очереди — в цикле? Экономия памяти, между прочим.
Если вам нужно вывести 100 товаров на странице, очевидно, что лучше использовать PDO — будет быстрее и вы не производите никаких манипуляций, только показываете содержимое таблицы БД. А вот если нужно выбрать 10 ресурсов и изменить у них родителя — тут удобнее xPDO.
То есть, нужно понимать, что именно вы делаете.
Заключение
MODX Revolution, как и xPDO — это огромный чемодан с инструментами на все случаи жизни. Это фреймворк, который по старой привычке косит под CMS. И конечный результат зависит только от умений и знаний программиста.
Хотите мега скорости — используйте PDO, или даже другой фреймворк. Хотя, чистый PHP будет гораздо быстрее. Но даже он не сравнится со статичным HTML. Намек ясен?
Хотите удобство — покупайте сервер получше и пишите с удовольствием, оперируя объектами и прибегая к PDO в нагруженных задачах, типа одновременной выборки 1000 ресурсов.
Подходить к ORM с мерками прямых запросов в БД просто нельзя — это разные вещи, для разных задач. Вы не просто работаете с БД — вы работаете с объектом своей системы, который имеет связи с другими объектами.
MODX кушает от 2,5 до 6 мегабайт ОЗУ, и тратит 2-4 десятитысячных секунды на инициализацию. Все остальное время и память — на вашей совести.
Надеюсь, после этой заметки у многих прояснится в голове.
Комментарии: 15
Красава ))
Привет, Василий!
Вопрос не совсем по теме именно xPDO, скорее по APCCache. Правильно ли я понимаю, что если на сервере доступен APC и в настройках revo указан нужный обработчик (cache.xPDOAPCCache), то скрипт (сниппет) корректно работающий с xPDOFileCache будет работать и с APC?
Проблема собственно вот в чем — есть интернет-магазин на шаред хостинге, php5.3 + APC. Используется modx revo+ shopkeeper. Изначально про обработчики не знал, использовался обычный файл кеш, но работало все неправильно (корзина не обновлялась, не добавлялись товары) до тех пор, пока я не прописал в htaccess php_flag apc.cache_by_default Off. Заработало, но временами страница загружалась долго (причем страница с древовидным меню, ибо вывод товаров происходит сниппетом, не использующем xPDO вообще).
Потом наткнулся на вашу статью, прописал обработчик, убрал флаг в htaccess. Грузиться все стало заметно быстрее, но вот корзина по-прежнему не хочет работать как надо. Сейчас apc.cache_by_default выключено, но обработчик прописан для apc. Нужны ли какие-то доработки в скрипт чтобы он работал с cache by default ON? Или может быть поработать с apc.filters и каким-то образом прописать туда, что нужно кешировать а что нет (как это сделать — это следующий вопрос)))
php знаю хреновато, хотя базовые навыки ООП и программирования вообще есть, поэтому и требуется наводка более опытных товарищей)
Заранее спасибо!
Вопрос не совсем по теме именно xPDO, скорее по APCCache. Правильно ли я понимаю, что если на сервере доступен APC и в настройках revo указан нужный обработчик (cache.xPDOAPCCache), то скрипт (сниппет) корректно работающий с xPDOFileCache будет работать и с APC?
Проблема собственно вот в чем — есть интернет-магазин на шаред хостинге, php5.3 + APC. Используется modx revo+ shopkeeper. Изначально про обработчики не знал, использовался обычный файл кеш, но работало все неправильно (корзина не обновлялась, не добавлялись товары) до тех пор, пока я не прописал в htaccess php_flag apc.cache_by_default Off. Заработало, но временами страница загружалась долго (причем страница с древовидным меню, ибо вывод товаров происходит сниппетом, не использующем xPDO вообще).
Потом наткнулся на вашу статью, прописал обработчик, убрал флаг в htaccess. Грузиться все стало заметно быстрее, но вот корзина по-прежнему не хочет работать как надо. Сейчас apc.cache_by_default выключено, но обработчик прописан для apc. Нужны ли какие-то доработки в скрипт чтобы он работал с cache by default ON? Или может быть поработать с apc.filters и каким-то образом прописать туда, что нужно кешировать а что нет (как это сделать — это следующий вопрос)))
php знаю хреновато, хотя базовые навыки ООП и программирования вообще есть, поэтому и требуется наводка более опытных товарищей)
Заранее спасибо!
Для полноты картины не хватает данных о выводе через rowboat
Ни разу не пользовался.
Читал, вроде полезная штука, но руки так и не дошли. Проще свой скриптик накидать за 5 минут.
Читал, вроде полезная штука, но руки так и не дошли. Проще свой скриптик накидать за 5 минут.
«Тому парню с того форума» не закидывали статью эту? Думаю, он сдулся бы вконец.
Хотя, конечно. справедливости ради я бы и сам задал вопрос, единственный в его перлах существенный. Действительно, а почему именно жёстко вшили xPDO, а не факультативно? Мне именно любопытно, в чём могла быть серемяга (точно знаю, что разрабы MODX не идиоты, как тот парень думает, и понимали, что делают (изначально не исключаю, что для таких вещей факультатив нереален (например, по безопасности) и, следовательно, надо жёстко вшивать)).
Хотя, конечно. справедливости ради я бы и сам задал вопрос, единственный в его перлах существенный. Действительно, а почему именно жёстко вшили xPDO, а не факультативно? Мне именно любопытно, в чём могла быть серемяга (точно знаю, что разрабы MODX не идиоты, как тот парень думает, и понимали, что делают (изначально не исключаю, что для таких вещей факультатив нереален (например, по безопасности) и, следовательно, надо жёстко вшивать)).
Того парня, как нашкодившего котенка, я носом тыкаю в эту заметку — он все равно делает вид, что ничего не видел.
А объяснение простое, и очевидное — без xPDO не было бы Revolution вообще. Был бы Evolution с обвесами, но не более.
Чем глубже разбираюсь в Revo — тем больше, простите, охуеваю от возможностей.
К примеру, сейчас мы пишем каменты к ресурсу класса не modResource, а Ticket. Среди прочего, отличается он еще и тем, что в любом случае при получении контента превращает теги MODX в html-сущности.
А при выводе контента у себя на странице — прогоняет его через Jevix, не только фильтруя, но и типографируя.
То есть, нефильтрованным контент этого ресурса можно получить только через прямой запрос в БД. Есть еще гора отличий в создании\изменении такого ресурса, и в админке.
Однако, я про них не думаю, ибо создал один раз этот новый класс ресурса — и дальше он работает по моим правилам, наследуя остальное от родителя modResource, а тот от xPDOSimpleObject, а потом xPDOObject… Ну вы поняли.
Как, ну как это сделать без ОРМ?! Короче, такой вопрос могут задавать только те люди, которые в Рево не ушли дальше использования стандартных сниппетов в Рево.
А объяснение простое, и очевидное — без xPDO не было бы Revolution вообще. Был бы Evolution с обвесами, но не более.
Чем глубже разбираюсь в Revo — тем больше, простите, охуеваю от возможностей.
К примеру, сейчас мы пишем каменты к ресурсу класса не modResource, а Ticket. Среди прочего, отличается он еще и тем, что в любом случае при получении контента превращает теги MODX в html-сущности.
А при выводе контента у себя на странице — прогоняет его через Jevix, не только фильтруя, но и типографируя.
То есть, нефильтрованным контент этого ресурса можно получить только через прямой запрос в БД. Есть еще гора отличий в создании\изменении такого ресурса, и в админке.
Однако, я про них не думаю, ибо создал один раз этот новый класс ресурса — и дальше он работает по моим правилам, наследуя остальное от родителя modResource, а тот от xPDOSimpleObject, а потом xPDOObject… Ну вы поняли.
Как, ну как это сделать без ОРМ?! Короче, такой вопрос могут задавать только те люди, которые в Рево не ушли дальше использования стандартных сниппетов в Рево.
На всякий случай, я не имел ввиду, что можно делать такие и этому подобные кульбиты без ОРМ :0)
"… без xPDO не было бы Revolution вообще. Был бы Evolution с обвесами, но не более." — а и не надо, был бы много более крутой Evo, не без доли здравого смысла сказал бы «тот парень с того форума». Однако, моё предположение ниже (если оно ± верное), основанное на Ваших знаниях = перефразированный Ваш ответ «добивает хлопца».
Итак, суть вопроса «почему нельзя подключать/не подключать xPDO».
Я так понимаю потому, что без жёсткой вшивки невозможно и/или неоправданно сложно реализовать ту изрядную часть возможностей, которые доступны, если вшивка жёсткая = а без этого был бы неплохо расширяющий возможности системы довесок, расширение, не более того. => дабы существенно увеличить возможности и было принято решение о жёсткой вшивке xPDO.
Если это ± так, «тот парень с того форума» окончательно «кончился», ибо ± вполне чёткий и понятный ответ на его единственно потенциально существенный и даже ключевой вопрос достаточно полон.
П.С.
Повторюсь, это так только, если в целом я правильно понял Вас.
П.П.С.
Для меня этот момент важен, т.к. не только «тот парень...» гнёт такую линию «последним рубежом обороны», а я особо ничего и ответить не мог.
"… без xPDO не было бы Revolution вообще. Был бы Evolution с обвесами, но не более." — а и не надо, был бы много более крутой Evo, не без доли здравого смысла сказал бы «тот парень с того форума». Однако, моё предположение ниже (если оно ± верное), основанное на Ваших знаниях = перефразированный Ваш ответ «добивает хлопца».
Итак, суть вопроса «почему нельзя подключать/не подключать xPDO».
Я так понимаю потому, что без жёсткой вшивки невозможно и/или неоправданно сложно реализовать ту изрядную часть возможностей, которые доступны, если вшивка жёсткая = а без этого был бы неплохо расширяющий возможности системы довесок, расширение, не более того. => дабы существенно увеличить возможности и было принято решение о жёсткой вшивке xPDO.
Если это ± так, «тот парень с того форума» окончательно «кончился», ибо ± вполне чёткий и понятный ответ на его единственно потенциально существенный и даже ключевой вопрос достаточно полон.
П.С.
Повторюсь, это так только, если в целом я правильно понял Вас.
П.П.С.
Для меня этот момент важен, т.к. не только «тот парень...» гнёт такую линию «последним рубежом обороны», а я особо ничего и ответить не мог.
Авторы MODX мне не рассказывали, почему они решили именно так, но копаясь во внутренностях их системы — я не представляю, как можно иначе.
Упертым баранам давайте ссылку на эту заметку — тут показано, как быстро работать с БД, без ненавистного ОРМ.
Кому кажется долгим сама инициализация ядра MODX — дорога в чистый php или еще куда подальше.
Упертым баранам давайте ссылку на эту заметку — тут показано, как быстро работать с БД, без ненавистного ОРМ.
Кому кажется долгим сама инициализация ядра MODX — дорога в чистый php или еще куда подальше.
Скажите, пожалуйста, а xPDO может выполнить UPDATE или DELETE — запрос? Никак не получается найти живой пример. Я хотел написать скрипт, который бы массово менял значения полей в БД, но в итоге решение было таким:
$q=$modx->newQuery('modResource');
$q->select(array(
'id',
'content'
)
);
$results = $modx->getCollection('modResource', $q);
foreach ($results as $r)
{
$newcontent = '';
$temp = explode('[~',$r->content);
if (count($temp) > 1)
{
$newcontent = str_replace('[~','[[~',$r->content);
$newcontent = str_replace('~]',']]',$newcontent);
$sql = "UPDATE modx_site_content SET content = '".$newcontent."' WHERE id = '".$r->id."'";
$query = $modx->prepare($sql);
$query->execute();
}
}
посоветуйте пожалуйста как зделать выборку с таблицы БД чтобы она отображалась в выпадающемся списке
в место масива
в место масива
Cabinets.combo.Region = function(config) {
config = config || {};
Ext.applyIf(config,{
store: new Ext.data.ArrayStore({
id: 0
,fields: ['region','display']
,data: [
['MB','Megabyte']
,['GB','Gigabyte']
,['TB','Terabyte']
,['PB','Petabyte']
,['EB','Exabyte']
,['ZB','Zettabyte']
,['YB','Yottabyte']
]
})
,mode: 'local'
,displayField: 'display'
,valueField: 'region'
});
Cabinets.combo.Region.superclass.constructor.call(this,config);
};
Ext.extend(Cabinets.combo.Region,MODx.combo.ComboBox);
Ext.reg('cabinets-combo-region',Cabinets.combo.Region);
Никак не пойму, как подсунуть xPDO UPPER(), когда пишем в JSON формате наримр аот сдесь:
$params['where']='{"longtitle:LIKE": "%'.$str_upper.'%"}';
$result.="<table id=\"table\" border=\"1\" width=\"100%\">".$modx->runSnippet('getPage', $params);
Зачем?
MODX создаёт регистронезависимые таблицы, по умолчанию.
Ну а вообще, в where можно указывать чистый SQL:
MODX создаёт регистронезависимые таблицы, по умолчанию.
Ну а вообще, в where можно указывать чистый SQL:
&where=`["UPPER(longtitle) LIKE '%ЗНАЧЕНИЕ%'"]`
Да вот чёрт меня дернул при установке выставить UTF8_bin. А переконвертировать в UTF8_general_ci боязно, вдруг чего пропадёт. Жалко.
Ничего не пропадёт, если сделать сначала бэкап таблицы.
А в нынешнем состоянии у тебя даже имена чанков и сниппетов будут от регистра зависить.
А в нынешнем состоянии у тебя даже имена чанков и сниппетов будут от регистра зависить.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.