Коротко о Batch API.

Версия Друпала:
6.x

Пакетные операции дают возможность обрабатывать формы в течении нескольких запросов. Это предотвращает обрыв обработки изза тайм-аута РНР. Также пользователю предоставляется информация о ходе осуществления текущих операций.


Утверждают, что в первую очередь batch был разработан для гармоничной интеграции с Forms API, хотя часто его используют в обычных скриптах таких как update.php.
Представим, что нам необходимо осуществить обработку большого количества данных. Для начала мы создадим страницу в hook_menu.

<?php
/**
* Batch form
*/
function module_brand_batch(&$form_state) {
  
$form['submit'] = array(
    
'#type'         => 'submit',
    
'#value'        => t('Start batch'),
    
'#description' => t("Make some operations"),
    
'#submit'      => array('module_batch_submit'),
  );
  return 
$form;
}
?>

На форме отобразили кнопку для запуска пакетных операций. Для удобства на форме можно размещать submit'ы для всех применяемых обработок. после submit'а формы исполняется функция module_batch_submit().

<?php
/**
* batch submit function
*/
function module_batch_submit($form, &$form_state) {
  
$batch = array(
    
'title' => t('Process'),
    
'init_message' => t('Process'),
    
//В следующем парметре возможно использования таких placeholders: @current, @remaining,                 @total, @percentage, @estimate and @elapsed. По умолчанию - t('Completed @current of @total.')
    
'progress_message' => t('In progress @current'),
    
//По умолчанию значение - t('An error has occurred.')
    
'error_message' => t('Warning! Error!'),
    
'operations' => array(
    array(
'operations_function', array()),
    ),
    
'finished' => 'module_finished_callback',
    
//Путь к файлу где находится функция указанная в 'operations' и 'finished'
    
'file' => 'module.inc',
  );
  
batch_set($batch);
  
batch_process();
}
?>

Такая запись обеспечит вызов обработки. Формируем массив $batch, в котором указываем название, функцию выполняющую обработку и функцию завершения обработки. batch_set() — открывает новую обработку. batch_process() — совершает обработку.

<?php
/**
* batch
*/
function operations_function(&$context) {
  if (empty(
$context['sandbox'])) {
    
//задаем стартовые переменные, в переменной $context['sandbox']['max'] указываем 
    //количество элементов
    
$context['sandbox']['progress'] = 0;
    
$context['sandbox']['current_node'] = 0;
    
$context['sandbox']['max'] = db_result(db_query("SELECT COUNT(`nid`) FROM {node}"));
  }
  
$limit 10;
  
// указываем количество обратавыемых элементов за шаг. Чем меньше тем медленее но 
  //надежнее
  
$result db_query_range("SELECT `nid` FROM {node} WHERE `nid` > %d"$context['sandbox']['current_node'], 0$limit);
  while (
$row db_fetch_object($result)) {
    
$node node_load($row->nidNULLTRUE);
    
$context['results'][] = $title '-' $nid;
    
$context['sandbox']['progress']++;
    
$context['sandbox']['current_node'] = $nid;
    
$context['message'] = $node->title
  
}
  if (
$context['sandbox']['progress'] != $context['sandbox']['max']) {
    
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}
?>

Также описываем функцию завершения операций.

<?php
/**
* finishig of batch
*/
function module_finished_callback($success$results$operations) {
  if (
$success) {
    
$message 'Process finished success';
  }
  else {
    
$error_operation reset($operations);
    
$message t('An error occurred while processing %error_operation with arguments: @arguments',     array('%error_operation' => $error_operation[0], '@arguments' => print_r($error_operation[1], TRUE)));
  }
  
drupal_set_message($message);
}
?>

Функция завершения проверяет успешно ли прошли операции обработки и выдает сообщение.
Тэги:
batch