web-dev-qa-db-fra.com

Quel est le concept de base derrière les crochets?

Je suis intermédiaire en PHP. Pour perfectionner mes compétences, je commence à apprendre Drupal 7. Tout en apprenant Drupal concepts d'architecture, les termes hooks et bootstrapping m'ont intrigué un lot. J'ai lu le livre "Pro Drupal development" et de la documentation sur drupal.org, mais c'est tellement avancé pour moi d'apprendre comment les hooks fonctionnent dans Drupal pour afficher la page Web.

Quelqu'un peut-il me dire ce que sont les crochets en termes simples?

120
GiLL

Les autres réponses sont excellentes, précises, détaillées, mais je ne suis pas sûr que ce soient les "mots simples" expliquant les os nus du concept que le demandeur recherchait.

Je pense aux crochets comme un point où le code s'arrête et crie " Quelqu'un d'autre a-t-il quelque chose à ajouter ici? ". Tout module peut avoir une fonction qui y répond et est déclenchée avec les données appropriées qui lui sont transmises à ce point du code.

Un bel exemple simple est hook_node_delete () . N'importe quel module peut l'utiliser pour faire bouger les choses chaque fois qu'un nœud est supprimé. Les documents vous indiquent que ce crochet transmet au module l'objet de ce nœud supprimé pour travailler, et décrit d'autres informations utiles telles que le moment exact de son appel (par exemple, c'est avant que les données du nœud ne soient réellement supprimées de la base de données) , et où dans le code de Drupal le hook est appelé (qui peut être plus d'un endroit).

Vous pouvez explorer les hooks existants et découvrir quelles données leur sont transmises en explorant les choses commençant par "hook_" dans le Drupal api .

Les hooks fonctionnent selon des conventions de nom: en utilisant hook_node_delete Comme exemple, lorsque le processus de suppression de noeud atteint le point où le hook est appelé, pour chaque module avec une fonction comme celle-ci [modulename]_node_delete() où le Word hook dans le nom du hook est remplacé par le nom du module (par exemple my_amazing_module_node_delete()), ces fonctions sont appelées.

Pourquoi? Ainsi, n'importe quel module peut faire n'importe quoi à ces points clés: par exemple, vous pouvez regarder le nœud supprimé et faire des choses s'il remplit une certaine condition (par exemple, envoyer un e-mail à un administrateur ou lancer un long processus).

Certains crochets vous permettent de modifier des éléments qui ont été générés juste avant leur traitement. Par exemple, hook_menu_alter () vous transmet les éléments de menu actuels que le système a générés. N'importe quel module peut définir une fonction some_modulename_menu_alter () et les regarder, éventuellement les changer (en supprimer, en ajouter, les trier ...) et passer le menu nouvellement modifié.

C'est simple, vraiment puissant et est au cœur de la façon dont Drupal fonctionne comme un système modulaire. Les implémentations de hooks sont au cœur de la plupart des modules Drupal.

Lorsque vous parcourez le code d'un module Drupal, vous pouvez repérer les fonctions qui proviennent des hooks (par opposition aux fonctions qui sont simplement appelées depuis le code du module lui-même), comme le Drupal applique une convention selon laquelle chaque implémentation d'un hook a un commentaire devant lui comme ceci (notez le bit "Implements hook _..."):

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

Certains modules qui agissent comme des API définissent leurs propres crochets. Par exemple, Vues définit de nombreux crochets qui vous permettent d'ajouter, de lire et de modifier des données à différents moments du processus de création ou d'affichage d'une vue. Vous pouvez trouver des informations sur les hooks créés dans des modules personnalisés à partir de deux endroits (en supposant que le module respecte les conventions, etc.):

  • Le code et les commentaires dans le fichier modulename.api.php Dans le dossier du module
  • drupalcontrib.org - par exemple, voici leur liste de modules D7 sur lesquels ils ont des informations, et voici leur page Vues crochets

Le bootstrap est, comme d'autres l'ont expliqué, essentiellement un démarrage - je ne reproduirai pas les autres bonnes explications claires.

107

Les crochets sont principalement des implémentations des modèles Visitor et Observer .

L'une des implémentations de hooks les plus courantes est hook_men , qui permet aux modules d'enregistrer de nouveaux chemins dans un système Drupal.

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

Un modèle très fréquent dans Drupal a un [DATATYPE]_info crochet, et un [DATATYPE]_info_alter crochet. Si vous souhaitez créer un nouveau type de champ, vous implémenterez le crochet field_info - approprié, et si vous voulez en manipuler un existant, vous implémenterez le field_info_alter - correspondant crochet.

Edit: Comme le souligne Chx dans les commentaires, le modèle d'observation est objet orienté, ce qui Drupal 7 est toujours, principalement, pas. Il y a cependant une page wiki, Programmation Drupal dans une perspective orientée objet (Créé par JonBob le 4 avril 2005), qui explique comment = Drupal utilise malgré tout des modèles de code orientés objet. Il est intéressant de noter qu'il mentionne les observateurs, mais pas les visiteurs.

Note sur Drupal 8 Ceci est encore assez tôt et est sujet à changement, mais je veux ajouter cela tout en les hooks sont depuis un certain temps la norme de facto pour ajouter des fonctionnalités à Drupal, le concept de plugins deviendra beaucoup plus visible dans Drupal 8, et donnera nous de nouvelles façons d'interagir avec Core. Pertinentes problème , et documentation .

52
Letharion

En termes simples, les crochets sont des sortes de ponts qui permettent aux modules d'interagir les uns avec les autres, de modifier la structure et les données les uns des autres, de fournir de nouvelles données, etc.

Dans la plupart des cas, le mot hook_ dans les noms de fonction est remplacé par le nom de votre module, ce qui permet à votre module d'exploiter le fonctionnement d'un autre module. Par exemple, un module de base drupal appelé "nœud" invoque divers hooks. L'un d'eux est hook_node_update qui est invoqué chaque fois qu'un nœud existant est mis à jour. Lorsque ce hook est invoqué, l'implémentation de votre module (disons que nous l'appelons mymodule) de hook_node_update est appelé, qui dans ce cas sera une fonction du fichier .module de votre module appelée mymodule_node_update (Évidemment, cette fonction peut se trouver dans n'importe quel fichier du dossier de votre module tant qu'elle est également incluse dans le fichier .module). Ce hook recevra également les paramètres (variables) nécessaires qu'il pourra utiliser, modifier et/ou retourner à la fonction qui a appelé le hook.

Quand j'ai commencé à apprendre Drupal, j'étais dans le même bateau que vous, c'est un peu difficile à comprendre au début, mais une fois que vous l'avez compris, c'est tellement simple et intuitif. Bonne chance.

32
Beebee

L'un des développeurs principaux a écrit il y a quelque temps un article intitulé "Programmation Drupal dans une perspective orientée objet" . Il explique bien comment les crochets peuvent être considérés comme implémentant la plupart des modèles de conception . La meilleure explication des crochets provient de l'article:

Le système de crochet de Drupal est la base de son abstraction d'interface. Les crochets définissent les opérations qui peuvent être effectuées sur ou par un module. Si un module implémente un hook, il conclut un contrat pour effectuer une tâche particulière ou retourner un type particulier d'informations lorsque le hook est appelé. Le code appelant n'a pas besoin de savoir quoi que ce soit sur le module ou la façon dont le hook est implémenté afin d'obtenir un travail utile en appelant le hook.

31
mpdonadio

Le Bootstrap est le processus Drupal passe par pour construire une page, en cours d'exécution sur tout le code du noyau, du thème et du module dans l'ordre).
C'est essentiellement comment Drupal démarre et se prépare à faire son travail en tant que CMS.

C'est intelligent, en ce sens qu'il nous permet de placer des crochets n'importe où dans nos modules et thèmes, et le processus bootstrap s'assure qu'ils s'exécutent au bon moment).
Par exemple, si vous utilisez 'hook_form_alter' pour ajouter une case à cocher personnalisée à un formulaire, Drupal's bootstrap s'assurera qu'il exécute ce code, juste avant de rendre votre formulaire.

Un problème avec le bootstrap est que le processus entier prend du temps à s'exécuter, même si vous ne renvoyez qu'une petite quantité de données. Lorsque vous utilisez Drupal avec le module de services en tant qu'API et renvoyant de nombreuses petites réponses XHTML ou JSON, parcourant l'intégralité de bootstrap n'est pas très performant. Certaines personnes intelligentes cherchent des moyens intelligents de contourner cela pour Drupal 8.

Mais pour le rendu normal des pages Drupal, le processus bootstrap fonctionne très bien, il utilise le système de mise en cache Drupals pour accélérer les choses et vous donne un contrôle total sur chaque partie de votre site. Si vous trouvez votre site lent, vous pouvez toujours utiliser quelque chose comme APC ou MemCached pour accélérer les choses.

J'espère que ma réponse était exacte et explique les choses simplement pour vous, je ne suis pas un expert, mais je pense que c'est comme ça que ça fonctionne.

20
medden

Bootstrap est le processus pendant lequel Drupal s'initialise lui-même; le processus comprend en fait:

  • Définition de l'erreur et des gestionnaires d'exceptions
  • Initialisation de la valeur de certaines variables globales de spécification contenues dans $_SERVER
  • Initialisation de certaines variables avec init_set()
  • Recherche de la version en cache de la page à diffuser
  • Initialisation de la base de données
  • Définition des gestionnaires qui chargent les fichiers lorsqu'une classe ou une interface est introuvable
  • Initialisation des variables Drupal
  • Initialisation de la session PHP
  • Initialisation de la variable de langue
  • Chargement des modules activés

Certaines des opérations que j'ai décrites sont spécifiques à Drupal 7, ou supérieur, mais la plupart des opérations sont indépendantes de la version Drupal.

Un hook est une fonction PHP qui peut être appelée à partir de Drupal ou de modules tiers, si nécessaire pour effectuer une tâche. Au lieu d'avoir une liste préfixée de fonctions à appeler, la liste est construite vérifier les modules activés et les fonctions qu'ils implémentent.
Par exemple, Drupal utilise hook_node_update(); lorsqu'un nœud est enregistré avec node_save () , le code suivant est exécuté .

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

Ce que fait node_invoke () est le suivant:

  • Obtenir la liste de tous les modules activés
  • Vérifier si les modules activés ont une fonction dont le nom se termine par "_node_update" et commence par le nom court du module
  • Appel de cette fonction, passage de $node Comme paramètre

Les hooks peuvent enregistrer leurs propres données dans une base de données ou modifier la valeur renvoyée par une fonction. Le dernier cas est, par exemple, ce qui se passe avec hook_form_alter () , qui modifie la valeur de $form Passée en référence à drupal_prepare_form () .

Les crochets Drupal sont généralement invoqués à l'aide de trois fonctions:

drupal_alter() est la fonction utilisée pour appeler des hooks spécifiques dont le but est de modifier les données qui leur ont été transmises comme référence, comme hook_form_alter () , hook_hook_info_alter () et hook_tokens_alter () .

Il existe d'autres fonctions qui sont utilisées pour appeler des hooks, comme node_invoke(), mais ces fonctions utilisent essentiellement l'une des fonctions que j'ai énumérées précédemment.

14
kiamlaluno

Les crochets sont coupes de points et module_invoke_all est le tisserand (hélas, nous ne sommes pas clairs dans la mise en œuvre et il existe d'autres fonctions de tissage). Pour autant que je sache, Drupal est le seul système à implémenter AOP avec les fonctions PHP.

Voir une autre explication sur Comment fonctionne AOP dans Drupal?

11
user49

Si vous voulez voir les crochets Drupal vous permet d'appeler, allez à api.drupal.org , tabulez vers la boîte de recherche et tapez 'hook_'. Cette vous donnera une grande liste de la plupart des crochets définis par Drupal. Faites la même chose pour '_alter' et voyez encore plus.

La page Node API Hooks propose une liste chronologique de tous les hooks invoqués pendant les opérations de noeud. Vous pouvez voir le module Node et les systèmes Entity and Field se donner mutuellement la parole lors de l'appel des hooks.

Par exemple, si vous faites défiler vers le bas et regardez la section pour node_load(): Le module Node vous donnera un hook_load (), puis passera le contrôle au système d'entité qui charge certains champs. Il y a tout un hôte de crochets de champs non répertoriés, puis lorsque cela est terminé, le système d'entités appelle hook_entity_load(), avant de renvoyer le contrôle à Node qui appelle hook_node_load().

Cela donne à votre code la possibilité d'agir sur le nœud en question lors de son chargement, morceau par morceau. Apprendre ces crochets et quand et pourquoi ils sont appelés fait partie de l'aventure du codage Drupal. :-)

D'autres systèmes ont également des crochets. Tels que hook_init() et hook_boot() . Cela arrive à la partie bootstrap de votre question. hook_boot() est invoquée par Drupal avant le chargement du système de mise en cache. Donc, si votre module doit faire quelque chose avant Drupal a vraiment démarré, et vous voulez que votre code s'exécute indépendamment de la mise en cache, alors vous implémenteriez hook_boot(). Sinon, si vous ne vous souciez que sur les pages qui ne sont pas mises en cache, vous implémentez hook_init().

Cela vous donne la possibilité d'implémenter quelque chose au début du processus de chargement, avant que Drupal ait complètement démarré, tout en vous donnant une certaine flexibilité quant au point du processus que vous souhaitez intercepter.

Si vous devez vous assurer que Drupal a démarré à un certain point avant de continuer, vous pouvez appeler drupal_bootstrap() . Si vous cliquez dessus documentation vous pouvez voir les niveaux bootstrap disponibles, de rien à tout.

Et, enfin, vous pouvez voir du code largement documenté pour un sous-système donné sur le Exemples de projet .

5
paul-m

Les crochets sont des fonctions php, des blocs de construction basés sur les conventions de dénomination "votrenom_module", ils sont destinés à faciliter la capacité des développeurs à créer des modules .

Les modules sont la vraie affaire car ils permettent à la fois des fonctionnalités CORE et personnalisées dans votre système Drupal. Ainsi, les modules sont constitués de crochets et lorsqu'un module est activé dans votre Drupal, ses fonctions hooks peuvent être appelées depuis d'autres modules grâce à la fonction module.inc module_invoke_all ($ hook) ou module_invoke.

Par conséquent, pour bien comprendre ce que sont les crochets, vous devriez vraiment vous salir les mains et essayer le développement de modules. Pour cela, commencez par télécharger et essayer certains Exemples Drupal pour les développeurs , vous devriez également vous familiariser avec création de modules .

Voici quelques exemples utiles de Drupal pour les développeurs mentionnés ci-dessus:

hook_block_view () exemple d'implémentation dans le module 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)');

Ce crochet vous donne accès à la création de blocs Drupal pour afficher des blocs personnalisés sur votre site Web. C'est possible car le block.module a une fonction _ block_render_block qui permet à tous les modules de définir leur vue hook_block (notez la dernière ligne 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 () exemple d'implémentation dans le module 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,
  );

Ce hook est lié au système de routage d'url de Drupal et définit les modèles d'url avec les rappels de rendu associés utilisés par votre module. Il est invoqué à partir de system.module .

À propos du bootstrap, il vous suffit de savoir qu'il est exécuté à chaque demande de page. Je vous conseille vraiment de lire cette réponse stackoverflow , elle explique comment bootstrap et les hooks sont liés mais séparés.

En ce qui concerne l'affichage de la page Web, l'affichage HTML du site Web de Drupal est principalement réalisé avec tableaux de rend et le thème.

5
B2F

Partout où un module appelle module_implements () http://api.drupal.org/api/drupal/includes%21module.inc/function/module_implements/7 Drupal will déclenchez toutes les fonctions correctement nommées dans le bon ordre en fonction de leur poids. Celles-ci sont appelées fonctions de hook car dans la documentation des modules qui utilisent module_implements, vous voyez des choses comme hook_menu (lorsque le menu appelle toutes les fonctions conçues pour renvoyer des éléments de menu). Le mot "hook" doit juste être remplacé par le nom du module qui l'implémente et Drupal fait le reste.

Il existe également une fonction drupal_alter () qui déclenche toutes les fonctions alter correctement nommées, avec l'intention de vous permettre de modifier des choses qui ont été précédemment enregistrées par un autre hook.

Généralement, alters transmettra les arguments par référence afin que vous puissiez modifier l'objet directement, tandis que les crochets "normaux" vous permettent généralement de retourner de nouvelles choses.

L'idée est que n'importe quel module (y compris le vôtre) peut facilement être étendu en demandant à Drupal d'appeler toutes les fonctions de hook requises et de récupérer ce qu'elles renvoient pour être traitées. Le module appelant les fonctions de hook n'a pas besoin de savoir quoi que ce soit sur les modules qui implémentent les hooks, et les modules implémentant le hook n'ont pas vraiment besoin de savoir quoi que ce soit sur le module appelant le hook. La seule chose que les deux modules doivent savoir est la structure des données être retourné ou modifié.

Dans la pratique, les crochets sont généralement utilisés pour:

  • répondre aux événements, comme hook_user_login est appelé lorsqu'un utilisateur se connecte
  • enregistrer quelque chose de nouveau qui peut être utilisé pour étendre le système comme hook_menu
  • thème/rendu html ou créer/valider/soumettre des formulaires
2
David Meister

Pour moi, il s'agit de la fonction module_implements en ce qui concerne les crochets et le noyau (D7). Une chose que je pense qu'il est crucial de comprendre est qu'en écrivant un crochet pour modifier quelque chose, vous n'avez en aucun cas le dernier mot sur ce qui arrive aux structures de données avec lesquelles vous avez affaire. Votre hook entre simplement dans la ligne (file d'attente) des fonctions qui agissent également sur les mêmes structures de données, qu'il s'agisse de menus, de menus_links, de blocs, de nœuds, d'utilisateurs ou de toute entité ou élément de rendu.

Donc, pour vraiment voir vos crochets être utilisés d'une manière attendue, vous devez savoir ou savoir où vous en êtes (votre crochet). Ceci est déterminé par le poids de votre mondule. Drupal core appelle simplement les hooks correctement nommés dans l'ordre de poids croissant et tout ce qui arrive aux données se produit.

J'ai écrit des crochets avant qui n'avaient aucun effet, seulement pour apprendre après des heures de headbanging que le poids de mon module était trop léger et que les crochets subséquents ne faisaient pas ce que je faisais ou ignoraient tout cela ensemble.

Un hook bien écrit ne se "manipulera pas" ou "ne se forcera" pas à être le dernier mais "placera Nice avec les autres" en s'assurant qu'ils maintiennent les structures de données comme prévu par le reste des hooks sur la ligne.

Et en parlant de "The Line" de crochets. Au fil des ans, j'ai recherché google pour Drupal trucs, cette image semble être une bonne représentation de la liste des possibilités de prétraitement et de hook de processus).
enter image description here

0
Dan Shumaker

Crochets. Permettre aux modules d'interagir avec le noyau Drupal. Le système de modules de Drupal est basé sur le concept de "hooks". Un hook est une fonction PHP nommée foo_bar (), où "foo" est le nom du module (dont le nom de fichier est donc foo.module) et "bar" est le nom du hook.

0
Amrendra Mourya

De manière beaucoup plus simple, les hooks aident le développeur à modifier les fonctionnalités existantes en fonction des exigences sans apporter de modifications au code existant. Plus comme la fonction abstraite en php.

Exemple: Vous avez créé un module pour réserver un ticket de bus. Selon votre code, si le billet est une fois réservé, le lieu de ramassage n'est pas modifiable, ce qui était votre exigence pour ce projet.Supposez que votre ami a besoin du même module pour une exigence similaire, à l'exception du fait que l'utilisateur peut changer le lieu de ramassage. D'une manière ou d'une autre, il doit utiliser votre module et vous ne voulez pas qu'il modifie le code. Vous fournissez donc une interface (hook dans notre cas) où il pourrait implémenter ses modifications sans apporter de modifications dans votre module.

Dans drupal jusqu'à drupal-7, nous avons des hooks pour les modules ainsi que les thèmes. Pour savoir comment fonctionne le hook, vérifiez est drupal.org hooks pour créer un hook personnalisé, vérifiez ceci lien

0
Anamika

Vous avez beaucoup de réponses ci-dessus mais je veux donner une réponse de manière beaucoup plus simple pour comprendre le concept très basique derrière les crochets. Les crochets sont en fait des fonctions intégrées dans drupal core pour gérer différentes choses et faire différents travaux dans core, vous pouvez synchroniser vos propres fonctions avec ces fonctions intégrées de drupal = core pour ajouter leurs fonctionnalités dans vos propres fonctions en appelant différents hooks.

J'espère que vous comprendrez!

0
user25892