[英]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:过程分步骤:
I think there is a better approach, I was thinking of:我认为有更好的方法,我在想:
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:想法:
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.