You are here

5.2 钩子的执行顺序

admin 的头像
Submitted by admin on 星期四, 2015-05-28 09:54

  作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

  前面我们在Drupal概念中讲到钩子,现在进一步的对其进行分析,掌握了Drupal的钩子机制,熟悉各种常用的钩子,这是Drupal开发过程中的必备条件。

 

    钩子的触发,通常使用module_invoke_all来完成,这是一种常用的方式,但是还存在其它的方式。比如在引导指令阶段,就使用了bootstrap_invoke_all触发hook_boot钩子。代码如下:

   bootstrap_invoke_all('boot');

   

    而在node_build_content函数中,hook_node_view_alterhook_entity_view_alter钩子的触发,则是使用drupal_alter完成的,代码如下:

    drupal_alter(array('node_view', 'entity_view'), $build, $type);

 

   而hook_field_prepare_viewhook_field_formatter_prepare_view钩子的触发,使用的代码分别是:

_field_invoke_multiple('prepare_view', $entity_type, $prepare);

_field_invoke_multiple_default('prepare_view', $entity_type, $prepare, $view_mode);

 

    注意,这两个都是内部函数,专门用于field相关的模块。后者对前者作了封装,最终将使用field_default_prepare_view()来触发hook_field_formatter_prepare_view钩子。

 

    这些触发钩子的函数,尽管名字各不相同,但是里面的核心代码,是一致的。

 

 foreach ($modules as $module) {  

    $function = $module . '_hookname';

    if (function_exists($function)) {

      $function();

    }

  }  

   

    如果多个函数都实现相同的钩子,那么这些钩子之间的执行顺序是怎么决定的呢?Drupal首先会使用模块的重量进行排序,按照顺序依次执行。重量越小,越靠前;重量越大,越靠后。但是通常情况下,模块的重量都默认为0。在重量相同的情况下,则按照模块名字的字母顺序进行排列。比如,我们使用form_alter模块修改特定表单,如果有多个模块同时修改了该表单,那么form_alter钩子的执行顺序将会对结果产生影响。而默认的按模块名字的字母顺序执行,有时候并不能得到我们想要的结果,这个时候我们可以调整模块本身的重量。示例代码如下(这里假定模块名字为module_name):

db_update('system')  

  ->fields(array(    

    'weight' => 999,      

  ))  

  ->condition('name', 'module_name')  

  ->execute();

 

    我画了一张钩子执行顺序的流程图,希望能够方便大家理解构字的执行顺序。

1.png 

                   钩子执行顺序图

 

 

总结

读完本章以后,你应该能够

理解Drupal是什么,

Drupal核心的文件结构、

Drupal常用术语,

Drupal处理http请求的大致流程,

引导指令流程,

钩子回调流程。