WordPress PHP致命错误:调用get_shipping_class()函数失败求助
WooCommerce短代码PHP致命错误排查与修复
问题场景
我在WooCommerce WordPress站点通过代码片段插件使用以下短代码,用于根据产品配送类显示对应配送提示:
add_shortcode( 'show_ship_class', 'wpse_295878_shipping_banner' ); function wpse_295878_shipping_banner() { $product = wc_get_product(); if ($product->get_shipping_class()){ $shipping_class = $product->get_shipping_class(); switch ( $shipping_class ) { case 'dsk2': return '<div class="shipdelay"><p>This item typically ships in 2-5 business days</p></div>'; break; case 'dsk': return '<div class="shipdelay"><p>This item typically ships in 1-3 business days</p></div>'; break; } } else { return; } }
错误日志
运行Media Cleaner插件时,错误日志出现以下PHP致命错误:
PHP Fatal error: Uncaught Error: Call to a member function get_shipping_class() on bool in /home/m01hurl/public_html/wp-content/plugins/insert-php/includes/class.execute.snippet.php(635) : eval()'d code:5 Stack trace: #0 /home/m01hurl/public_html/wp-includes/shortcodes.php(356): wpse_295878_shipping_banner('', '', 'show_ship_class') #1 [internal function]: do_shortcode_tag(Array) #2 /home/m01hurl/public_html/wp-includes/shortcodes.php(228): preg_replace_callback('/\[(\[?)(show_s...', 'do_shortcode_ta...', '<!-- wp:woobuil...') #3 /home/m01hurl/public_html/wp-content/plugins/media-cleaner/classes/core.php(264): do_shortcode('<!-- wp:woobuil...') #4 /home/m01hurl/public_html/wp-content/plugins/media-cleaner/classes/parsers/common.php(103): Meow_WPMC_Core->get_urls_from_html('<!-- wp:woobuil...') #5 /home/m01hurl/public_html/wp-includes/class-wp-hook.php(307): MeowApps_WPMC_Parser_Common->scan_post('<!-- wp:woobuil...', '36805') #6 /home/m01hurl/public_html/wp-includes/class-wp-hook.php(331): WP_Hook->apply_filters('', Array) in /home/m01hurl/public_html/wp-content/plugins/insert-php/includes/class.execute.snippet.php(635) : eval()'d code on line 5
问题原因
你的函数写法存在明显问题:
wc_get_product()在未传入产品ID且当前上下文不是产品页面时,会返回false(布尔值),而代码直接调用$product->get_shipping_class(),相当于在布尔值上调用对象方法,直接触发致命错误。- Media Cleaner插件扫描内容时会执行短代码,此时上下文并非产品页面,
wc_get_product()返回false,触发了这个错误。
修复后的代码
添加对$product有效性的判断,同时优化产品获取逻辑,确保只在有效产品上下文执行后续代码:
add_shortcode( 'show_ship_class', 'wpse_295878_shipping_banner' ); function wpse_295878_shipping_banner() { // 获取当前文章ID,优先确保是产品类型 $product_id = get_the_ID(); if ( empty( $product_id ) || 'product' !== get_post_type( $product_id ) ) { return ''; } $product = wc_get_product( $product_id ); // 验证产品对象是否有效 if ( ! is_a( $product, 'WC_Product' ) ) { return ''; } $shipping_class = $product->get_shipping_class(); if ( empty( $shipping_class ) ) { return ''; } switch ( $shipping_class ) { case 'dsk2': return '<div class="shipdelay"><p>This item typically ships in 2-5 business days</p></div>'; case 'dsk': return '<div class="shipdelay"><p>This item typically ships in 1-3 business days</p></div>'; // 可添加默认情况,避免未匹配到的配送类无输出 default: return ''; } }
额外说明
- 修复后的代码先验证当前是否为产品类型的文章,再获取产品对象,避免非产品上下文执行时出错。
- 添加了
is_a()验证产品对象类型,进一步确保调用方法的安全性。 - 补充了
default分支,处理未匹配到的配送类场景。
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

