Woocommerce基于WordPress媒体库自动创建产品重复生成问题求助
问题原因排查
你遇到的重复生成产品问题,主要是以下3个代码错误导致的:
- 钩子选择错误
你把逻辑挂载到了init钩子上,这个钩子会在WordPress每次页面加载(不管前台后台、任意用户访问)时都触发一次。只要有人访问你的网站,程序就会跑一遍生成逻辑,自然会反复给同一张图片创建多个产品。 - 变量未初始化、未定义
你在循环生成产品的代码里,$downloads数组没有在每次循环前重置,而且用来当下标的$md5_num是完全未定义的变量,会导致PHP报错、下载资源绑定逻辑混乱,也会干扰后续的产品创建判断。 - 没有运行权限/开关限制
逻辑没有任何触发限制,任何人任何时候访问站点都会触发执行,很容易出现重复运行的情况。
修复后的代码
// 仅在管理员访问且带指定参数时执行,避免误触发 add_action( 'admin_init', 'product_automation'); function product_automation() { // 加开关和权限验证,只有管理员访问/wp-admin/?run_product_import=1时才执行 if ( !current_user_can( 'manage_options' ) || !isset( $_GET['run_product_import'] ) ) { return; } $loopProdutos = new WP_Query([ 'post_type' => 'product', 'posts_per_page' => -1, 'post_status' => 'publish' // 只查已发布的产品,避免草稿干扰 ]); $arrayProduct = (array) $loopProdutos->posts; $idImgProduct = []; foreach($arrayProduct as $product) { $produto = wc_get_product($product->ID); $idImgProduct[] = $produto->get_image_id(); // 用官方get方法更稳定 } $loopImagens = new WP_Query([ 'post_type' => 'attachment', 'post_mime_type' => 'image', 'orderby' => 'post_date', 'order' => 'desc', 'posts_per_page' => -1, 'post_status' => 'inherit' ]); $arrayImg = (array) $loopImagens->posts; $idImg = []; foreach($arrayImg as $image) { $idImg[] = $image->ID; } $newIds = array_diff($idImg, $idImgProduct); $newProductsArray = []; foreach($newIds as $idImagem) { $objProduct = new WC_Product_Simple(); $objProduct->set_name("Foto"); $objProduct->set_status("publish"); $objProduct->set_catalog_visibility('visible'); $objProduct->set_price(15.00); $objProduct->set_regular_price(15.00); $objProduct->set_sold_individually(true); $objProduct->set_image_id($idImagem); $objProduct->set_downloadable(true); $objProduct->set_virtual(true); $src_img = wp_get_attachment_image_src( $idImagem, 'full'); $img_meta = wp_get_attachment_metadata( $idImagem, false ); $file_title = !empty($img_meta['image_meta']['title']) ? $img_meta['image_meta']['title'] : '图片资源'; $file_url = reset($src_img); $file_md5 = md5($file_url); $download = new WC_Product_Download(); $download->set_name($file_title); $download->set_id($file_md5); $download->set_file($file_url); // 每次循环都重置downloads数组,避免之前的内容累积 $downloads = []; // 用实际生成的$file_md5当下标,替换之前未定义的$md5_num $downloads[$file_md5] = $download; $objProduct->set_downloads($downloads); $newProductsArray[] = $objProduct; } foreach ($newProductsArray as $product) { $product->save(); } // 执行完后跳回后台首页,避免刷新页面重复执行 wp_redirect(admin_url()); exit; }
使用方法
你需要生成产品的时候,登录WordPress后台,访问地址你的后台地址/?run_product_import=1就会自动执行一次生成逻辑,执行完会自动跳回后台,不会重复触发。
内容的提问来源于stack exchange,提问作者user17080548
相关产品推荐
相关产品推荐

