【问题标题】:WooCommerce querying all productsWooCommerce 查询所有产品
【发布时间】:2020-05-16 22:43:43
【问题描述】:

有一个网站展示了来自数千家电子商店的产品。 他们获取所有这些网店产品的方式是通过 XML 文件。

我创建了包含我所有 2k+ 产品的 XML 文件。

为了让我创建这个 XML 产品列表,我做了一个 BIG 查询,列出了每个产品及其变量以及变量具有的每个变体。

整个查询大约需要 30-40 秒才能完成并生成我的 XML 文件。

但有时当服务器非常繁忙时,进程会失败,因为繁忙时内存太高。我已将内存限制提高到 132MB,将 max_execution_time 提高到 60 秒。但是我仍然会不时生成 XML 文件随机失败。

我应该怎么做才能使查询更快?我已经阅读了很多关于 Transient API 的内容。你认为使用它是个好主意吗?我发送 XML 文件的第 3 方网站每 1 小时请求一次。所以我为我的服务器做了一个 cron 作业,每 1 小时重新创建一次 XML,这样文件就总是包含新产品或任何更改的值。

我的主要问题是如何更快地查询所有变体/变量?

这就是我构建 XML 的方式,以防你们认为该过程不高效:

// Create the XML file
$myFile = fopen("skroutz.xml", "w+");

// XML Headers
$ex .= "<?xml version='1.0' encoding='UTF-8'?>";
$ex .= "<mywebstore>";
$ex .= "<created_at>" . date("Y-m-d H:i") . "</created_at>";
$ex .= "<products>";

// Loop through products
$loop = new WP_Query( array(
    'post_type' => 'product',
    'posts_per_page' => -1,
    'orderby' => 'title',
    'order' => 'ASC',
    'tax_query' => array( array(
        'taxonomy' => 'product_cat',
        'field' => 'id',
        'terms' => 113,
        'operator' => 'NOT IN'
    ) )
) );

if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();

if ( $product->is_type( 'variable' ) ){  // Check if product is Variable

...

}

endwhile;
endif;
wp_reset_query();


$ex .= "</products>";
$ex .= '</mywebstore>';

fwrite($myFile, $ex);
fclose($myFile);

【问题讨论】:

  • 如果您绝对无法增加主机上的内存限制和 max_execution_time,您可以将查询拆分为多个块(例如,一次 500 个posts_per_page),暂时存储查询的偏移量。如果瞬态 offset 尚不存在,请创建一个带有标题的空 XML 文件。在遍历前 500 个结果后,将偏移量存储在瞬态中,您将在下次调用 PHP 脚本时恢复。对于 2000 个产品,这需要调用脚本 4 次。您可以通过对偏移量 + 500 强制刷新(元标记/JS)来自动执行此操作
  • 该死,这些听起来都太高级了,我无法编写代码。您认为上面的代码是创建 XML 文件的正确方法吗?唯一更好的性能方法是使用瞬态?
  • 瞬态与查询性能无关。它们就像选项一样,但在到期时会自动删除最佳使用日期。
  • 是的,你是对的。即使我创建瞬态,我也不会在性能方面获得任何好处。我只是想知道我使用$ex .=在文件中附加内容的方法是否正确。

标签: wordpress woocommerce transient


【解决方案1】:

因此,这不会是一个完全有效(或经过测试)的示例,但您可能会从中得到足够的提示:

define('XML_FILE', 'skroutz.xml');
define('QUERY_LIMIT', 500);
$query_offset = get_transient('xml_query_offset');
if (($query_offset === false) || !is_numeric($query_offset)) {
  // -- (re-)start the query initially, write a new XML file --
  $query_offset = 0;
  ob_start();
  // XML Headers
?>
<?xml version='1.0' encoding='UTF-8'?>
<mywebstore>
<created_at><?= date("Y-m-d H:i") ?></created_at>
<products>
<?php
  file_put_contents(XML_FILE, ob_get_clean()); // flush buffer to new XML file
}

// Loop through products (from $query_offset)
$loop = new WP_Query( array(
    'post_type' => 'product',
    'offset' => $query_offset,
    'posts_per_page' => QUERY_LIMIT,
    'orderby' => 'title',
    'order' => 'ASC',
    'tax_query' => array( array(
        'taxonomy' => 'product_cat',
        'field' => 'id',
        'terms' => 113,
        'operator' => 'NOT IN'
    ) )
) );

if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();

if ( $product->is_type( 'variable' ) ){  // Check if product is Variable

...

}
file_put_contents(XML_FILE, $GENERATED_XML_CONTENT, FILE_APPEND); // append product's XML code to the end of the file

endwhile;
endif;

if (($query_offset + QUERY_LIMIT) >= $loop->found_posts) {
  // you've reached the end, delete the transient
  delete_transient('xml_query_offset');
  file_put_contents(XML_FILE, '</products>'.PHP_EOL, FILE_APPEND); // close the products XML tag, finally.
  // we're done.
} else {
  $query_offset += QUERY_LIMIT;
  set_transient('xml_query_offset', $query_offset, 5 * MINUTE_IN_SECONDS);
  // we will force a reload via JS (assuming the front-end output is HTML)
?>
<script>
location.reload(true); // bypass cache
</script>
<?php
}
wp_reset_query();

总体思路是检测代码是否在过去 5 分钟内运行(瞬态超时)。如果没有,这意味着您想要生成一个新的 XML 文件。我个人更喜欢使用输出缓冲而不是附加到$ex 变量,将其写入文件。然后,您可以使用file_put_contents 或者不使用FILE_APPEND 来创建一个新文件,或者只是附加到已经存在的内容。

就性能而言,写入文件(无论哪种方式)不是您的瓶颈,而是 WP 查询和循环。这意味着您可以缩短限制结果的循环。最后一个块完成后,关闭 XML 标记并删除瞬态。我不确定那个笨拙的 JS 自动重新加载是否真的有效,或者您是否必须再次手动调用它。

【讨论】:

  • 非常感谢您提供的信息!我会尝试实现它,看看效果如何!
猜你喜欢
  • 2015-09-05
  • 2017-10-30
  • 1970-01-01
  • 2019-03-13
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
相关资源
最近更新 更多