Какова основная концепция за крючками?

Я занимаюсь промежуточным звеном в PHP. Чтобы отполировать мои навыки, я начинаю изучать Drupal 7. При изучении концепций архитектуры Drupal термины hooks и bootstrapping меня много озадачили. Я прочитал книгу «Pro Drupal development» и некоторую документацию на drupal.org, но она настолько продвинута для меня, чтобы узнать, как крючки работают в Drupal для отображения веб-страницы.

Может ли кто-нибудь сказать мне, какие крючки в простых словах?

122 голоса | спросил GiLL 23 MaramFri, 23 Mar 2012 11:36:40 +04002012-03-23T11:36:40+04:0011 2012, 11:36:40

13 ответов


108

Другие ответы велики, точны, детализированы, но я не уверен, что они «простые слова», объясняющие голые кости концепции, которую искал искатель.

Я думаю о крючках как о точке, где код останавливается и кричит « Кто-нибудь еще получил что-нибудь, чтобы добавить сюда? ». Любой модуль может иметь функцию, которая отвечает на это, и запускается с соответствующими данными, переданными ему в этой точке кода.

Хорошим простым примером является hook_node_delete () . Любой модуль может использовать его, чтобы все происходило при каждом удалении узла. Документы сообщают вам, что этот крюк передает модулю объект этого удаленного узла для работы с ним и описывает другую полезную информацию, такую ​​как точное время ее вызова (например, что это до того, как данные узла фактически удалены из базы данных) , и где в коде Drupal вызывается хук (который может быть более одного места).

Вы можете изучить, какие существуют крючки, и узнать, какие данные передаются им, исследуя вещи, начинающиеся с «hook_» в Drupal api .

Крючки работают по соглашениям имен: используя hook_node_delete в качестве нашего примера, когда процесс удаления узла достигает точки, где вызывается hook, для каждого модуля с функцией, подобной этой [modulename]_node_delete(), где слово hook в имени крюка заменяется именем модуля (например, my_amazing_module_node_delete()), эти функции вызываются.

Почему? Таким образом, любой модуль может делать что-либо в этих ключевых моментах: например, вы можете посмотреть удаленный узел и сделать что-то, если оно соответствует определенному условию (скажем, по электронной почте администратора или запустить какой-то длительный процесс).

Некоторые перехватчики позволяют изменять вещи, которые были сгенерированы непосредственно перед их обработкой. Например, hook_menu_alter () передает вам текущий элементы меню, которые система сгенерировала. Любой модуль может определить функцию some_modulename_menu_alter () и посмотреть на них, по желанию изменить их (удалить некоторые, добавить некоторые, отсортировать их ...) и передать вновь измененное меню.

Это просто, очень мощно и в основе того, как Drupal работает как модульная система. Реализация крючков лежит в основе большинства модулей Drupal.

При просмотре кода модуля Drupal вы можете определить, какие функции выполняются с помощью крючков (в отличие от функций, которые просто вызывают из самого кода модуля), поскольку сообщество Drupal применяет соглашение, в соответствии с которым каждая реализация у крючка есть комментарий перед ним, как это (обратите внимание на бит «Реализует крюк _...»):

/**
 * Implements hook_some_hook().
 *
 * Some descriptive summary of what this does
 */
function my_amazing_module_some_hook() {

Некоторые модули, которые действуют как API, определяют свои собственные привязки. Например, Просмотры определяет множество перехватов, которые позволяют добавлять, читать и редактировать данные в разных точках процесса создания или отображения вид. Вы можете найти информацию о крючках, созданных в пользовательских модулях, из двух мест (при условии, что модуль соответствует соглашениям и т. Д.):

Загрузочный процесс, как объясняют другие, в основном загружается - я не буду дублировать другие хорошие четкие объяснения.

ответил user568458 23 J0000006Europe/Moscow 2012, 20:06:36
53

Крючки - это в основном реализации Посетителя и Observer .

Одна из наиболее распространенных реализаций переходов - hook_menu , который позволяет модулю регистрировать новые пути в системе Drupal.

function my_module_menu() {
  return array('myawesomefrontpage' => array(
    'page callback' => 'function_that_will_render_frontpage'
  ));
}

Очень частой шаблон в Drupal имеет крючок [DATATYPE]_info и [DATATYPE] _info_alter. Если вы хотите создать новый тип поля, вы реализуете соответствующий field_info -hook, и если вы хотите управлять существующим, вы реализуете соответствующий field_info_alter -hook.

Изменить: Как указывает Chx в комментариях, шаблон наблюдателя ориентирован на object , который Drupal 7 по-прежнему, в основном, отсутствует. Однако есть страница wiki, программирование Drupal с объектно-ориентированной точки зрения (Создано JonBob 4 апреля 2005 г.), что объясняет как Drupal использует объектно-ориентированные шаблоны кода, несмотря на это. Интересно отметить, что в нем упоминаются наблюдатели, но не посетители.

Примечание по Drupal 8 . Это все еще довольно рано и может быть изменено, но я хочу добавить, что, хотя перехватчики уже довольно давно являются стандартом де-факто в добавлении функций Drupal , концепция плагинов станет намного более заметной в Drupal 8 и даст нам новые способы взаимодействия с Core , Релевантная проблема и документация .

ответил Letharion 23 MaramFri, 23 Mar 2012 11:52:13 +04002012-03-23T11:52:13+04:0011 2012, 11:52:13
33

В терминах непрофессионала крючки представляют собой своего рода мосты, которые обеспечивают взаимодействие модулей друг с другом, изменяют структуру и данные друг друга, предоставляют новые данные и т. д.

В большинстве случаев слово hook_ в именах функций заменяется именем вашего модуля, и это дает возможность вашему модулю подключиться к работе другого модуля. Например, основной модуль drupal, называемый «узлом», вызывает различные крючки. Одним из них является hook_node_update, который запускается каждый раз, когда обновляется существующий узел. Когда этот крючок вызывается, вызывается реализация вашего модуля (скажем, мы называем его mymodule) hook_node_update, который в этом случае будет функцией в файле .module вашего модуля, называемом mymodule_node_update (Очевидно, что эта функция может быть в любом файле в папке вашего модуля, если она также включена в файл .module). Этот hook также будет передан необходимые параметры (переменные), которые он может использовать, изменить и /или вернуться к функции, которая вызвала hook.

Когда я впервые начал изучать Drupal, я был в той же лодке, что и сейчас, сначала немного сложно понять, но как только вы ее получите, это так просто и интуитивно. Удачи.

ответил Beebee 23 MarpmFri, 23 Mar 2012 13:20:22 +04002012-03-23T13:20:22+04:0001 2012, 13:20:22
32

Один из основных разработчиков недавно написал статью под названием «Программирование Drupal с объектно-ориентированной точки зрения» . Он хорошо объясняет, как крючки можно рассматривать как реализующие многие из общих шаблонов проектирования . Лучшее объяснение крючков происходит из статьи:

  

Система крючков Drupal является основой абстракции интерфейса. Крючки   определить операции, которые могут выполняться на модуле или с помощью модуля. Если   модуль реализует крючок, он заключает контракт на выполнение   конкретную задачу или вернуть определенный тип информации, когда   вызывается hook. Код вызова не должен знать ничего о   модуль или способ осуществления крюка для получения полезной работы   сделанный путем вызова крюка.

ответил mpdonadio 23 MarpmFri, 23 Mar 2012 17:10:25 +04002012-03-23T17:10:25+04:0005 2012, 17:10:25
20

Bootstrap - это процесс, который Drupal выполняет для создания страницы, в основном выполняющей все основные, тематические и модульные коды. В основном, как Drupal загружается, и готовится сделать это как CMS.

Это умно, поскольку он позволяет нам помещать крючки в любом месте в наши модули и темы, а процесс начальной загрузки гарантирует, что они будут запущены в нужном месте.
Например, если вы используете «hook_form_alter», чтобы добавить настраиваемый флажок в форму, загрузочный бункер Drupal убедится, что он запускает этот код, перед тем, как он отобразит вашу форму.

Одной из проблем с загрузкой является то, что весь процесс требует времени для запуска, даже если вы возвращаете только небольшое количество данных. При использовании Drupal с сервисным модулем как API и возвратом многих небольших ответов XHTML или JSON, запуск через весь загрузочный файл не очень эффективен. Некоторые умные люди ищут умные способы обойти это для Drupal 8.

Но для рендеринга обычных страниц Drupal процесс начальной загрузки отлично работает, он использует систему кэширования Drupals для ускорения работы и дает полный контроль над каждой частью вашего сайта. Если вы обнаружите, что ваш сайт медленный, вы всегда можете использовать что-то вроде APC или MemCached, чтобы ускорить процесс.

Надеюсь, мой ответ был точным и объясняет вещи просто для вас, я не эксперт, но я думаю, что так оно и работает.

ответил medden 28 MaramWed, 28 Mar 2012 11:33:28 +04002012-03-28T11:33:28+04:0011 2012, 11:33:28
15

Bootstrap - это процесс, во время которого Drupal инициализирует себя; процесс фактически включает в себя:

  • Установка ошибки и обработчики исключений
  • Инициализация значения некоторых spec-глобальных переменных, содержащихся в $_SERVER
  • Инициализация некоторых переменных с помощью init_set()
  • Поиск кэшированной версии страницы для обслуживания
  • Инициализация базы данных
  • Настройка обработчиков, которые загружают файлы, когда класс или интерфейс не найдены
  • Инициализация переменных Drupal
  • Инициализация сеанса PHP
  • Инициализация языковой переменной
  • Загрузка разрешенных модулей

Некоторые из описанных операций специфичны для Drupal 7 или выше, но большинство операций не зависят от версии Drupal.

Крюк - это функция PHP, которую можно вызвать из Drupal или сторонних модулей, когда это необходимо для выполнения задачи. Вместо того, чтобы иметь префиксный список функций для вызова, список строит проверку включенных модулей и функций, которые они реализуют.
Например, Drupal использует hook_node_update(); когда узел сохраняется с node_save () , выполняется следующий код.

// Call the node specific callback (if any). This can be
// node_invoke($node, 'insert') or
// node_invoke($node, 'update').
node_invoke($node, $op);

Что node_invoke () делает следующее:

  • Получение списка всех включенных модулей
  • Проверка наличия у разрешенных модулей функции, имя которой заканчивается на «_node_update» и начинается с краткого имени модуля
  • Вызов этой функции, передача $node в качестве параметра

Крючки могут сохранять свои собственные данные в базе данных или изменять значение, возвращаемое функцией. В последнем случае, например, что происходит с hook_form_alter () , который изменяет значение $form, переданное как ссылка на drupal_prepare_form () .

Взаимодействие с Drupal обычно вызывается с использованием трех функций:

drupal_alter() - это функция, используемая для вызова определенных перехватчиков, целью которых является изменение данных, переданных в качестве ссылки, таких как hook_form_alter () , hook_hook_info_alter () и hook_tokens_alter () .

Существуют и другие функции, которые используются для вызова hooks, таких как node_invoke(), но эти функции по существу используют одну из функций, которые я ранее указывал.

ответил kiamlaluno 16 J0000006Europe/Moscow 2012, 22:23:20
12

Крюки pointcuts и module_invoke_all - это ткач (увы, мы не совсем понятны в реализации и есть другие функции ткачества). Насколько мне известно, Drupal - единственная система для реализации AOP с функциями PHP .

См. другое объяснение в Как работает АОП в Drupal?

ответил 28 J0000006Europe/Moscow 2012, 11:40:00
6

Если вы хотите увидеть крючки, которые Drupal позволяет вам позвонить, перейдите на api.drupal.org , перейдите на вкладку в поле поиска и введите «hook_». Это даст вам большой список большинства перехватов, определенных Drupal. Сделайте то же самое для «_alter» и увидите еще больше.

Страница страницы API-интерфейсов Node API предлагает хронологический список всех крючков, вызываемых во время операций узла. Вы можете видеть модуль узла и системы Entity и Field, дающие друг другу повороты при вызове крючков.

Например, если вы прокрутите страницу вниз и посмотрите раздел node_load(): модуль узла даст вам hook_load (), а затем передаст управление системе сущностей, которая загружает некоторые поля , Существует целый ряд перехватчиков полей, которые не указаны, а затем, когда это происходит над системой сущностей, вызывает hook_entity_load(), прежде чем передать управление обратно в узел, который вызывает hook_node_load().

Это дает вашему коду возможность действовать на рассматриваемом узле, когда он загружается, по частям. Изучение этих крючков, и когда и почему они называются, является частью приключения кодирования Drupal. : -)

В других системах также есть крючки. Например hook_init() и hook_boot() . Это доходит до начальной части вашего вопроса. hook_boot() вызывается Drupal до загрузки системы кэширования. Поэтому, если вашему модулю нужно что-то сделать до того, как Drupal действительно запустится, и вы хотите, чтобы ваш код запускался независимо от кеширования, вы должны реализовать hook_boot(). В противном случае, если вы не заботитесь о страницах, которые не кэшируются, вы должны реализовать hook_init().

Это дает вам возможность реализовать что-то в начале процесса загрузки, прежде чем Drupal полностью загрузится, и предоставит вам некоторую гибкость в отношении того, в какой момент процесса вы хотите перехватить.

Если вам необходимо убедиться, что Drupal загрузился до определенного момента, прежде чем продолжить, вы можете вызвать drupal_bootstrap() . Если вы перейдете к этой документации, вы увидите доступные уровни загрузки, от ничего общего.

И, наконец, вы можете увидеть какой-то широко документированный код для любой данной подсистемы в примере проекта .

ответил paul-m 22 J0000006Europe/Moscow 2012, 22:14:06
6

Крюки - это php-функции, строительные блоки основанные на соглашениях об именах «yourmodulename_hookname», они предназначены для облегчения способности разработчиков создавать модули .

Модули - это настоящая сделка, поскольку они позволяют использовать CORE и пользовательские функции в вашей системе Drupal. Таким образом, модули состоят из крючков и когда модуль активирован в вашей установке Drupal, его функции перехвата могут быть вызваны из других модулей благодаря функции module.inc module_invoke_all ($ hook) или module_invoke.

Поэтому, чтобы правильно понять, что такое крючки, вы должны действительно загрязнить свои руки и попробовать разработку модуля. Для этого начните с загрузки и тестирования некоторых примеров Drupal для разработчиков , вы должны ознакомиться с создание модулей .

Вот некоторые из полезных примеров Drupal для разработчиков, упомянутых выше:

Пример

hook_block_view () в модуле block_example

/**
 * @file examples/block_example/block_example.module line 127
 *
 * Implements hook_block_view().
 *
 * This hook generates the contents of the blocks themselves.
 */
function block_example_block_view($delta = '') {
  //The $delta parameter tells us which block is being requested.
  switch ($delta) {
    case 'example_configurable_text':
      // The subject is displayed at the top of the block. Note that it
      // should be passed through t() for translation. The title configured
      // for the block using Drupal UI supercedes this one.
      $block['subject'] = t('Title of first block (example_configurable_text)');

Этот крючок дает вам доступ к созданию блоков Drupal для отображения пользовательских блоков на вашем веб-сайте. Это возможно, потому что block.module имеет _block_render_block , которые позволяют всем модулям определять их вид hook_block (обратите внимание на последнюю строку module_invoke):

/**
 * @file modules/block/block.module, line 838
 *
 * Render the content and subject for a set of blocks.
 *
 * @param $region_blocks
 *   An array of block objects such as returned for one region by _block_load_blocks().
 *
 * @return
 *   An array of visible blocks as expected by drupal_render().
 */
function _block_render_blocks($region_blocks) {
  ...
  foreach ($region_blocks as $key => $block) {
    ...
    $array = module_invoke($block->module, 'block_view', $block->delta);

пример использования hook_menu () в модуле render_example

/**
 * @file examples/render_example/render_example.module line 22
 * 
 * Implements hook_menu().
 */
function render_example_menu() {
  ...
  $items['examples/render_example/arrays'] = array(
    'title' => 'Render array examples',
    'page callback' => 'render_example_arrays',
    'access callback' => TRUE,
  );

Этот хук связан с системой маршрутизации URL-адресов Drupal и определяет шаблоны url с связанными обратными вызовами рендеринга, используемыми вашим модулем. Он вызывается из системы. модуль .

О загрузке, в основном, вам просто нужно знать, что он выполняется при каждом запросе страницы. Я действительно советую вам прочитать этот ответ stackoverflow , он объясняет, как загрузочный файл и крючки связаны, но разделены.

Что касается отображения веб-страницы, то отображение html-сайта веб-сайта Drupal в основном достигается с помощью рендеринга массивов и тематики .

ответил B2F 23 J0000006Europe/Moscow 2012, 17:51:53
3

В любом месте модуль вызывает module_implements () http: //api.drupal.org/api/drupal/includes%21module.inc/function/module_implements/7 Drupal будет запускать все правильно названные функции в правильном порядке в зависимости от их веса. Они называются функциями hook, потому что в документации для модулей, которые используют module_implements, вы видите такие вещи, как hook_menu (когда меню вызывает все функции, предназначенные для возврата пунктов меню). Слово «hook» просто нужно заменить именем модуля, реализующего его, а Drupal сделает все остальное.

Существует также функция drupal_alter (), которая запускает все корректные именованные функции alter, с намерением позволить вам изменить вещи, которые ранее были зарегистрированы другим крюком.

Обычно изменения передаются в аргументах по ссылке, поэтому вы можете редактировать объект напрямую, тогда как «обычные» крючки обычно возвращают вам новые вещи.

Идея состоит в том, что любой модуль (включая ваш собственный) можно легко расширить, попросив Drupal вызвать все необходимые функции hook и вернуть обратно, что они возвращают для обработки. Модуль, вызывающий функции hook, не должен ничего знать о модулях, которые реализуют hooks, а модули, реализующие hook, действительно не должны знать ничего о модуле, вызывающем hook. Единственное, что должны знать оба модуля, это структура возвращаемых или измененных данных.

На практике крючки чаще всего обычно используются для:

  • реагировать на события, например hook_user_login вызывается, когда пользователь регистрируется в
  • зарегистрировать что-то новое, которое можно использовать для расширения системы, например hook_menu
  • тема /рендеринг html или сборка /проверка /отправка форм
ответил David Meister 25 J0000006Europe/Moscow 2012, 15:18:03
1

У вас много ответов выше, но я хочу дать ответ гораздо более простым способом понять основную концепцию за крючками. Крюки фактически встроены в функции ядра drupal для управления различными вещами и amp; выполнял разные задания в ядре, вы можете синхронизировать свои собственные функции с помощью этих встроенных функций ядра drupal, чтобы добавить их функциональность в свои собственные функции, вызывая разные перехватчики.

Надеюсь, вы поймете смысл!

ответил user25892 17 MaramThu, 17 Mar 2016 10:55:51 +03002016-03-17T10:55:51+03:0010 2016, 10:55:51
1

Для меня это все о функции module_implements, когда дело касается крючков и ядра (D7). Одна вещь, которая, как мне кажется, имеет решающее значение для понимания, заключается в том, что, написав крючок, чтобы что-то изменить, вы ни в коем случае не имеете последнего слова в том, что происходит с структурами данных, с которыми вы имеете дело. Ваш хук просто попадает в строку (очередь) функций, которые ТАКЖЕ действуют в тех же структурах данных, будь то меню, menu_links, блоки, узлы, пользователи или любой объект или элемент визуализации.

Итак, чтобы действительно увидеть, как ваши крючки будут использоваться в ожидаемом режиме, вам нужно знать или знать, где вы (ваш крюк) встаете в очередь. Это определяется весом вашего расписания. Ядро Drupal просто вызывает правильно названные крючки в порядке возрастания веса и все, что происходит с данными.

Я написал крючки, прежде чем это не имело никакого эффекта, только чтобы узнать после нескольких часов о том, что мой вес модуля был слишком легким, а подстрочные крючки фактически не делали то, что я делал, или полностью игнорировали все это .

Хорошо написанный крючок не будет «манипулировать человеком» или «заставлять» себя быть последним, но «поместится хорошо с другими», убедившись, что они поддерживают структуры данных, как ожидалось, остальными крючками вниз по линии.

И говоря о «Линии» крючков. На протяжении многих лет я троллировал Google для Drupal, это изображение, по-видимому, является хорошим представлением списка возможностей процесса и списка процессов.
 введите описание изображения здесь>> </a> </p></body></html>

ответил Dan Shumaker 11 Maypm16 2016, 21:32:46
1

В гораздо более простом режиме крючки помогают разработчику изменять существующую функциональность в соответствии с требованиями без внесения изменений в существующий код. Больше похоже Абстрактная функция в php.

Пример. Вы создали модуль для бронирования билета на автобус. Согласно вашему коду, если билет когда-то был забронирован, выберите место, которое невозможно изменить, и это было вашим требованием для этого проекта. Предположите, что вашему другу нужен тот же модуль для аналогичного требования, за исключением того, что пользователь может изменить местоположение пикапа. Каким-то образом он должен использовать ваш модуль, и вы не хотите, чтобы он делал какие-либо изменения кода. Таким образом, вы предоставляете интерфейс (в нашем случае - крючок), где он может выполнять свои изменения без внесения изменений в ваш модуль.

В drupal до drupal-7 у нас есть крючки для модулей, а также темы. Чтобы узнать, как работает проверка работы крюка, drupal.org hooks , чтобы создать пользовательский крючок, проверьте это

ответил Anamika 26 PMpWed, 26 Apr 2017 15:45:02 +030045Wednesday 2017, 15:45:02

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132