Drupal 7如何防止多个表单提交(服务器端)

时间:2012-12-13 22:10:58

标签: drupal-7

以下是我正在测试的工作模块代码:

/**
 * @file myform.module
 */

 /**
 * Implements hook_menu().
 */
 function myform_menu() {
   $items['myform'] = array(
     'title' => 'myform',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('myform'),
     'access callback' => true,
     'type' => MENU_NORMAL_ITEM
   );
   return $items;
 }

 /**
 * Form
 */
 function myform() {
   $form['Value'] = array(
     '#title' => t('Value'),
     '#type' => 'textfield',
     '#description' => t('You may not enter the same value twice. (unless you hit enter really fast).'),
     '#required' => true,
   );
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit')
   );
   return $form;
 }

 /**
 * Validate
 */
 function myform_validate($form, &$form_state) {
   if (isset($form_state['values']['Value']) && trim($form_state['values']['Value'])!=''){
     // prevent duplicates
     db_set_active('test');
     $r = db_query("SELECT id FROM test WHERE value = '".$form_state['values']['Value']."'");
     $n = $r->rowCount();
     if ($n) {
       form_set_error('Value', t('This value has already been submitted.'));
     }
     db_set_active();
   }
 }

 /**
 * Submit
 */
 function myform_submit($form, &$form_state) {

   for ($i=0; $i<=10000000; $i++) {
     // do nothing
   }

   db_set_active('test');
   db_insert('test')->fields(array('value'=>$form_state['values']['Value']))->execute();
   db_set_active();
 }

验证挂钩可以防止插入重复值,除非我快速点击回车键或提交按钮,在这种情况下,多次将相同的值插入数据库。

如何防止插入重复值?

2 个答案:

答案 0 :(得分:3)

如果您的意思是用户不小心点击了提交按钮,那么您应该查看Hide submit button模块。您可以在模块的INFO文件中将其定义为依赖项。

答案 1 :(得分:1)

我遇到了完全相同的问题,并设法使用Drupal的Locking mechanisms修复它

在我使用的验证函数中:

function mymodule_custom_form_validate($form, &$form_state){
  if (lock_acquire('your_custom_lock_name')) {
    // long operations here
  } else {
    form_set_error("", t("You submitted this form already."));
  }
}

在提交功能中,我发布了锁:

function mymodule_custom_form_submit($form, &$form_state){
  // submit code
  lock_release('your_custom_lock_name');
}