modZone.ru
138 subscribers
15 photos
3 files
57 links
Канал сайта modZone.ru
Download Telegram
В коде MODX можно найти много примеров, когда нужно получить первый символ строки. Например в парсере, в зависимости от первого символа в теге элемента, определяется соответствующая логика.
$token= substr($tagName, 0, 1);

В PHP есть возможность обращаться к строке как к массиву
$token= $tagName[0];

Так проще и нагляднее.
Рубрика "Так лучше не делать"

Ещё одно наследие из далёкого PHP4. Тогда не было модификаторов доступа (public, protected, private), и названия закрытых методов начинали с нижнего подчёркивания. А так как есть инерция мышления, то даже при переходе на PHP5 такой подход остался в силе. В MODX можно найти public методы, начинающиеся с нижнего подчёркивания. В современных стандартах разработки такой подход считается плохим примером кодирования.

Кстати, так делают и в ванильном javascript. Там нет модификаторов.
Рубрика "Так лучше не делать"

В исходниках MODX можно нередко встретить такой код. Но давайте разберёмся почему это яркий пример говнокодинга.

В данном случае функция empty() возвращает или true или false. Т.е. мы уже получаем булево значение. В итоге парсер PHP видит это так -
true ? true : false;
// или так
false ? true : false;
Т.е. если true, то возвращаем true. Если false, то false. Явный перебор.

Часто попадаются такие конструкции
$var == 'value' ? true : false;
И тут первая часть возвращает булево значение. Но бывают случаи использования тернарного оператора без явного булева значения. Например, в кэш менеджере есть такая конструкция -
$results['system_settings'] = $this->generateConfig($partOptions) ? true : false;
В данном случае достаточно явно привести значение к булеву типу -
$results['system_settings'] = (bool)$this->generateConfig($partOptions);
Кто-нибудь может мне объяснить, чем сборщики скриптов на javascript принципиально лучше сборщиков на PHP? Лично я вижу только повальную моду на JS.
У них обязательная зависимость от NodeJS. Они не умеют собирать скрипты на лету. И как следствие не могут собирать их со страницы как может делать тот же MinifyX. Для меня это явные минусы. Так в чем их преимущество?
Рубрика "Так лучше не делать"

Практически все авторы компонентов для MODX складывают все свои классы в папку model, которая, исходя из названия, предназначена для классов моделей, т.е. объектов в базе данных. Классы сервисов и другие вспомогательные классы должны размещаться в отдельных папках - services, src и т.п.
Рубрика "Так лучше не делать"

Начиная с седьмой версии PHP активно двигается в сторону строгой типизации. До этого разработчикам в помощь были только статические анализаторы. MODX в этом плане выступает антипримером. На картинке выше видно, что используется строковый ключ для обращения к массиву с числовыми ключами. PHP так позволяет делать используя неявное преобразование типов. И если пробежаться по коду, то можно найти и другие примеры. Часто вместо true и false указывают 1 и 0.
curl_setopt($ch, CURLOPT_NOBODY, !empty($options['curlopt_nobody']) ? $options['curlopt_nobody'] : 0);
Иногда неявное преобразование используется в проверках
if ($foo) {...}  // А если $foo = 'false'?
В общем, старайтесь избегать неявного преобразования типов. Это вводит в заблуждение разработчиков и может приводить к ошибкам.
Рубрика "Так лучше не делать"

В MODX в условиях проверки можно часто встретить такой код. Что же тут не так? А дело в том, что эта проверка избыточна. Если заглянуть в документацию, то мы узнаем, что функция isset проверяет существование переменной. А вот что написано про функцию empty
"Проверяет, считается ли переменная пустой. Переменная считается пустой, если она не существует или её значение равно false."

Т.е. она делает то же самое, что и isset, плюс проверяет на false.

В ядре MODX таких проверок очень много -
isset($_REQUEST['ctx']) && !empty($_REQUEST['ctx'])
...
isset($source['baseUrlRelative']) && !empty($source['baseUrlRelative'])
...
isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])
...
isset($_FILES) && !empty($_FILES)
...
if ($filters && isset($filters[1]) && !empty($filters[1]))
и т.д.


Я был очень удивлен, что даже Томас Джакоби (Jako), являющийся одним из контрибьютеров MODX, не знал этого.
Уверен, многие знают библиотеку pdoTools. В основном её использование ограничивается сниппетами, входящими в библиотеку, и шаблонизатором Fenom. Но продвинутые разработчики используют ещё и API. Самые основные - это методы getChunk и runSnippet. Они не только расширяют функциональные возможности аналогичных методов MODX, включая байндинги (@INLINE, @FILE и т.д.), но и оптимизируют их.
Но не все разработчики знают, что для сниппетов добавлена возможность управления кэшированием как в тегах шаблонизатора. Т.е. для вызова некэшированного сниппета нужно перед именем указать знак "!". Это главное отличие от modX::runSnippet(), который никогда не кэширует результат. А некоторые забывают про это и в результате получают кэшированные данные.
А вот pdoTools::getChunk() безразличен к признаку кэширования. Он никогда не кэширует полученный результат.

П.С. Вообще и у шаблонизатора Fenom из pdoTools присутствует непродуманность функционала кэширования. Об этом я писал на своём сайте про сравнение шаблонизаторов.
Небольшая статья о проблеме слияния массивов в цикле.

https://modzone.ru/blog/2021/06/08/merging-arrays-in-a-loop/
Анонс.
Я закончил оптимизацию большого новостного сайта (около 200 тыс. ресурсов) и в ближайшее время планирую поделиться опытом, как удалось снизить нагрузку на сервер почти в 3 раза, ускорить отдачу страниц на порядок, увеличить скорость по Google SpeedPage с 37 до 80 (остальные 20 - это проблемы фронта).

Чтобы добиться этого пришлось подкрутить настройки, оптимизировать кэш-менеджер, доработать pdoTools и написать пару сниппетов и плагин для управления кэшем. Coming Soon.
Первая статья из цикла статей про оптимизацию больших сайтов. В ней мы поговорим о системных настройках.

https://modzone.ru/blog/2021/06/16/big-sites-optimization-p1/
Продолжение цикла статей про оптимизацию больших сайтов. На этот раз будем говорить про подходы к кэшированию ресурсов (с примерами).

https://modzone.ru/blog/2021/06/18/big-sites-optimization-p2/
Сегодня поговорим о популярной библиотеке pdoTools. Она предоставляет полный набор необходимых для разработки сайта сниппетов. Но для больших сайтов придётся её оптимизировать.

https://modzone.ru/blog/2021/06/30/pdotools-optimization/
Опытные разработчики знают, что pdoPage самый медленный сниппет из всего набора сниппетов библиотеки pdoTools. Некоторые даже от него отказываются. Но его достаточно просто оптимизировать. Как раз об этом рассказано в моей статье.

https://modzone.ru/blog/2021/07/28/pdopage-optimization/
Рубрика "Так лучше не делать"

В былые времена я принимал код MODX за образец и старался перенимать используемые в нём подходы и приёмы. И вот такой код
$this->fileHandler->modx->getCacheManager();

казался проявлением гибкости.

Но стоило только выглянуть за пределы MODX, в мир современной разработки, как оказалось, что такой подход считается вери бэд. Потому как понятный, хорошо поддерживаемый и легко тестируемый код должен следовать шаблону "Низкая связанность" (Low Coupling), описанный в законе Деметры. Т.е. объект не должен иметь зависимость от третьих объектов. Сегодня это обязательное требование в разработке.

https://habr.com/ru/post/319652/
Смотришь на этот код и думаешь, ошибок вроде нет, но какой смысл в этой проверке, непонятно.
На днях на сайте сообщества была опубликована статья про управление сессиями в MODX. Автор предлагает более мощный и гибкий вариант менеджера сессий. Я решил предложить альтернативный подход для тех, кому достаточно только ограничить создание сессий для ботов.

https://modzone.ru/blog/2021/08/01/disabling-sessions-for-bots/
В шаблонизаторе Fenom библиотеки pdoTools есть объект $_modx, заменяющий реальный объект $modx. Сделано это, со слов автора, для безопасности, чтобы злой контент-менеджер не нахулиганил безобразия. Лично мне данная проблема кажется немного надуманной. Потому как, если вы пустили пользователя в админку, то безопасность сайта уже под угрозой. А с установленным pdoTools контент-менеджер может легко превратиться в админа сайта.

Ну а про $_modx можно сказать, что он нужен если только для удобства (хотя это тоже спорный вопрос). Ведь опытный разработчик легко узнает из документации Fenom, что есть такая системная переменная $.globals, которая является ссылкой на массив $GLOBALS, содержащий объект $modx.

В общем, вооружен, значит предупреждён. Или наоборот ;)

https://github.com/fenom-template/fenom/blob/master/docs/ru/syntax.md#%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5
Как и обещал, выпустил статью, в которой разобрал известные мне уязвимости, которые автор pdoTools посчитал неопасными. Лично я считаю их критическими, поэтому предлагаю варианты их устранения.

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

https://modzone.ru/blog/2021/08/06/closing-vulnerabilities-of-pdotools/
В продолжении темы про безопасность...
Любой контент-менеджер может получить значение любой системной настройки - [[++mail_smtp_pass]]. Например, логины и пароли к различным сервисам. Поэтому нужно понимать, что если уж вы дали доступ к сайту человеку, то вы должны быть в нём максимально уверены. Так как всё зависит от его порядочности.
Наглядная демонстрация как с помощью функционала файловых элементов pdoTools можно легко вывести содержимое любого файла на странице.