【问题标题】:Can I stop Drupal re-creating a form when it's submitted?我可以在提交表单时停止 Drupal 重新创建表单吗?
【发布时间】:2010-10-06 15:21:10
【问题描述】:

我有一个使用通过第三方 API 检索的选项构建的预订表单,并且由于需要获取最新信息,因此无法缓存来自 API 的结果(至少不会缓存很长时间)。

我遇到的问题是我在提交表单时注意到 Drupal 正在重新调用我的 _form 函数,该函数再次触发 API 调用,我想阻止它这样做以尝试减少数量进行的 API 调用次数。

显然,如果验证失败,则需要重新绘制表单,并且需要再次进行 API 调用,但我想知道当表单验证时是否有办法阻止它这样做,这样我就可以停止它了大量不必要的 API 调用。

感谢您的帮助。

【问题讨论】:

    标签: php drupal forms


    【解决方案1】:

    如果表单要由 Drupal 处理,则无法避免重新创建表单。它是Drupals form processing workflow 的核心部分:每个表单至少构建两次,一次用于初始输出,至少在来自客户端的帖子进入时再次构建. 它甚至可能不止于此,这取决于表单之后的作用,例如发生任何验证错误时重新显示(通常会在那时使用缓存的版本,但这取决于特定的表单)。

    您应该遵循 Simons 的建议 - 在第一次调用表单构建器函数时,进行 API 调用并将结果存储在 $form_state['storage']['yourIdentifier'] 中('yourIdentifier' 是标准表单处理不使用的一些字符串 - 通常开始与您的模块名称)。在每次调用表单构建器函数时,检查结果是否已经在 $form_state['storage'] 中。如果是,您只需使用它们,跳过 API 调用。

    这将避免重复的 API 调用,并让您更好地控制如何/何时执行它们(例如,如果特殊条件要求从外部 API 重新获取,您还可以在验证期间清除这些结果)。

    【讨论】:

    • 感谢您的回复,我已经尝试过让它工作,但遇到了一些麻烦。我在表单函数中设置了 $form_state,但是当我提交表单时,它总是返回 null。是否有任何示例可以更详细地解释其工作原理?我查看了 Drupal 网站上的那些,但它们并没有那么有用
    • @pogo:如果不查看表单构建器函数,很难判断出什么问题,但一个常见的错误是使用了错误的函数签名 (drupal.org/node/794694#comment-2949122)。也许您可以编辑您的问题以包含您目前使用的代码?
    【解决方案2】:

    您能否将 API 的返回值存储/缓存在 $form_state['storage'] 中,因此至少如果每次调用 _form 时,您可以在再次调用 API 之前先检查存储。

    【讨论】:

    • +1 - 我发布了另一个包含更多细节的答案,但这是解决问题的正确方法。
    【解决方案3】:

    首先,如果验证失败,Drupal 会有一份表单副本,因此您的表单函数实际上不会被调用。

    现在是解决方案。

    • 您可以在表单提交中重定向到新页面,避免重新调用表单。
    • 不要在菜单定义中直接调用表单,而是调用表单的回调。然后,您可以测试表单是否已提交,并仅在需要时调用您的表单函数。

    如果您担心 API 调用,您也可以将其缓存 5-10 分钟,这将使我的两个建议过时。

    【讨论】:

      【解决方案4】:

      Drupal 不能这样做吗? “不能”不在我的词汇表中!

      我也有同样的问题,但我不能让它打败我。这是我克服它的方法:

      在处理表单中,将详细信息插入数据库(或电子邮件或其他)后,我设置了 2 条这样的 drupal 状态消息

      function process_form($form){
        $success = do_email($form);
        if ($success){
          drupal_set_message("Success");
          drupal_set_message("Your form worked!");
        }
      }
      

      在表单生成器中,我读取并清除消息,清除表单并将状态消息作为标记输出:

      function form_generator($form_state,$parameters){
        $form = array();
         ...// This is where I make the regular form
        $messages = drupal_get_messages(); // this gets the messages and clears them
        if (isset($messages["status"])){
          if (isset($messages['status'][0]) && isset($messages['status'][1])){
            if ($messages['status'][0]=="Success"){
              $form = array(); // This clears the form I've just made
              $form['final_message']= array(
                '#type' => 'markup',
                '#markup' => $messages['status'][1],
              );
            }
          }
        }
      }
      

      这不会在第一次显示时清除表单,因为 $messages 未设置,当您遇到验证错误时,它们仍然会出现。

      Drupal 的魔力挡住了我们的路,但 PHP 程序员的意志力更强。

      【讨论】:

        猜你喜欢
        • 2011-10-21
        • 1970-01-01
        • 2015-05-04
        • 2014-05-07
        • 1970-01-01
        • 2019-07-20
        • 2014-08-23
        • 2013-10-27
        相关资源
        最近更新 更多