回答:
他の答えは素晴らしく、正確で、詳細ですが、質問者が探していた概念の骨を説明する「単純な言葉」かどうかはわかりません。
フックは、コードが一時停止して「他に誰かがここに追加するものがありますか?」と叫ぶポイントだと思います。すべてのモジュールはこれに応答する関数を持つことができ、コードのその時点で適切なデータが渡されてトリガーされます。
わかりやすい簡単な例はhook_node_delete()です。ノードが削除されるたびに、どのモジュールでもそれを使用して物事を発生させることができます。ドキュメントは、このフックが削除されたノードのオブジェクトを処理するモジュールに渡し、呼び出された正確なタイミングに関するその他の有用な情報を概説します(たとえば、ノードデータがデータベースから実際に削除される前) 、Drupalのコードのどこでフックが呼び出されるか(複数の場所になります)。
Drupal apiで「hook_」で始まるものを調べることにより、フックが存在するものを探索し、それらに渡されるデータを見つけることができます。
フックは名前の規則によって機能しhook_node_delete
ます。例として、ノードの削除プロセスがフックが呼び出されるポイントに達すると、[modulename]_node_delete()
フックの名前の単語hookがモジュールの名前に置き換えられるこのような機能を持つすべてのモジュールについてmy_amazing_module_node_delete()
)、これらの関数が呼び出されます。
どうして?したがって、どのモジュールでもこれらの重要なポイントで何でもできます。たとえば、削除されたノードを見て、特定の条件(管理者にメールを送信したり、いくつかの長いプロセスを起動したり)を満たせば何かを実行できます。
一部のフックでは、処理される直前に生成されたものを変更できます。たとえば、hook_menu_alter()は、システムが生成した現在のメニュー項目を渡します。どのモジュールでも関数some_modulename_menu_alter()を定義し、それらを見て、オプションでそれらを変更(いくつかを削除、いくつかを追加、ソート...)し、新しく変更されたメニューを戻すことができます。
シンプルで非常に強力であり、Drupalがモジュラーシステムとして機能する方法の中心にあります。フックの実装は、ほとんどのDrupalモジュールの中心です。
Drupalコミュニティは、フックの各実装が持つ規約を実施するため、Drupalモジュールのコードを調べると、(モジュールコード自体から単純に呼び出される関数とは対照的に)フックからの関数を見つけることができますその前に次のようにコメントします(「Implements hook _...」ビットに注意してください):
/**
* Implements hook_some_hook().
*
* Some descriptive summary of what this does
*/
function my_amazing_module_some_hook() {
APIとして機能する一部のモジュールは、独自のフックを定義します。たとえば、ビューは、ビューの作成または表示プロセスのさまざまな時点でデータの追加、読み取り、編集を可能にする多くのフックを定義します。カスタムモジュールで作成されたフックに関する情報は、2つの場所から見つけることができます(モジュールが規則に従っていると仮定すると)。
modulename.api.php
モジュールフォルダー内のファイルのコードとコメント他の人が説明したように、ブートストラップは基本的に起動します-他の明確な説明を複製しません。
フックは、ほとんどがVisitorパターンとObserverパターンの実装です。
最も一般的なフック実装の1つは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がコメントで指摘しているように、オブザーバーパターンはオブジェクト指向であり、Drupal 7はまだほとんどではありません。ただし、Wikiページ、オブジェクト指向の観点からのDrupalプログラミング(2005年4月4日にJonBobによって作成)があり、これにもかかわらずDrupalがオブジェクト指向のコードパターンを使用する方法を説明しています。興味深いのは、オブザーバーに言及しているが訪問者には言及していないことです。
Drupal 8に関する注意これはまだかなり早く、変更される可能性がありますが、フックはかなり長い間、Drupalに機能を追加する際の事実上の標準でしたが、プラグインの概念ははるかに明らかになりますDrupal 8では、Coreと対話する新しい方法を提供します。関連する問題、およびドキュメント。
素人の言葉で言うと、フックとは、モジュールが相互にやり取りし、互いの構造とデータを変更し、新しいデータを提供する方法を提供する一種のブリッジです。
ほとんどの場合、hook_
関数名の単語はモジュールの名前に置き換えられ、モジュールが別のモジュールの操作を利用する方法を提供します。たとえば、「ノード」と呼ばれるdrupalコアモジュールは、さまざまなフックを呼び出します。それらの1つはhook_node_update
、既存のノードが更新されるたびに呼び出されるものです。このフックが呼び出されると、モジュールの(たとえば、呼び出すmymodule
)実装が呼び出されます。hook_node_update
この場合、モジュールの.moduleファイル内の関数になりますmymodule_node_update
(明らかに、この関数は、モジュールのフォルダー内の任意のファイルにあります。 .moduleファイルにも含まれています)。このフックには、使用、変更、および/またはフックを呼び出した関数に戻ることができる必要なパラメーター(変数)も渡されます。
最初にDrupalを学び始めたとき、私はあなたと同じ船に乗っていました。最初はつかむのが少し難しいですが、一度理解すると、とてもシンプルで直感的です。幸運を。
コア開発者の1人が「オブジェクト指向の観点からのDrupalプログラミング」という記事を少し前に書きました。フックが一般的なデザインパターンの多くを実装すると考えられる方法を説明する良い仕事をします。フックの最良の説明は、記事から来ています。
Drupalのフックシステムは、インターフェイスの抽象化の基礎です。フックは、モジュール上またはモジュールによって実行できる操作を定義します。モジュールがフックを実装すると、フックが呼び出されたときに特定のタスクを実行したり、特定の種類の情報を返したりする契約が締結されます。フックを呼び出すことで有用な作業を行うために、呼び出し元のコードはモジュールやフックの実装方法について何も知る必要はありません。
ブートストラップは、Drupalがページを構築するプロセスであり、基本的にすべてのコア、テーマ、およびモジュールコードを順番に実行します。
基本的には、Drupalが起動し、CMSとしての仕事を準備する方法です。
モジュールやテーマの任意の場所にフックを配置できるという点で賢明であり、ブートストラッププロセスにより、それらが適切なポイントで実行されるようになります。
たとえば、「hook_form_alter」を使用してカスタムチェックボックスをフォームに追加すると、Drupalのブートストラップは、フォームをレンダリングする直前にそのコードを実行するようにします。
ブートストラップの問題の1つは、たとえ少量のデータしか返さない場合でも、プロセス全体の実行に時間がかかることです。DrupalをサービスモジュールでAPIとして使用し、多くの小さなXHTMLまたはJSON応答を返す場合、ブートストラップ全体を実行することはあまりパフォーマンスがありません。一部の賢い人々は、Drupal 8についてこれに関する賢い方法を検討しています。
しかし、通常のDrupalページをレンダリングする場合、ブートストラッププロセスはうまく機能し、Drupalキャッシングシステムを使用して処理を高速化し、サイトのすべての部分を完全に制御できます。サイトの速度が遅い場合は、APCやMemCachedなどを使用して、速度を上げることができます。
私の答えが正確で、あなたのために物事を簡単に説明してくれることを望みます、私は専門家ではありませんが、それがどのように機能するかと思います。
ブートストラップは、Drupalが自身を初期化するプロセスです。プロセスには実際に以下が含まれます。
$_SERVER
init_set()
説明した操作の一部は、Drupal 7以降に固有のものですが、ほとんどの操作はDrupalバージョンから独立しています。
フックは、タスクを実行する必要があるときにDrupalまたはサードパーティのモジュールから呼び出すことができるPHP関数です。呼び出す関数のプレフィックスリストを使用する代わりに、リストは有効なモジュールとそれらが実装する関数をチェックしてビルドされます。
たとえば、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
パラメーターとして渡すフックは、独自のデータをデータベースに保存したり、関数から返される値を変更したりできます。最後のケースは、例えば、drupal_prepare_form()への参照として渡される値を変更するhook_form_alter()で起こることです。$form
Drupalフックは通常、3つの関数を使用して呼び出されます。
drupal_alter()
その目的は、データを変更することであるような参照としてそれらを渡す特定フック呼び出すために使用される機能であるhook_form_alter() 、hook_hook_info_alter() 、及び)hook_tokens_alterは(。
フックなど、フックを呼び出すために使用される関数は他にもありますがnode_invoke()
、これらの関数は基本的に、前にリストした関数の1つを使用します。
フックはポイントカットでmodule_invoke_all
あり、ウィーバーです(実装には明確ではなく、他のウィービング関数があります)。私の知る限り、DrupalはPHP関数でAOPを実装する唯一のシステムです。
DrupalでのAOPの動作に関する別の説明をご覧ください。
Drupalで呼び出すことができるフックを表示するには、api.drupal.orgに移動し、検索ボックスにタブで移動して、「hook_」と入力します。これにより、Drupalで定義されているほとんどのフックの大きなリストが得られます。'_alter'についても同じことを行い、さらに多くを確認します。
ノードAPIフックのページには、ノードの操作中に呼び出されたすべてのフックの時系列リストを提供しています。Nodeモジュールと、EntityシステムとFieldシステムがフックの呼び出しで互いに交代することを確認できます。
たとえば、下にスクロールして次のセクションを見ると、node_load()
Nodeモジュールはhook_load()を提供し、いくつかのフィールドをロードするエンティティシステムに制御を渡します。リストされていないフィールドフックのホスト全体があり、それがエンティティシステムを呼び出すとhook_entity_load()
、を呼び出すNodeに制御を戻す前に呼び出しますhook_node_load()
。
これにより、コードは、問題のノードが1つずつロードされるときに、そのノードで動作する機会を与えます。これらのフックとそれらが呼び出されるタイミングと理由を学習することは、Drupalコーディングの冒険の一部です。:-)
他のシステムにもフックがあります。などhook_init()
とhook_boot()
。これにより、質問のブートストラップ部分に到達します。hook_boot()
キャッシングシステムがロードされる前にDrupalによって呼び出されます。したがって、Drupalが実際に起動する前にモジュールで何かを行う必要があり、キャッシュに関係なくコードを実行したい場合は、を実装しhook_boot()
ます。それ以外の場合、キャッシュされていないページのみに関心がある場合は、を実装しhook_init()
ます。
これにより、Drupalが完全に起動する前に、ロードプロセスの早い段階で何かを実装するオプションが提供され、プロセスのどのポイントをインターセプトするかについてある程度の柔軟性が得られます。
続行する前にDrupalが特定のポイントまで起動したことを確認する必要がある場合は、を呼び出すことができますdrupal_bootstrap()
。そのドキュメントをクリックすると、ブートストラップのレベルが何からすべてに至るまで利用できます。
そして最後に、Examplesプロジェクトで、特定のサブシステム用に広範囲に文書化されたコードを見ることができます。
フックはphp関数であり、「yourmodulename_hookname」という命名規則に基づいてブロックを構築し、開発者がモジュールを作成できるようにします。
モジュールは、DrupalシステムでCORE機能とカスタム機能の両方を有効にするため、本当に重要です。したがって、モジュールはフックで構成され、Drupalインストールでモジュールがアクティブ化されると、module.inc関数module_invoke_all($ hook)またはmodule_invokeのおかげで、そのフック関数を他のモジュールから呼び出すことができます。
したがって、フックが何であるかを適切に理解するには、実際に手を汚してモジュール開発を試してください。この目的のために、開発者向けのDrupalのサンプルをダウンロードして試してみてください。モジュールの作成にも慣れておく必要があります。
上記の開発者向けの便利なDrupalの例を次に示します。
block_exampleモジュールのhook_block_view()実装例
/**
* @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のブロック作成にアクセスして、Webサイトにカスタムブロックを表示できます。block.moduleには、すべてのモジュールがhook_blockビューを定義できるようにする_block_render_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);
render_exampleモジュールのhook_menu()実装例
/**
* @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,
);
このフックは、DrupalのURLルーティングシステムにリンクされ、モジュールで使用される関連するレンダリングコールバックでURLパターンを定義します。system.moduleから呼び出されます。
ブートストラップについては、基本的に、各ページ要求で実行されることを知る必要があります。このstackoverflowの答えを読むことを本当にお勧めします。ブートストラップとフックがどのように関連しているが分離されているかを説明しています。
Webページの表示に関して、DrupalのWebサイトのHTML表示は、レンダー配列とテーマを使用してほとんど達成されます。
モジュールがmodule_implements()を呼び出す場所http://api.drupal.org/api/drupal/includes%21module.inc/function/module_implements/7 Drupalは、重みに基づいて、正しい名前の関数をすべて正しい順序で起動します。module_implementsを使用するモジュールのドキュメントではhook_menuのようなものを見るため(メニューがメニュー項目を返すように設計されたすべての関数を呼び出す場合)、これらはフック関数と呼ばれます。「フック」という単語は、それを実装するモジュールの名前に置き換えるだけで、Drupalが残りを行います。
drupal_alter()関数もあります。これは、別のフックによって以前に登録されたものを変更できるように、正しく名前が付けられたすべての変更関数を起動します。
通常、変更は参照によって引数を渡すので、オブジェクトを直接編集できますが、通常の「フック」では通常、新しいものを返すことができます。
アイデアは、Drupalにすべての必要なフック関数を呼び出して、処理するために返すものを取得するように要求することにより、任意のモジュール(独自のものを含む)を簡単に拡張できるということです。フック関数を呼び出すモジュールは、フックを実装するモジュールについて何も知る必要はなく、フックを実装するモジュールは、フックを呼び出すモジュールについて何も知る必要はありません。両方のモジュールが知る必要があるのは、返されるデータまたは変更されるデータの構造だけです。
実際には、フックは次の目的で最も一般的に使用されます。
私にとっては、フックとコア(D7)に関しては、module_implements関数がすべてです。理解することが重要だと思うことの1つは、何かを変更するためのフックを作成することで、処理しているデータ構造に何が起こるかについて最後の発言権がまったくないということです。フックは、メニュー、menu_links、ブロック、ノード、ユーザー、エンティティ、レンダー要素など、同じデータ構造に作用する関数の行(キュー)を取得します。
したがって、フックが期待どおりに使用されることを実際に確認するには、自分(フック)が並んでいる場所を知るか、意識する必要があります。これは、小石の重量によって決まります。Drupalコアは、適切な名前のフックを重みの昇順で呼び出すだけで、データに何が起きても起こります。
数時間のヘッドバンギングの後、モジュールの重量が軽すぎて、後続のフックが私がしたことを事実上無効にしたり、すべてをまとめて無視したことを知るためだけに、それは何の効果もないフックを書きました。
よく書かれたフックは、それ自体が最後になるように「人を扱う」ことも「強制する」こともありません。
そして、フックの「ライン」といえば。何年もの間、GoogleでDrupalを検索してきましたが、この画像は可能性のプリプロセスとプロセスフックリストをよく表しているようです。
より簡単な方法で、フックは、開発者が既存のコードを変更せずに、要件に応じて既存の機能を変更するのに役立ちます。PHPの抽象関数に似ています。
例:バスのチケットを予約するためのモジュールを作成しました。あなたのコードによると、チケットが一度予約された場合、ピックアップ場所はそのプロジェクトの要件であった編集できません。ユーザーがピックアップ場所を変更できることを除いて、友人が同様の要件に同じモジュールを必要とするとします。どういうわけか彼はあなたのモジュールを使わなければならず、あなたは彼にコードの変更をさせたくありません。したがって、モジュールを変更せずに変更を実装できるインターフェース(この場合はフック)を提供します。
drupal〜drupal-7では、テーマと同様にモジュール用のフックがあります。フックがどのように機能するかを確認するには、drupal.orgのフックでカスタムフックを作成し、このリンクを確認してください
フック。モジュールがDrupalコアと対話できるようにします。Drupalのモジュールシステムは、「フック」の概念に基づいています。フックはfoo_bar()という名前のPHP関数です。ここで、「foo」はモジュールの名前(ファイル名はfoo.module)であり、「bar」はフックの名前です。