バッチ処理を設定します。
バッチ処理を設定することによって、PHP のタイムアウトによって途中で中断されることなく、一度の送信で複数のページリクエストにわたって処理されるようなフォームの実装が可能になります。処理の間、ユーザーには処理の進捗状況を示すプログレスバーが表示されます。

この API は主に、フォーム API のワークフローにおいて使いやすいように設計されていますが、必ずしもフォームを使用しないスクリプト (update.php のような) や、単純にページコールバックで使用することもできます(但しページコールバックでの使用は控え目にすべきでしょう)。
例:
<?php
$batch = array(
'title' => t('Exporting'),
'operations' => array(
array('my_function_1', array($account->uid, 'story')),
array('my_function_2', array()),
),
'finished' => 'my_finished_callback',
'file' => 'path_to_file_containing_myfunctions',
);
batch_set($batch);
// フォームのサブミットハンドラ以外で必要
// batch_process の設定
batch_process('node/1');
?>バッチの 'title'、'init_message' 、 'progress_message' 、 もしくは 'error_message' にユーザからの入力文字列を含める場合は、batch_set() をコールする前に check_plain() や filter_xss() 等のフィルター関数で事前にサニタイズしておくことが必要です。さらに $context の 'results' や 'message' など、バッチ処理から返されるメッセージにユーザからの入力文字列を含める場合も同様です。
バッチ処理のサンプル:
<?php
// 指定したタイプ、指定したユーザーのノードをロードする単純な例
function my_function_1($uid, $type, &$context) {
// $context 配列は実行時のコンテキスト配列を収集します。(読み)
// カレントオペレーションの「返り値」でもあります。 (書き)
// 以下のキーが使用できます。 :
// 'results' (読み / 書き): バッチ処理によってこれまでに収集された
// 結果の配列です。カレントオペレーションでは現在の結果を追加できます。
// 'message' (書き): 進捗状況のページに表示されるメッセージです。
// 以下のキーは反復処理が必要な場合に使用できます。 :
// 'sandbox' (読み / 書き): 反復処理の間、永続的に使用するデータを
// 格納する配列で、自由な用途に使用できます。$_SESSION の代わりに
// 使用することが推奨されます。バッチ処理の間、ユーザーが複数の
// ウインドウを立ち上げた場合を想定すると、$_SESSION を使うことは
// 安全ではありません。
// 'finished' (書き): 処理の進捗状況のパーセンテージを表す 0 と 1 の
// 間の浮動小数点数です。 1 (もしくは設定なし) は処理が完結したと
// いうことになり、バッチ処理は次のオペレーションに進みます。
$node = node_load(array('uid' => $uid, 'type' => $type));
$context['results'][] = $node->nid . ' : ' . check_plain($node->title);
$context['message'] = check_plain($node->title);
}
// さらに高度な例: すべてのノードをロードします。そうとう時間がかかり、
// 反復処理が必要な場合です。
function my_function_2(&$context) {
if (empty($context['sandbox'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField();
}
$limit = 5;
$result = db_select('node')
->fields('node', array('nid'))
->condition('nid', $context['sandbox']['current_node'], '>')
->orderBy('nid')
->range(0, $limit)
->execute();
foreach ($result as $row) {
$node = node_load($row->nid, NULL, TRUE);
$context['results'][] = $node->nid . ' : ' . check_plain($node->title);
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $node->nid;
$context['message'] = check_plain($node->title);
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
?>'finished' コールバックの例:
<?php
function batch_test_finished($success, $results, $operations) {
// 'success' パラメータはPHP の致命的エラーが検出されなかったことを意味します。
// その他のエラーマネジメントには 'results' が使用されます。
if ($success) {
$message = format_plural(count($results), 'One post processed.', '@count posts processed.');
}
else {
$message = t('Finished with an error.');
}
drupal_set_message($message);
// リダイレクト先のページのデータの提供は $_SESSION を通して行われます。
foreach ($results as $result) {
$items[] = t('Loaded node %title.', array('%title' => $result));
}
$_SESSION['my_batch_results'] = $items;
}
?>