简体   繁体   English

更新 WooCommerce 产品和变体的最佳方法

[英]Best approach to update WooCommerce products and variations

I am relatively new to PHP, WordPress, and WooCommerce. But I have 5 years experience in Oracle (SQL and PL/SQL) and also did a lot of JavaScript and some TypeScript.我对 PHP、WordPress 和 WooCommerce 比较陌生。但我在 Oracle(SQL 和 PL/SQL)方面有 5 年的经验,并且还做了很多 JavaScript 和一些 TypeScript。

I am working for a client of mine.我正在为我的一个客户工作。 He has a WooCommerce-based webshop.他有一个基于 WooCommerce 的网上商店。 I need to update stock_quantity, backorders, and stock_status for products and product variations according to data coming from another HTTP server.我需要根据来自另一台 HTTP 服务器的数据更新产品和产品变体的库存数量、延期交货和库存状态。 Currently, I have a working solution in TS/JS, which runs on a Linode server and is basically retrieving and combining/preparing data to update WooCommerce. But because it utilizes the WooCommerce HTTP API which has batch update limits (100 in a second, all variations have to be updated per parent id also 1 per second), and I am updating about 2500 products and product variations, it takes very long for the process to complete (~10 min).目前,我在 TS/JS 中有一个工作解决方案,它在 Linode 服务器上运行,基本上是检索和组合/准备数据以更新 WooCommerce。但是因为它利用了 WooCommerce HTTP API ,它具有批量更新限制(每秒 100 次,每个父 ID 的所有变体也必须每秒更新 1 个),我正在更新大约 2500 个产品和产品变体,完成该过程需要很长时间(约 10 分钟)。

The process in steps:过程分步骤:

  1. Get stock from 3rd party API, this is a list of SKUs and their stock amount.从第 3 方 API 获取库存,这是 SKU 及其库存量的列表。
  2. Get all WC products and WC product variations获取所有 WC 产品和 WC 产品变体
  3. Match stock list on WC product and product variation lists by SKU.按 SKU 匹配 WC 产品和产品变体列表上的库存清单。
  4. Update products in batches of 100 per second (/products/batch)每秒更新 100 个产品 (/products/batch)
  5. Update product variations per parent product per second (/products/${id}/variations/batch)每秒更新每个父产品的产品变体 (/products/${id}/variations/batch)

I think there is a better approach, I was thinking of:我认为有更好的方法,我在想:

  • PHP procedure, closer to DB, maybe no limit on batch updates? PHP 程序,更接近DB,也许没有限制批量更新? But I am unable to find any WooCommerce PHP API other than https://github.com/woocommerce/wc-api-php , which is a wrapper for the HTTP API, so in the end, would return the same result.但我找不到任何 WooCommerce 8832478985188 API 除了https://github.com/woocommerce/wc-api-php ,它是 HTTP API 的包装,所以返回相同的结果。
  • MySQL Database procedure, in DB, should run way quicker. MySQL DB 中的数据库过程应该运行得更快。 Difficult to dissect what tables need to be updated exactly with what values.很难剖析哪些表需要用哪些值准确更新。 Is the MySQL DB able to do HTTP requests? MySQL 数据库是否能够执行 HTTP 请求?

What approach would be best concerning performance, security, and keeping updates of PHP, WordPress, and WooCommerce in mind?关于性能、安全性和保持 PHP、WordPress 和 WooCommerce 更新的最佳方法是什么?

Using the WC API to do this is by far the most "reliable" way to accomplish your goal.使用 WC API 来执行此操作是迄今为止实现您的目标的最“可靠”方式。 The API is very stable and doesn't (usually) break when internals are changed. API 非常稳定,并且(通常)不会在内部结构更改时中断。 It is, however, the slowest method, as you've noticed.然而,正如您所注意到的,这是最慢的方法。

Your next best option is to run an update using the Woocommerce CRUD methods but, again, not super speedy but faster than using the API.您的下一个最佳选择是使用 Woocommerce CRUD 方法运行更新,但同样,速度不是超快,但比使用 API 更快。

$product = wc_get_product( $product_id );
$product->set_stock = 100;
$product->set_stock_status = 'instock';
$product->save();

Updating the DB directly is by far the fastest way but error prone because, for example, while stock status is in wp_postmeta, it's ALSO a taxonomy and both have to match or you'll have unintended consequences.直接更新数据库是迄今为止最快的方法,但容易出错,因为例如,虽然库存状态在 wp_postmeta 中,但它也是一种分类法,两者必须匹配,否则会产生意想不到的后果。

Based on additional comments by @HotFix and answer provided by @VegasGeek, I created a PHP file that can be run on the WordPress server from the command line or a cron job.基于@HotFix 的附加评论和@VegasGeek 提供的答案,我创建了一个 PHP 文件,可以从命令行或 cron 作业在 WordPress 服务器上运行。

The idea:想法:

  • We'll create a PHP script that will load the WordPress inside, call the external API and update the product quantity if needed.我们将创建一个 PHP 脚本,它将在内部加载 WordPress,调用外部 API 并在需要时更新产品数量。

Let's assume that 3rd party external API returns a JSON response like this让我们假设第 3 方外部 API 返回这样的 JSON 响应

{
  "products": [
    {
      "id": 123,
      "sku": "PR1234",
      "name": "Product 1",
      "stock_quantity": 10
    },
    {
      "id": 456,
      "sku": "PR-3333",
      "name": "Product 2",
      "stock_quantity": 5
    }
  ]
}

There a 2 products with SKU and quantity info.有 2 个产品带有 SKU 和数量信息。

The PHP script requires wp-load.php so replace my path with yours. PHP 脚本需要wp-load.php所以用你的路径替换我的路径。 For simplicity, I created this file in the website root so I can run it in the browser too but you can put it somewhere else and change the path.为简单起见,我在网站根目录中创建了这个文件,这样我也可以在浏览器中运行它,但你可以将它放在其他地方并更改路径。 It's only important that the path to wp-load.php is correct.唯一重要的是wp-load.php的路径是正确的。 This line of code will load the WordPress and all plugins and make it available to the script.这行代码将加载 WordPress 和所有插件,并使其可供脚本使用。

I am simulating API response with a simple static JSON file, you replace the endpoint with the URL of the real API. Also, you may need to add some authentication to access the external API and your data will probably be different to my example, so you'll have to change the code a bit.我正在用一个简单的 8810007683788 JSON 文件模拟 API 响应,您将端点替换为真实 API 的 URL。此外,您可能需要添加一些身份验证才能访问外部 API,因此您的数据可能会有所不同您必须稍微更改一下代码。 We are using curl to get the data from the API so it should be easy to modify the call.我们正在使用 curl 从 API 获取数据,因此修改调用应该很容易。

Then, we iterate over the products, find the product in WooCommerce by SKU, check if the quantity has changed and update if needed.然后,我们遍历产品,通过SKU找到WooCommerce中的产品,检查数量是否有变化,如果需要更新。


// Load WordPress
define( 'WP_USE_THEMES', false );
//require_once( 'path/to/wp-load.php' );
require_once "wp-load.php";
// Set the API endpoint
//$api_endpoint = 'https://your-api.com/products';
$api_endpoint = 'http://bytwoo.local/TestData.json';

echo "<pre>";

// Build the cURL request to retrieve the list of products from the external API
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $api_endpoint );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

// Execute the API request and decode the response
$response = json_decode( curl_exec( $ch ), true );
curl_close( $ch );

// Check if the API request was successful and if the products were found
if ( isset( $response['products'] ) && is_array( $response['products'] ) ) {
    // The products were found, loop through the products
    foreach ( $response['products'] as $product ) {
        // Get the product SKU and stock quantity
        $product_sku    = $product['sku'];
        $stock_quantity = $product['stock_quantity'];

        // Get the product ID from the SKU
        $product_id = wc_get_product_id_by_sku($product_sku);
        // Get the WooCommerce product object
        $wc_product =  wc_get_product($product_id);

        // Check if the product exists in the WooCommerce shop
        if ( ! empty( $wc_product ) ) {
            // The product exists, get the current stock quantity
            $current_stock_quantity = $wc_product->get_stock_quantity();

            // Check if the stock quantity needs to be updated
            if ( $stock_quantity != $current_stock_quantity ) {
                // Set the new stock quantity and stock status
                $wc_product->set_stock_quantity($stock_quantity);
                $wc_product->set_stock_status( 'instock' );

                // Save the product
                $wc_product->save();

                echo PHP_EOL."Successfully updated stock quantity for product with SKU '$product_sku' to $stock_quantity";
            } else {
                echo PHP_EOL."Stock quantity for product with SKU '$product_sku' is already up to date";
            }
        } else {
            echo PHP_EOL."Product with SKU '$product_sku' not found in WooCommerce shop";
        }
    }
} else {
    echo PHP_EOL."No products found in external API";
}

echo "</pre>";

I tested it with 2 products, only one of them needed an update.我用 2 种产品对其进行了测试,其中只有一种需要更新。 The result (log):结果(日志):

Stock quantity for product with SKU 'PR1234' is already up to date
Successfully updated stock quantity for product with SKU 'PR-3333' to 5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM