在AJAX回调中,$this上下文会发生变化吗?

时间:2020-08-20 作者:armadadrive

当尝试在插件实例中获取数据时,插件类文件中定义的所有PHP方法都可以;请参阅;刚刚为某个属性设置的数据。

然而,当我们在插件中创建一个响应来自JavaScript文件的AJAX post请求的PHP方法时,该属性突然变为空,就好像它从未被设置过一样。

从任何其他方法访问它都可以很好地工作,因此我相信AJAX可调用方法看到的是$this的不同上下文,它还没有设置属性。

可能是这样吗?还是有其他事情正在进行?

为清晰起见,进行了编辑:

所讨论的数据在运行时通过启动主要功能的短代码中的参数进行设置。因此,在执行短代码之前,它并不存在,这让我想知道AJAX调用该方法的方式是否存在于与WordPress在页面加载时创建的插件对象不同的上下文中。

编辑以添加代码片段(仅相关内容,这些内容不完整):

// From WP template file:

// This is well-formed and on the other end the plugin can print_r() the 
// unserialized $args just fine
<?php echo do_shortcode(\'[cptgm \' . serialize($args) . \']\'); ?>
// From plugin class file:
private query_args;

public function get_query_args() {
  if (!empty($this->query_args)) {
    return $this->query_args;
  }
  return false;
}

public function set_query_args($newArgs) {
  if (empty($newArgs)) {
    return false;
  }
  $this->query_args = $newArgs;
}

public function render_map_shortcode($atts = [], $content = null, $shortcode_tag = \'\') {

  // We know from doing a print_r() of $this->get_query_args immediately after
  // this line that the property is set and can be accessed
  $this->set_query_args(unserialize($atts[0]));
  $this->render_map();
}

// This is the method called via AJAX and is the only time in the plugin
// that we seem to have an issue. When called via AJAX, we can\'t print_r()
// here, but the return value is an empty array ONLY when we replace a hard-coded
// $args with $this->get_query_args(), which works everywhere else
public function get_data_from_custom_fields() {
  $return_data = [];
  $args = $this->get_query_args();

  // If we hard-code the $args, the WP_Query works fine and echos JSON
  // as a response to the JS file just fine. Only when we try and use
  // $this->get_query_args(); does the plugin end up echoing back $return_data
  // as an empty array (the way it was initialized above)

  // This is what led us to believe that, in the AJAX context, 
  // $this->get_query_args(); didn\'t seem to be supplying the $args we knew where 
  // there when the same getter was called from other methods
  $wp_query = new WP_Query($args);
  // ... echo/return results from $wp_query as JSON to the calling JS file
}
// From the plugin\'s JS file:
function cptgmRenderMap() {
  console.log(\'[CPTGM] Rendering map...\');

  cptgmData = {
    \'action\': \'get_data_from_custom_fields\'
  }

  $.post(ajax_object.ajax_url, cptgmData, function(response) {
    var parsedResponse = JSON.parse(response);
    // Setup map markers, etc. EXCEPT that the return JSON is now empty
    // ...
  }
}

1 个回复
SO网友:armadadrive

根据Jacob Peattie的确认,我现在的理解是这样的(如果这对未来的读者有帮助的话)。

加载页面时解释WordPress插件的PHP文件时,对WordPress插件方法的AJAX调用存在于与对象实例完全不同的上下文(单独的请求)中。

因此,只有在运行时才给定特定值的属性(例如,$this->foo), 虽然在给定会话期间可见,但不能保证对AJAX调用可见。AJAX调用访问对象的属性,因为它是在对象实例化上设置的,或者是通过AJAX调用和在AJAX调用期间设置或更改的。

要使JS和PHP文件之间的动态数据更改可见,即使属于同一个插件包,也可能需要另一种存储方法。

相关推荐

如何用AJAX提交日期?

我一直在尝试创建一个约会表单。其他一切都正常,但我无法提交日期。这是我的代码:My HTML for the date field:<input type="date" name="aptdate" class="form-control rounded-pill mr-sm-2" id="aptdate" placeholder="Select a date" onfocus="(this