<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>hook | 伪架构师</title>
    <link>/tags/hook/</link>
      <atom:link href="/tags/hook/index.xml" rel="self" type="application/rss+xml" />
    <description>hook</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Wed, 05 Aug 2015 10:32:19 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>hook</title>
      <link>/tags/hook/</link>
    </image>
    
    <item>
      <title>Drupal 7 - Hook执行顺序</title>
      <link>/post/hook-order-in-drupal7/</link>
      <pubDate>Wed, 05 Aug 2015 10:32:19 +0800</pubDate>
      <guid>/post/hook-order-in-drupal7/</guid>
      <description>&lt;p&gt;没有什么文档来说明这个事情，在阅读 &lt;code&gt;&amp;quot;module_implements&amp;quot;&lt;/code&gt; 代码的过程中，我获得了变更 Hook 执行顺序的灵感。&lt;/p&gt;

&lt;p&gt;下面是 &lt;code&gt;module_implements&lt;/code&gt; 中的代码片段&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Allow modules to change the weight of specific implementations but avoid
// an infinite loop.
if ($hook != &#39;module_implements_alter&#39;) {
drupal_alter(&#39;module_implements&#39;, $implementations[$hook], $hook);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;所以只要简单的实现一下 &lt;code&gt;&amp;quot;module_implements_alter&amp;quot;&lt;/code&gt; ，在代码中对 Module 列表进行重新排序，也就改变了 Hook 的执行顺序。&lt;/p&gt;

&lt;p&gt;下面是示例代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;function mymodule_module_implements_alter(&amp;amp;$module_list, $context){
    if($context === &amp;quot;node_insert&amp;quot;){
    $temp = $module_list[&#39;mymodule&#39;];
    // Removing the mymodule key/value
    unset($module_list[&#39;mymodule&#39;]);
    // Adding the mymodule key value as the last member in the list
    $module_list[&#39;mymodule&#39;] = $temp;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里需要注意 &lt;code&gt;module_list&lt;/code&gt; 参数是引用传递。&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>最佳实践：hook_cron</title>
      <link>/post/best-practice-hook_cron/</link>
      <pubDate>Wed, 05 Aug 2015 10:32:19 +0800</pubDate>
      <guid>/post/best-practice-hook_cron/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://www.thirdandgrove.com/best-practices-for-using-drupals-cron-system-hook_cron&#34; target=&#34;_blank&#34;&gt;Best practices for using Drupal’s cron system: hook_cron()
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;如果你成功的设置了 &lt;a href=&#34;https://drupal.org/cron&#34; target=&#34;_blank&#34;&gt;Drupal Cron&lt;/a&gt;，&lt;a href=&#34;https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_cron/7&#34; target=&#34;_blank&#34;&gt;hook_cron()&lt;/a&gt; 提供了一种不依赖页面请求的方式来进行后台任务，然而，Cron 的滥用也有可能造成性能问题，甚至威胁数据完整性。&lt;/p&gt;

&lt;p&gt;这里提供一些我们在实际工作中得来不易的一些 Cron 方面的最佳实践：&lt;/p&gt;

&lt;h2 id=&#34;第一条-用变量控制-cron&#34;&gt;第一条：用变量控制 Cron。&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;hook_cron()&lt;/code&gt; 的每一次调用都封装在一个变量检查的条件之内，这个变量的缺省值是TRUE，想要禁止这个 CRON，只要把这个变量创建起来并赋值为 False 即可，当你的 CRON 过程失控或者消耗太多资源时，这一手段是非常有效的。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;/**
  * Implements hook_cron().
  */
function example_cron() {
  if (variable_get(&#39;example_process_users_during_cron&#39;, TRUE)) {
    module_load_include(&#39;inc&#39;, &#39;example&#39;);
    example_process_users();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;第二条-在-inc-文件中实现逻辑&#34;&gt;第二条：在 inc 文件中实现逻辑。&lt;/h2&gt;

&lt;p&gt;需要注意的是，Drupal 很重：每次页面请求都会载入所有被启用的 Module 文件。所以 module 文件里只应该包含每次页面请求都需要执行的部分，Cron 代码运行频率很低，因此不应包含在 module 文件里。这也是一条适用于其他模块开发的最佳实践。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;（这是快速得知一个模块作者是否真正了解 Drupal 的办法。）&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&#34;第三条-drush-命令&#34;&gt;第三条：Drush 命令。&lt;/h2&gt;

&lt;p&gt;即使你不想使用 Drush 来运行 Cron，也应该创建一个简单的 Drush 命令来运行你的代码。在你的 CRON 过程消耗过高的时候，可以利用前面第一条说的方法禁用这条 CRON 命令，然后做一个系统的 Cron 过程，在恰当的时机来利用 drush 直接运行这段代码。可以根据开销情况，用这种方法来单独调节每个 Cron 任务。这是一种未雨绸缪的措施。&lt;/p&gt;

&lt;p&gt;下面是 &lt;code&gt;example.drush.inc&lt;/code&gt; 文件里的示例代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;/**
  * Implements hook_drush_command().
  */
function example_drush_command() {
  return array(
    &#39;example-process-users&#39; =&amp;gt; array(
      &#39;description&#39; =&amp;gt; dt(&#39;Process the user accounts.&#39;),
      &#39;alias&#39; =&amp;gt; array(&#39;epu&#39;),
    ),
  );
}

/**
  * Process user accounts.
  */
function drush_example_example_process_users() {
  module_load_include(&#39;inc&#39;, &#39;example&#39;);
  example_process_users();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;第四条-批处理&#34;&gt;第四条：批处理。&lt;/h2&gt;

&lt;p&gt;在开发之前，不要仅仅想着今天或这个月的处理量，而应该想想一年甚至更大量的情况，确保你的处理效率能够适应数据的增长。&lt;/p&gt;

&lt;p&gt;这意味着，需要在代码重一次处理大批记录，可以用一个变量来指定每次的处理量，或者可以哦能够队列的方式来处理。&lt;/p&gt;

&lt;h2 id=&#34;第五条-我真的需要-cron-么&#34;&gt;第五条：我真的需要 Cron 么？&lt;/h2&gt;

&lt;p&gt;Drupal 的 &lt;code&gt;hook_cron()&lt;/code&gt; 是一个很适合处理简单，常见任务的方式。不过如果你要处理大量数据，或者复杂任务，你应该使用一些更专门的方法，例如 Drupal 7 的 &lt;a href=&#34;https://api.drupal.org/api/drupal/modules!system!system.queue.inc/group/queue/7&#34; target=&#34;_blank&#34;&gt;Queue System&lt;/a&gt;甚至 Drupal 之外的方案，例如 &lt;a href=&#34;http://jenkins-ci.org/&#34; target=&#34;_blank&#34;&gt;Jenkins CI&lt;/a&gt;。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
