CF7自定义select下拉功能不显示选项值及相关bug排查求助
问题1:下拉菜单不显示城市列表的原因
你对CF7的$tag结构理解错误,才会出现不渲染的问题:
- CF7的select类型标签的
raw_values和values字段本身就是存储所有选项的一维数组,不需要你把每个选项封装成独立的$tag子数组再push到原$tag里,你现在的写法相当于破坏了原标签结构,CF7解析时只会读取根层级的values数组,你当前根层级的values还是空的,自然不会渲染选项。 - 正确逻辑是:直接修改原
$tag的raw_values、values、labels数组,把城市作为元素追加到这几个数组里即可。
问题2:函数重复执行两次的原因
wpcf7_form_tag是CF7的公共钩子,会在两个场景自动触发:
- 前端页面渲染表单、解析短代码的时候执行一次
- 用户提交表单做字段校验、解析标签的时候执行一次
这是CF7的正常机制,不属于代码错误,如果不需要重复执行数据库查询,可以加判断条件,比如仅在非POST、非AJAX请求时执行查询逻辑即可。
问题3:array_unique无法去重的原因
你的用法完全不符合array_unique的函数规范:
array_unique的第一个参数是要做去重处理的数组,第二个参数是排序方式常量(比如SORT_STRING),你传入$tag['values']作为第二个参数本身就是语法错误。- 另外你之前的选项都存在
$tag的子数组里,根层级的values是空的,自然也没法做去重。正确做法是先把查询到的城市存到临时数组里,先对临时数组做去重,再批量写入$tag的对应字段。
修正后的可运行代码
add_filter( 'wpcf7_form_tag', 'filter_wpcf7_form_tag_select_city_list', 10, 2); function filter_wpcf7_form_tag_select_city_list($tag, $unused) { if ( $tag['name'] != 'city_dropdown') { return $tag; } // 仅在前端渲染时执行查询,提交校验时跳过避免重复查询 if ( defined('DOING_AJAX') && DOING_AJAX ) { return $tag; } global $wpdb; $table_name = $wpdb->prefix . 'pi_counter'; // 直接加where条件过滤无效数据,减少后续处理 $retrieve_data = $wpdb->get_results( "SELECT City FROM $table_name WHERE Count_value != '0'" ); if(empty($retrieve_data)) { return $tag; } // 收集城市并去重 $cities = []; foreach ($retrieve_data as $item) { $cities[] = $item->City; } $cities = array_unique($cities, SORT_STRING); // 写入tag对应的字段 $tag['raw_values'] = $cities; $tag['values'] = $cities; $tag['labels'] = $cities; $tag['pipes'] = new WPCF7_Pipes($cities); return $tag; }
内容的提问来源于stack exchange,提问作者Spineless
相关产品推荐
相关产品推荐

