Вольный и дополненный перевод https://drupal.stackexchange.com/questions/2509/what-are-the-downsides-o...
На форуме некоторые товарищи, иногда рекомендуют для решения задачи использовать встроенный в ядро PHP фильтр, или Views PHP. Никогда так не делайте! И вот почему:
- Данный код пишется в базу, поэтому его нельзя будет отследить через систему контроля версий, например git. (если вы не используете систему контроля версий в разработке - это тоже плохо).
- Поля с php-фильтром не кэшируются.
- Код в php-фильтре выполняется через eval(). Код через eval работает медленнее, не кэшируется opcache-м, а на некоторых хостингах eval может быть отключен из соображений безопасности.
- Не информативные сообщения об ошибках. Что-то типа error in eval() on line 4. Где этот кусок кода, что с ним делать?
- Проблемы с обновлением модулей. Обновление модуля - и у вас куча ошибок, которые сложно найти и исправить.
- Сложно писать и поддерживать такой код. В обычном textfield - нет форматирования как в IDE, да и шрифт не моноширинный. Копировать туда-обратно тоже заколебаться можно.
- Человеческий фактор. Всегда существует возможность ошибки в конфигурации, которая позволит не доверенным пользователям заюзать php-фильтр. ОЙ!
- Безопасность в целом. Любой сайт могут взломать, но присутствие на сайте php-фильтра может сделать последствия взлома гораздо тяжелее. XSS, SQL-инъекция - и вот вас уже shell прямо в базе.
- Сложности деплоя. Нельзя просто обновить файлы на сервере. Надо лезть в админку, и копипастить код в нужные места. Хотя обычно в PHP-фильтр пишут прямо на продакте. Не стоит работать на продакте.
- Повышается цена ошибки. Одна небольшая опечатка в сквозном блоке - и всё пропало, шеф.
- Многие разработчики высказываются против использования php-фильтра. Например: пользователь Semantics в своей записи в блоге высказывался против PHP-фильтра ещё в 2013-м (!) году.
Хорошо, PHP-фильтр использовать не стоит. А что же тогда делать?
- Через template_preprocess хуки.
- Можно создать свой токен и вставлять его с помощью token_filter
- Можно создавать вычисляемые поля с помощью computed_field. Этот модуль даже сам подскажет вам, какое название функции использовать.
- Если используется Display Suite - можно написать своё Display Suite поле
- Ещё варианты, тысячи их! В зависимости от задачи.
Комментарии
У меня есть своя более короткая версия:
Есть только две причины использовать php filter - глупость и лень.
И в обоих случаях, заниматься разработкой вам не стоит.
"5. Проблемы с обновлением модулей. Обновление модуля - и у вас куча ошибок, которые сложно найти и исправить." - голословный бред же, ну что за фигня то?
Пример из жизни - обновилась мажорная версия модуля, потерялась обратная совместимость. Какие-то умельцы вставили PHP-код в панели, для встраивания Яндекс.карт на НЕКОТОРЫЕ страницы. При обновлении модуля - эти страницы больше не открываются. Вот было весело переписывать их все искать и переводить на нормальный код.
Вот бы если в computed_field они бы это написали - проблем бы не было. Ой. Или бы ли бы. Ты же советуешь этот механизм, так ведь?
В той ситуации надо было написать Ctools Custom Content Type - совершенно хрестоматийный случай их применения.
А что касается компьютэд филд, так по мне этот модуль та ещё галдэша. Лучше высчитать нужные поля в hook_entity_presave
Да кто спорит, что есть разные варианты. Только бесит, что какое то фанатье упёртое считает, что один из вариантов неправилен, потому что слишком прост( а на деле других причин тут не просматривается).
Ведь если так все просто - вписать пару строк кода в php-фильтр в виде - то что ж я за профи, мне надо написать модуль для решения элементарной задачи, а php-фильтр я не могу использовать, потому что я такой крутой.
Вот такой подход вызывает рвоту.
ОХРЕНЕТЬ!! А в computed_field чем исполняется код по-твоему? Святым духом? Да там eval ужасный выполняет код, аллё.
Нельзя использовать php-фильтр, потому что там ужасный eval - юзайте computed_field потому что там хороший eval? Тьфу блин, а выглядело так что ты изучил вопрос
http://cgit.drupalcode.org/computed_field/tree/computed_field.module#n463
УПС чувак.
Что упс то? Eval не видим?
<?php
if (function_exists($compute_func)) {
$compute_func($entity_field, $entity_type, $entity, $field, $instance, $langcode, $items);
}
?>
В своем модуле, определяется функция, которая называется, например, computed_field_field_rating_current_compute. В данной функции и происходит собственно вычисление, без всякого eval.
Ты дураками то всех не считай, а? А если я в php-фильтре вызову функцию из модуля, все ок? Ты тут про eval писал, так вот он
<?php // Execute the display code.
$display_output = NULL;
if ($display_in_code) {
$display_output = $display_func($field, $entity_field_item, $entity_lang, $langcode, $entity);
}
else {
eval($field['settings']['display_format']);
}?>
и вот
<?php if (isset($settings['code'])) {
eval($settings['code']);
}?>
То есть если я в php-фильтре вызову функцию, то все ок что ли? Что за бред?
Я вот проверил, в computed_field вызвал пару функций - user_load(1) а потом user_save - и все ок, другой теперь пароль у user#1.
Но это конечно же ерунда, можно юзать
Сегодня ты используешь пхп-фильтр, а завтра будешь сайты на хостинг по фтп закачивать.
А как надо? )
гитом конечно, а как же ещё?
magallanes или capistrano, например
ну или jenkins для тех кто знает толк
Ну оно же так или иначе в глубине души базируется на гите))
git там используется на этапе формирования-сборки того, что собираемся деплоить. Сам деплой - это уже не гит.
Выкатывать на прод командой git pull - тоже не хорошо.
Чекаут предпочтительнее?
оба хуже
Ну по ftp например.
Не подскажете, в чем проблема по ftp файлы закачивать?
1. Нужно самому отслеживать и запоминать, какие файлы изменены.
2. Долго таскать их мышкой
3. Долгая передача файлов - на каждый файл создаётся новое соединение.
4. Не секьюрно.
5. Очень часто при бросании файлов мышкой туда-сюда они могут не переписаться.
1.Данный код пишется в базу, поэтому его нельзя будет отследить через систему контроля версий, например git. (если вы не используете систему контроля версий в разработке - это тоже плохо).
3. Код в php-фильтре выполняется через eval(). Код через eval работает медленнее, не кэшируется opcache-м, а на некоторых хостингах eval может быть отключен из соображений безопасности.
Не информативные сообщения об ошибках. Что-то типа error in eval() on line 4. Где этот кусок кода, что с ним делать?
6. Сложно писать и поддерживать такой код. В обычном textfield - нет форматирования как в IDE, да и шрифт не моноширинный. Копировать туда-обратно тоже заколебаться можно.
7. Человеческий фактор. Всегда существует возможность ошибки в конфигурации, которая позволит не доверенным пользователям заюзать php-фильтр(или computed_field). ОЙ!
8. Безопасность в целом. Любой сайт могут взломать, но присутствие на сайте php-фильтра может сделать последствия взлома гораздо тяжелее. XSS, SQL-инъекция - и вот вас уже shell прямо в базе.
9.Сложности деплоя. Нельзя просто обновить файлы на сервере. Надо лезть в админку, и копипастить код в нужные места. Хотя обычно в PHP-фильтр пишут прямо на продакте. Не стоит работать на продакте.
10.Повышается цена ошибки. Одна небольшая опечатка в сквозном блоке - и всё пропало, шеф.
Все вышеуказанные пункты вычеркивай или вычеркивай computed_field и пиши статью, почему этот модуль нельзя использовать - и все эти пункты туда пойдут отлично.
А давайте вы лучше напишите статью, почему стоит использовать PHP-фильтр. С аргументами, пожалуйста.
Я выше написал уже - это удобно и работает. Какие вам ещё причины нужны? Может написать ещё почему можно использовать computed_field? Может написать, почему я не верблюд, а, сразу уж?
Офигеть удобно. Вот надо тебе этот код в пхп-фильтре поправить
- идёшь на сайт
- логинишься,
- ищешь в админке нужный блок, вьюс или что-то ещё
- правишь всё в неудобном поле без подсветки кода и форматирования
- сохраняешь
А если всё в коде, то правка происходит так
- поправил код в иде-шке
- гит пуш
- гит пулл
Нет, не так. Есть сайт безо всяких гитов. Идешь и создаешь к примеру поле Views php - пишешь там три строчки.
Или же - ставишь гит, если ещё хостинг позволяет, потом пишешь модуль, потом через гит его закачиваешь и потом удаляешь? Это типа быстрее что ли?
Если на сайте нет гита, то нефиг работать с такими заказчиками. Даже на самых бомжацких шаред-хостингах гит есть из коробки, а на впс гит ставится одной командой за 5 сек.
Какое высокомерие же. Ты для понтов что ли работу делаешь или чтобы деньги заработать?
Я делаю работу исключительно ради денег. Именно поэтому я не хочу работать с нищебродами, которых жаба душит переплачивать целый доллар за нормальный хостинг. Если человек скупится на хостинг, то оплата услуг программиста будет аналогичная. Я лучше пройду мимо таких людей и буду работать с теми, с кем сотрудничать приятнее и выгоднее.
Я наверное напишу статью, почему нельзя использовать computed_field - и вон у меня уже и аргументы есть. Ну что бы дурь этих доводов была нагляднее видна
Про rules тоже надо такую статью - почему нельзя его использовать. Там тоже без проблем можно код выполнять
И про devel тоже
Rules как раз и нужен вместо кода.
Приведу пример с расчетом итоговой цены и типа скидки для пользователя.
У нас в магазине скидка может быть трёх типов:
- распродажа: розничная цена + цена со скидкой, значения загружаются извне
- акция: скидка от розничной цены, действующая непродолжительный период времени, "товар дня" условно говоря
- накопительная скидка пользователя
Обычная практика - из трёх возможных скидок выбирается максимальная, и берётся её тип.
Как быть, если скидка по распродаже и скидка по акции - одинаковы (бывает, когда менеджер магазина напутал)?
Какой тип выбрать? Распродажа - смотри, у нас тут распродажи-распродажи?
Или акцию? Смотри - у нас тут акции-акции, хотя ты и так бы мог купить по той же цене на распродаже?
А если у пользователя - такая же накопительная скидка как и по распродаже-акции? Какой тип показать?
Правильный ответ - A/B/C тесты. Как будет лучше продаваться - так и надо делать.
Так вот, чтобы не хардкодить логику в модуле, её вынесли в отдельный рул - в аргументах вся инфа по товару, пользователю, акциям. Результат - итоговая цена и тип получившейся скидки. И поменять эту логику в случае необходимости - теперь задача администратора сайта, а не программиста.
Бонусом - возможность добавления какой угодно дополнительной логики: а если сегодня четверг и нечётный месяц, то...
Вот для этого и нужен рул - вынести бизнес-логику из кода.
И php-фильтр тут не причем.
За devel, включенный на проде - надо наказывать материально.
Drupal-разработчики делятся на тех, кто пользуется php-фильтрами, и тех, кто уже не пользуется.
Секта "свидетелей качественной разработки" ?
Автор не съехал. У автора три выходных.
Делая сайты на базе drupal, мы сталкиваемся с тем,
что возникшую задачу можно решить несколькими различными способами.
Помимо прочих сопутствующих задаче условий, важнейшим является компетенция разработчика.
Косвенно о ней можно судить по методу решения поставленной задачи))
Но спор не о наших скилах а о принципах разработки.
Так, откинув несущественное мы придем к простому принципу:
база данных - для данных.
Да в drupal этот принцип зачастую обходится,
и это видим на примере не только ядра, но и многих очень популярных и отличных контриб модулей.
Однако, это не повод сей принцип не принимать в расчет.
Хорошей практикой будет учитывать его в своей работе.
Тем паче, это же мы видим и в развитии самого drupal от версии к версии.
Те же настройки сайта, это не данные но они в бд, но в 8-ке у нас уже есть конфиги,
читай - возможность хранить свои настройки в файловой системе,
(где им в принципе самое и место).
Из тех-же шаблонов уезжает логика и вызовы в БД.
Исполняемый код в БД - не лучшее решение.
Да есть такая возможность, но так-же есть возможность этого не делать для своего функционала.
Все упирается в компетенцию исполнителя работ.
Тут самое простое и быстрое на первый взгляд решение - не всегда оптимальное и безопасное.
Это жизнь - костыли были есть и будут.
Но это не повод постоянно с ними жить и защищать такой метод.
Вывод по сабжу темы:
с php_filter возможно решать локальные задачки,
но получив работающий функ-л, важно знать - это первейший кандидат на рефакторинг.
Так зачем делать двойную работу?
Имеет смысл делать правильно изначально))
Устарело, D8 убирает вопрос.
если б это было правдой))
но увы
Да, - нет счастья, убрать вообще PHP, а то только мешается под ногами.
Спасибо, то что нужно)
Согласен с ТС полностью: использовать php фильтр не стОит. Лучшее что можно с ним сделать - отключить.
Действительно, бывают моменты, когда он может выручить, но следует всеми силами этого избегать.
Для хейтеров ТС - ребята, это не секта, это опыт. Надеюсь вы к этому тоже придёте. А не придёте - у нас работы прибавится, что тоже не может не радовать Как раз сейчас такой экземпляр на поддержке.
Когда видишь в логах
Strict warning: Only variables should be passed by reference в функции eval() (строка 19 в файле /home/webmaster/domains/domain.com/html/modules/php/php.module(80) : eval()'d code).
а в боди ноды
<?php<div id="catalog">
<?php print create_jplayer_from_vocabulary('playlist2');?>
</div>
<?php if (block_get_blocks_by_region('triptych_middle')): ?>
<?php print render(block_get_blocks_by_region('triptych_middle')); ?>
<?php endif; ?>
чувствуется уверенность в завтрашнем дне
От половины этих пунктов можно запросто избавиться, если в поле php-фильтра писать не код, а инклуд файла, в котором код. А сам файл хранить в файловой структуре сайта. У меня для этого отдельная папочка создана. И в комментариях к каждому файлу даю ссыль на представление, куда этот файл инклудится.
Не спорю с тем, что код в БД (даже если это одна строчка инклуда) всё равно не фонтан. И eval() не фонтан. Вообще, решение не фонтан. Но бывает нужно такую ерунду сделать, из-за которой городить огород, используя предложенные альтернативы, кажется потерей времени. Жаль, что такой фичи уже нет в Д8 и дальше.
Выпиливание php-filter чуть-ли не лучшее, что было сделано в 8.
Все здорово и понятно, но как быть, если через php include() в Body подгружается контент? Причем аж 22 с лишним тыщи единиц?
Структуру сайта делать правильной
А эту функцию нельзя вписать в шаблон ноды? Ну это если вы ненавистник views.
Она в шаблоне и есть.
На дворе 2021 год. Если тебе приходится использовать include, значит ты решаешь задачу неправильно.
В 2008 такой подход был точно также ошибочным. Да и раньше, на самом деле.
В каждую ноду надо подгружать чистенький html, формируемый в источнике, не связанном с друпалом. Причем периодически приходится обновлять по несколько тысяч нод.
Теоретически можно и вручную копипастить, а можно инклудом всасывать html в поле. Из двух зол выбрал меньшее. За 10 лет проблем с сайтом на семерке не было, поскольку доступ только админский.
Если есть какие толковые соображения, буду рад выслушать.