首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Drupal 7 表單 API 進階:重定向、Destination 覆蓋、多步驟表單實戰

     編輯:PHP 相關知識

Drupal 7 表單系統功能強大,但重定向邏輯、Destination 參數干擾、多步驟流程控制常讓開發者困惑。本文匯總三大核心痛點解決方案。

1. 提交後重定向到指定頁面

在 _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
}

默認行為: 未設置時,重定向回當前頁面(保留查詢參數)。

2. 覆蓋 URL 中的 destination 參數

Drupal 核心 drupal_goto() 優先檢查 $_GET['destination'],導致表單多按鈕提交時無法按業務邏輯跳轉。

解決方案:在 submit 中清除 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']);
  }
}

相關 API 函數

  • drupal_get_destination():獲取當前 destination 值(數組格式)
  • drupal_goto($path, $options):核心跳轉函數,內部檢查 destination
  • drupal_redirect_form($form_state):表單提交後執行重定向的內部函數

3. 實現多步驟表單

核心機制:$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'支持字符串/數組格式
忽略 destinationunset($_GET['destination'])必須在 submit 中執行
多步驟流程$form_state['rebuild'] = TRUE + $form_state['storage']storage 自動持久化跨請求
返回上一步單獨 submit handler + #limit_validation_errors = []跳過驗證避免阻塞

最佳實踐建議

  1. 重定向邏輯集中在 submit handler,避免分散在 validate/builder 中
  2. 多步驟表單用 $form_state['step'] 明確狀態,而非隱藏字段
  3. 敏感操作(刪除、發布)使用確認表單 confirm_form()
  4. 大型表單拆分為多個 #tree => TRUE 的 fieldset 組

掌握這三大核心,即可駕馭 Drupal 7 表單複雜交互場景,構建流暢用戶體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved