最近我在一个基于Drupal平台的客户端项目上工作。
这项工作最重要的部分是自动从远程源导入数据,但我没有编写脚本来完成工作,而是为Drush创建了一个命令从Drush存储库站点引用

Drush是Drupal的命令行shell和脚本界面,Drupal是一款名副其实的瑞士军刀,旨在让那些花费工作时间在命令提示符下进行攻击的人更轻松。

Drush可以处理Drupal站点的几乎所有方面,从普通的缓存管理到 用户管理,从将Drupal安装打包到makefile到 项目管理等等,包括用于运行sql查询CLI用于开发http服务器以及rsync包装
如果安装了Drush,则通过指定服务器别名(例如drush clear-cache @staging,也可以在远程机器上执行Drush命令

有不同的方法来创建Drush脚本:

  • 使用shebang #!/usr/bin/env drush#!/full/path/to/drush使用 Drush命令预先添加脚本

  • 使用Drush php解释器#!/full/path/to/drush php-script并使用Drush PHP api

  • 编写自定义命令

本指南是关于最后一个案例。
Drush命令很像Rake或Grunt任务,你给它们一个名字(更像是命名空间),Drush指出必须调用什么函数。要创建Drush命令,请执行以下简单步骤

  • 创建一个namespace.drush.inc标准的导入路径

  • 实现namespace_drush_command入口点功能

  • 实现命令功能。按照约定,调用命令函数drush_namespace_commandname

在以下位置搜索命令文件:

  • /path/to/drush/commands 夹

  • 系统范围的drush命令文件夹,例如 /usr/share/drush/commands

  • .drush文件夹中的$HOME文件夹。

  • sites/all/drush 在当前的Drupal安装中

  • 当前Drupal安装中所有已启用的模块文件夹

实现命令

要实现Drush命令,脚本必须实现drush_command挂钩。此函数必须返回包含定义自定义命令的所有信息的数据结构。
作为一个例子,我们将开发一个掷骰子并打印结果的命令。
我们将使用diceroller命名空间和roll-dice命令名称。
这是主钩子函数的实现

<?php
function diceroller_drush_command() {
  $items = array();

  $items['roll-dice'] = array(
    'description' => "Roll a dice for your pleasure.",
    'arguments' => array(
      'faces' => 'How many faces the dice has? Default is 6, max is 100.',
    ),
    'options' => array(
      'rolls' => 'How many times the dice is rolled, default is 1 max is 100',
    ),
    'examples' => array(
      'drush drrd 6 --rolls=2' => 'Rolls a 6 faced dice 2 times',
    ),
    'aliases' => array('drrd'),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
    // see http://drush.ws/docs/bootstrap.html for detailed informations
    // about the bootstrap values
  );

  return $items;
}

该命令很容易以这种方式实现

<?php

function drush_diceroller_roll_dice($faces=6) {
  $rolls = 1;

  if ($tmp = drush_get_option('rolls')) {
    $rolls = $tmp;
  }  

  drush_print(dt('Rolling a !faces faced dice !n time(s)', array(
    '!faces' => $faces,
    '!n' => $rolls
  )));
  // for n=0..$rolls
  // roll the nth dice
  // print the result
}

在这种情况下,我们假设该--rolls选项包含一个数字,但我们可以保证函数参数在实现validate钩子时是有效的(在实际命令函数之前和之后还有其他调用)。

<?php

function drush_diceroller_roll_dice_validate($faces=6) {

  if($faces <= 0) {
    return drush_set_error('DICE_WITH_NO_FACES', dt('Cannot roll a dice with no faces!'));
  }
  if($faces > 100) {
    return drush_set_error('DICE_WITH_TOO_MANY_FACES', dt('Cannot roll a sphere!'));
  }

  $rolls = drush_get_option('rolls');
  if(isset($rolls)) {
    if(!is_numeric($rolls))
      return drush_set_error('ROLLS_MUST_BE_INT', dt('rolls value must be a number!'));

    if($rolls <= 0)
      return drush_set_error('NOT_ENOUGH_ROLLS', dt('What you\'re asking cannot be done!'));

    if($rolls > 100)
      return drush_set_error('TOO_MANY_ROLLS', dt('I\'m not your slave, roll it by yourself!'));
  }

}

如果我们努力工作,跑步drush help roll-dice应该给我们这个输出

Roll a dice for your pleasure.

Examples:
 drush drrd 6 --rolls=2                    Rolls a 6 faced dice 2 times

Arguments:
 faces                                     How many faces the dice has? Default is 6, max is 100.

Options:
 --rolls                                   How many times the dice is rolled, default is 1 max is 100

Aliases: drrd

有关钩子函数常量的完整列表,请参阅Drush api从命令行启动 有关命令示例的完整实现,请参阅drush topic docs-api
drush topic docs-examplecommand