Drupal 7 表單系統功能強大,但重定向邏輯、Destination 參數干擾、多步驟流程控制常讓開發者困惑。本文匯總三大核心痛點解決方案。
在 _submit 處理器中設置 $form_state['redirect']:
function myform_submit($form, &$form_state) {
// 簡單路徑
$form_state['redirect'] = 'node/123';
// 或帶查詢參數、錨點的數組格式
$form_state['redirect'] = array(
'node/123',
array(
'query' => array('foo' => 'bar'),
'fragment' => 'section-comments',
),
);
// 實際跳轉:node/123?foo=bar#section-comments
}
默認行為: 未設置時,重定向回當前頁面(保留查詢參數)。
Drupal 核心 drupal_goto() 優先檢查 $_GET['destination'],導致表單多按鈕提交時無法按業務邏輯跳轉。
function myform_submit($form, &$form_state) {
if ($form_state['values']['op'] == t('Save and Continue')) {
// 1. 保存 destination 供後續使用(可選)
$destination = drupal_get_destination();
// 2. 設置業務目標重定向
$form_state['redirect'] = array(
'admin/content/next-step',
array('query' => $destination) // 保留原 destination 作為查詢參數
);
// 3. 關鍵:移除 $_GET['destination'] 防止 drupal_goto 劫持
unset($_GET['destination']);
}
}
drupal_get_destination():獲取當前 destination 值(數組格式)drupal_goto($path, $options):核心跳轉函數,內部檢查 destinationdrupal_redirect_form($form_state):表單提交後執行重定向的內部函數核心機制:$form_state['rebuild'] = TRUE 強制重構表單,配合 $form_state['storage'] 傳遞數據。
function my_multistep_form($form, &$form_state) {
// 步驟 1:收集基本信息
if (empty($form_state['step'])) {
$form_state['step'] = 1;
}
switch ($form_state['step']) {
case 1:
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#default_value' => isset($form_state['storage']['name']) ? $form_state['storage']['name'] : '',
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Next Step'),
);
break;
case 2:
// 從 storage 讀取步驟 1 數據
$name = $form_state['storage']['name'];
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('Email for @name', array('@name' => $name)),
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
$form['back'] = array(
'#type' => 'submit',
'#value' => t('Back'),
'#submit' => array('my_multistep_form_back_submit'),
'#limit_validation_errors' => array(), // 返回時跳過驗證
);
break;
}
return $form;
}
function my_multistep_form_submit($form, &$form_state) {
switch ($form_state['step']) {
case 1:
// 保存步驟 1 數據到 storage
$form_state['storage']['name'] = $form_state['values']['name'];
$form_state['step'] = 2;
$form_state['rebuild'] = TRUE; // 關鍵:重構表單進入步驟 2
break;
case 2:
// 最終提交:合併所有步驟數據
$data = array_merge($form_state['storage'], $form_state['values']);
// 保存到數據庫、發送郵件等...
drupal_set_message(t('Form submitted successfully!'));
$form_state['redirect'] = 'admin/content/success';
break;
}
}
function my_multistep_form_back_submit($form, &$form_state) {
$form_state['step'] = 1;
$form_state['rebuild'] = TRUE;
}
| 需求 | 關鍵代碼 | 注意事項 |
|---|---|---|
| 自定義重定向 | $form_state['redirect'] = 'path' | 支持字符串/數組格式 |
| 忽略 destination | unset($_GET['destination']) | 必須在 submit 中執行 |
| 多步驟流程 | $form_state['rebuild'] = TRUE + $form_state['storage'] | storage 自動持久化跨請求 |
| 返回上一步 | 單獨 submit handler + #limit_validation_errors = [] | 跳過驗證避免阻塞 |
$form_state['step'] 明確狀態,而非隱藏字段confirm_form()#tree => TRUE 的 fieldset 組掌握這三大核心,即可駕馭 Drupal 7 表單複雜交互場景,構建流暢用戶體驗。