【问题标题】:Prevent infinite AJAX loop when using own API使用自己的 API 时防止无限 AJAX 循环
【发布时间】:2016-09-19 17:59:17
【问题描述】:

我目前正在尝试找出 2 个 Wordpress 插件之间的集成:WooCommerce Follow Up Emails 插件和 Ninja Forms 插件(最终目标是我们可以发送手动类型的后续电子邮件模板作为响应忍者表格提交)。我们正在使用 Ninja Forms 3,物有所值。

在为Action class 定义选项时,我向用户提供了模板列表,以便在定义操作时他们可以选择要发送的模板。为了从后续电子邮件插件中获取电子邮件模板,我使用了他们的API client,特别是get_emails() 方法(这反过来又转换为在他们的API URL 下对/emails 端点的GET 调用)。

问题是这样的:在每个页面加载时都会调用ninja_forms_register_actions 操作,在此期间我会实例化我的操作类。在__construct 调用期间,我们填充操作的设置,为此,我们调用Follow Up Emails API。这将启动页面加载,在此期间调用 ninja_forms_register_actions 操作...

虽然我确实预料到了这个问题,但我计划的解决方案并没有帮助:也就是说,我计划使用瞬态来存储 API 调用的结果,如下所示:

private static function _get_templates()
    {
        error_log('_get_templates() started - ' . microtime(true));
        if (false === ($templates = get_transient(self::TEMPLATE_TRANSIENT))) {
            error_log('_get_templates() fetching - ' . microtime(true));
            $fue_api = self::fue_api();
            $templates = $fue_api->get_emails();
            set_transient(self::TEMPLATE_TRANSIENT, $templates, self::TEMPLATE_TRANSIENT_EXPIRY);
            error_log('_get_templates() fetched - ' . microtime(true));
        }
        error_log('_get_templates() done - ' . microtime(true));

        return $templates;
    }

但是我的日志中的结果如下:

[22-May-2016 23:53:33 UTC] _get_templates() started - 1463961213.692187
[22-May-2016 23:53:33 UTC] _get_templates() fetching - 1463961213.694222
[22-May-2016 23:53:34 UTC] _get_templates() started - 1463961214.05998
[22-May-2016 23:53:34 UTC] _get_templates() fetching - 1463961214.061054
[22-May-2016 23:53:38 UTC] _get_templates() started - 1463961218.660683
[22-May-2016 23:53:38 UTC] _get_templates() fetching - 1463961218.661265
[22-May-2016 23:53:40 UTC] _get_templates() started - 1463961220.772228
[22-May-2016 23:53:40 UTC] _get_templates() fetching - 1463961220.774142
[22-May-2016 23:53:41 UTC] _get_templates() started - 1463961221.150277
[22-May-2016 23:53:41 UTC] _get_templates() fetching - 1463961221.654757
[22-May-2016 23:53:45 UTC] _get_templates() started - 1463961225.306565
[22-May-2016 23:53:45 UTC] _get_templates() fetching - 1463961225.308898
[22-May-2016 23:53:46 UTC] _get_templates() started - 1463961226.281794
[22-May-2016 23:53:46 UTC] _get_templates() fetching - 1463961226.283803

这一直持续到我终止 Web 服务器进程或其他诸如删除/重命名插件文件夹之类的剧烈事件,此时瞬态被 HTTP 错误代码填充(这本身并不令人惊讶)。很明显,我的瞬态解决方案不起作用,因为直到请求之后瞬态仍未设置。

在某些情况下,我会添加对DOING_AJAX 的检查,但这不适合有两个原因 - 我仍然需要这些数据可用于 Ninja Forms AJAX 进程,而且我不确定是否DOING_AJAX 实际上会在这里设置,因为 FUE API 不使用admin-ajax.php。我正在考虑更改为以下内容:

private static function _get_templates()
        {
            error_log('_get_templates() started - ' . microtime(true));
            if (false === get_option(self::TEMPLATE_LOCK_OPTION, false) && false === ($templates = get_transient(self::TEMPLATE_TRANSIENT))) {
                delete_option(self::TEMPLATE_LOCK_OPTION);
                add_option(self::TEMPLATE_LOCK_OPTION, true, '', 'no');
                error_log('_get_templates() fetching - ' . microtime(true));
                $fue_api = self::fue_api();
                $templates = $fue_api->get_emails();
                delete_option(self::TEMPLATE_LOCK_OPTION);
                set_transient(self::TEMPLATE_TRANSIENT, $templates, self::TEMPLATE_TRANSIENT_EXPIRY);
                error_log('_get_templates() fetched - ' . microtime(true));
            }
            error_log('_get_templates() done - ' . microtime(true));

            return $templates;
        }

但是使用选项作为锁感觉很脏和错误,而且我觉得在使用对象缓存时它会留下错误空间(例如 WPEngine 等)。有没有更好/正常的方法来处理这个问题,或者,上述方法没有真正的问题吗?

编辑:所以锁定解决方案也不能 100% 工作 - 我最终通过 WP Cron 作业完成了这个 - 每十分钟我们获取模板列表,而不是根据需要,并将其存储在选项。我不喜欢这个解决方案——但我还没有想出一个更好的解决方案。如果有针对此问题的通用解决方案,仍然很感兴趣。

【问题讨论】:

  • 你试过更新wordpress吗?还是有问题?

标签: php ajax wordpress ninja-forms


【解决方案1】:

以下部分函数调用_get_templates()

$fue_api = self::fue_api();
$templates = $fue_api->get_emails();
delete_option(self::TEMPLATE_LOCK_OPTION);
set_transient(self::TEMPLATE_TRANSIENT, $templates, self::TEMPLATE_TRANSIENT_EXPIRY);

【讨论】:

    【解决方案2】:

    最后打印的和第一个预期的 error_log 之间的方法/功能之一是再次调用您的方法。要获得循环/递归开始的线索,您可以使用 debug_backtrace() 来获取调用堆栈以及循环/递归开始的点。

    开始的最佳位置是将 debug_backtrace 放置在您上次工作的 error_log 之后。

    【讨论】:

      猜你喜欢
      • 2011-10-11
      • 2021-01-16
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多