Drupal 10中hook_update无法一次性批量更新700个节点状态问题求助
Drupal 10 hook_update 批量更新节点状态不完整的解决方案
这个问题是因为hook_update有默认的执行时间和内存限制,一次性处理700个节点容易触发超时或内存溢出,导致Drupal中断执行,所以每次只能处理一部分。最靠谱的解决办法是用Batch API来分批次处理,它会自动处理分片、进度跟踪,避免超时问题。
直接上可用的代码示例:
/** * 更新指定内容类型的所有节点为已发布状态。 */ function mymodule_update_8001(&$sandbox) { // 初始化batch沙盒 if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; $sandbox['current_nid'] = 0; // 统计需要更新的节点总数(替换成你的内容类型机器名) $sandbox['max'] = \Drupal::entityQuery('node') ->condition('type', 'your_content_type') ->condition('status', 0) ->count() ->execute(); if ($sandbox['max'] === 0) { // 没有需要更新的节点,直接结束 $sandbox['#finished'] = 1; return; } } // 每次处理50个节点(可根据服务器性能调整) $limit = 50; // 查询下一批需要更新的节点 $nids = \Drupal::entityQuery('node') ->condition('type', 'your_content_type') ->condition('status', 0) ->condition('nid', $sandbox['current_nid'], '>') ->sort('nid') ->range(0, $limit) ->execute(); if (!empty($nids)) { $nodes = \Drupal\node\Entity\Node::loadMultiple($nids); foreach ($nodes as $node) { $node->set('status', TRUE); $node->save(); $sandbox['progress']++; $sandbox['current_nid'] = $node->id(); } } // 更新完成进度 $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max']; // 输出当前进度信息 if ($sandbox['#finished'] < 1) { return t('已更新 @progress 个节点,共 @max 个。', [ '@progress' => $sandbox['progress'], '@max' => $sandbox['max'], ]); } else { return t('所有指定内容类型的节点已成功更新为已发布状态。'); } }
关键说明:
- 替换代码里的
your_content_type为你要处理的内容类型机器名 $limit = 50可以根据服务器性能调整,比如改成100或30,确保单次处理不会超时- 沙盒变量
$sandbox会在每次执行hook_update时保留进度,即使中途中断,下次执行会从上次结束的位置继续 - 用entityQuery过滤未发布的节点,避免重复处理已经更新过的节点
如果不想用Batch API,也可以手动记录处理进度,但Batch API是Drupal官方推荐的批量处理方式,更稳定可靠。
内容的提问来源于stack exchange,提问作者Anuradha Bics
相关产品推荐
相关产品推荐

