Я относительно новичок в PHP, WordPress и WooCommerce. Но у меня есть 5-летний опыт работы с Oracle (SQL и PL/SQL), а также я много писал на JavaScript и немного на TypeScript.
Я работаю на своего клиента. У него есть интернет-магазин на базе WooCommerce. Мне нужно обновить stock_quantity, backorders и stock_status для продуктов и вариантов продуктов в соответствии с данными, поступающими с другого HTTP-сервера. В настоящее время у меня есть рабочее решение в TS/JS, которое работает на сервере Linode и в основном извлекает и объединяет/подготавливает данные для обновления WooCommerce. Но поскольку он использует WooCommerce HTTP API , который имеет ограничения на пакетное обновление (100 в секунду, все варианты должны обновляться для каждого родительского идентификатора также 1 раз в секунду), и я обновляю около 2500 продуктов и вариантов продуктов, это занимает очень долго для завершения процесса (~ 10 мин).
Процесс по шагам:
Я думаю, что есть лучший подход, о котором я думал:
Какой подход лучше всего подходит для производительности, безопасности и учета обновлений PHP, WordPress и WooCommerce?
@IvoJerkovic спасибо, я добавил шаги программы.
Спасибо. У меня есть несколько идей сейчас. Вы можете удалить сервер JS Linode и вызвать сторонний API непосредственно с сервера woocommerce в php-скрипте. Затем вы можете обновлять продукты без API, используя php-код, который @VegasGeek предложил в своем ответе. Если вам нужно сохранить JS-сервер, вы можете сравнить количество и обновить только те товары, количество которых изменилось. Это должно сократить количество обновлений и ускорить процесс.






Использование WC API для этого, безусловно, является наиболее «надежным» способом достижения вашей цели. API очень стабилен и (обычно) не ломается при изменении внутренних компонентов. Однако, как вы заметили, это самый медленный метод.
Ваш следующий лучший вариант — запустить обновление с использованием методов Woocommerce CRUD, но, опять же, не супер быстро, но быстрее, чем с использованием API.
$product = wc_get_product( $product_id );
$product->set_stock = 100;
$product->set_stock_status = 'instock';
$product->save();
Обновление базы данных напрямую, безусловно, самый быстрый способ, но подверженный ошибкам, потому что, например, в то время как состояние акций находится в wp_postmeta, это ТАКЖЕ таксономия, и оба должны совпадать, иначе у вас будут непредвиденные последствия.
Согласен с вами, я бы тоже пользовался остальным апи и следил за сервером. Возможно, простое увеличение ресурсов сервера может достаточно ускорить процесс.
Основываясь на дополнительных комментариях @HotFix и ответе, предоставленном @VegasGeek, я создал файл PHP, который можно запустить на сервере WordPress из командной строки или задания cron.
Идея:
Предположим, что сторонний внешний API возвращает такой ответ JSON.
{
"products": [
{
"id": 123,
"sku": "PR1234",
"name": "Product 1",
"stock_quantity": 10
},
{
"id": 456,
"sku": "PR-3333",
"name": "Product 2",
"stock_quantity": 5
}
]
}
Там 2 товара с артикулом и информацией о количестве.
PHP-скрипт требует wp-load.php, поэтому замените мой путь на свой. Для простоты я создал этот файл в корне веб-сайта, чтобы я мог запустить его и в браузере, но вы можете поместить его в другое место и изменить путь. Важно только, чтобы путь к wp-load.php был правильным. Эта строка кода загрузит WordPress и все плагины и сделает их доступными для скрипта.
Я имитирую ответ API с помощью простого статического файла JSON, вы заменяете конечную точку URL-адресом реального API. Кроме того, вам может понадобиться добавить некоторую аутентификацию для доступа к внешнему API, и ваши данные, вероятно, будут отличаться от моего примера, поэтому вам придется немного изменить код. Мы используем curl для получения данных из API, поэтому модифицировать вызов должно быть легко.
Затем мы перебираем продукты, находим продукт в 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>";
Я протестировал его с двумя продуктами, только один из них нуждался в обновлении. Результат (лог):
Stock quantity for product with SKU 'PR1234' is already up to date
Successfully updated stock quantity for product with SKU 'PR-3333' to 5
Очень интересная проблема. 10 минут кажутся слишком длинными. Можете ли вы описать свой процесс? Вы сначала тянете список продуктов? Что именно вы обновляете? Знаете ли вы, какие конечные точки API WooCommerce вы вызываете? Всегда можно написать какой-нибудь скрипт, который будет обновлять информацию непосредственно в базе данных, но тогда вы не будете запускать различные хуки, которые срабатывают. Например, отправка электронной почты клиенту. Возможно, ваше обновление вызывает некоторые электронные письма, которые затем вызывают задержку.