如何在WooCommerce中获取未HTML转义的变体描述JSON数据?
问题背景
我在WooCommerce中使用带变体的产品,需要把JSON数据存在变体描述里用于模板开发。数据库的_meta字段_variation_description里存的是正常的未转义JSON,示例:
{"next_date":"2021-05-12","days":"-1217","tmp1":"1","tmp2":"149.53400000000002","tmp3":...}
但用get_available_variations()循环获取变体时:
foreach ( $product->get_available_variations() as $variation_data ) { print_r( $variation_data['variation_description']); }
得到的是带HTML标签和HTML实体转义的内容:
<p>{„next_date“:“2019-03-11″,“days“:“-2009″,“tmp1″:“1“...}
试过用strip_tags()和HTML实体解码,但会出现引号格式错误:
{„next_date“....
虽然可以通过变体ID调用get_meta()拿原始数据,但会多跑不必要的SQL查询,想找不用额外查询的方法获取未转义的原始JSON。
解决方案
方法1:直接遍历产品的变体对象(无额外查询)
WooCommerce的$product对象已经缓存了所有变体数据,不需要额外查库。跳过get_available_variations(),直接操作变体对象:
// 获取所有变体ID(已缓存,无SQL查询) $variation_ids = $product->get_children(); foreach ( $variation_ids as $variation_id ) { // 从缓存中获取变体对象,无额外SQL $variation = wc_get_product( $variation_id ); // 第二个参数传true,获取未转义的原始元数据 $raw_json = $variation->get_meta( '_variation_description', true ); // 解析成数组使用 $json_data = json_decode( $raw_json, true ); print_r( $json_data ); }
方法2:用钩子提前把原始数据加入到get_available_variations()返回结果中
如果习惯用get_available_variations()循环,可以通过钩子在返回数据中添加原始JSON字段,后续直接取用:
// 过滤可用变体数据,添加原始描述字段 add_filter( 'woocommerce_available_variation', 'inject_raw_variation_json', 10, 3 ); function inject_raw_variation_json( $variation_data, $product, $variation ) { // 把原始JSON加入返回数组 $variation_data['raw_variation_json'] = $variation->get_meta( '_variation_description', true ); return $variation_data; }
之后循环时直接调用新增的字段:
foreach ( $product->get_available_variations() as $variation_data ) { $raw_json = $variation_data['raw_variation_json']; $json_data = json_decode( $raw_json, true ); print_r( $json_data ); }
这个钩子只会在get_available_variations()执行时触发一次,$variation对象已加载,不会额外增加SQL查询。
问题原因说明
get_available_variations()返回的variation_description是经过WooCommerce格式化的:自动添加了<p>标签(wpautop()处理),并且做了HTML实体转义,所以才会出现转义后的引号和标签。而直接调用变体对象的get_meta()并设置$single = true,就能拿到数据库里存的原始未处理JSON。
内容的提问来源于stack exchange,提问作者StefanBD

