WP_QUERY扩展类中的术语“%s”导致巨大的内存泄漏(268MB)

时间:2015-05-21 作者:Archonic

我用过WP-Geo-Posts 作为构建插件的起点,该插件扩展了WooCommerce,以支持类似分类广告的功能。使用ACF 我已经将产品与位置(纬度和经度)关联,现在我正在搜索中构建位置支持。用户提供搜索词、位置和半径。结果应为特定半径内的产品,按离提供位置最近的顺序排序。它工作得很好,但搜索当前忽略了用户输入的任何搜索词。

我创建了一个类,它扩展了WP\\u查询来构建“distance”的伪字段。你会认为我可以提供s 到相同的$args 数组,它将像WP\\u Query一样按关键字作用域。相反,我得到一个空白页,日志上写着

 PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 130968 bytes) in /home/mydir/home/mysite/public_html/wp-includes/query.php on line 1681, referer: http://example.com/shop/
我有一个很好用的:

$args = array(
  \'post_type\'       => $query->get(\'post_type\') ,
  \'posts_per_page\'  => 20,
  \'fields\'          => \'all\',
  \'lat\'             => $_REQUEST[\'lat\'],
  \'lng\'             => $_REQUEST[\'lng\'],
  \'distance\'        => $_REQUEST[\'dist\']
);
$query = new WP_Query_Geo( $args );
这就像帮派杀手一样泄露内存:

$args = array(
  \'post_type\'       => $query->get(\'post_type\') ,
  \'posts_per_page\'  => 20,
  \'fields\'          => \'all\',
  \'lat\'             => $_REQUEST[\'lat\'],
  \'lng\'             => $_REQUEST[\'lng\'],
  \'distance\'        => $_REQUEST[\'dist\'],
  \'s\' => $search_terms
);
$query = new WP_Query_Geo( $args );
扩展WP\\u Query(WP\\u Query\\u Geo)的My类使用concat(.=) 在$字段、$join和$where上,我不明白为什么要提供s 会造成任何伤害。

这是的输出var_dump($query->request); 没有s 以$args为单位:

string(799) "SELECT SQL_CALC_FOUND_ROWS wp_posts.*, ( 6371 * acos( cos( radians(48.4284207) ) * cos( radians( latitude.meta_value ) ) * cos( radians( longitude.meta_value ) - radians(-123.36564440000001) ) + sin( radians(48.4284207) ) * sin( radians( latitude.meta_value ) ) ) ) AS distance , latitude.meta_value AS latitude , longitude.meta_value AS longitude FROM wp_posts INNER JOIN wp_postmeta AS latitude ON wp_posts.ID = latitude.post_id INNER JOIN wp_postmeta AS longitude ON wp_posts.ID = longitude.post_id WHERE 1=1 AND wp_posts.post_type = \'product\' AND (wp_posts.post_status = \'publish\') AND latitude.meta_key="lat" AND longitude.meta_key="lng" HAVING distance <= 100 ORDER BY distance ASC, wp_posts.post_date DESC LIMIT 0, 20"

1 个回复
最合适的回答,由SO网友:Archonic 整理而成

我不知道惯例是怎么回事pre_get_posts, 但它似乎是为了设置额外的参数,而不是在运行查询时替换参数。比较wp\\U查询和我自己的地理查询,我注意到我自己的查询对象中有post数据。这可能是导致内存泄漏的原因,但它一定有一个无限循环-我的整个DB在268MB附近没有。也许查询不应该在构造函数内部进行?我想知道一个使用pre_get_posts.

而不是使用pre_get_posts, 我用了woocommerce_before_shop_loop 要更换的挂钩$wp_query 总共

add_action(\'woocommerce_before_shop_loop\', \'wr_product_geo_query\');
function wr_product_geo_query() {
  global $wp_query;

  if ($wp_query->is_search() && isset($_REQUEST[\'loc\'])) {
    $args = array(
      \'post_type\'       => $_REQUEST[\'post_type\'] ,
      \'posts_per_page\'  => 20,
      \'fields\'          => \'all\',
      \'lat\'             => $_REQUEST[\'lat\'],
      \'lng\'             => $_REQUEST[\'lng\'],
      \'distance\'        => $_REQUEST[\'dist\'],
      \'s\' => $_REQUEST[\'s\']
    );

    $wp_query = new WP_Query_Geo( $args );
  }
}
非常简单,但我希望有一个将自身插入默认搜索行为的解决方案,而不是依赖模板挂钩。

更新:经过多次内部审议,我认为pre\\u get\\u posts专门用于修改现有查询。我不是在修改它,我是在使用核武器。在这种情况下,通过自定义模板或模板挂钩创建新的查询对象是“正确的”方法。

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post