WooCommerce我的账户自定义端点菜单:多标签对应数据库内容异常
修复WooCommerce我的账户自定义Endpoint内容重复问题
问题根源
你当前的代码中,所有自定义Endpoint都绑定了同一个pa_custom_endpoint_content函数,而该函数最终输出的是循环遍历数据库结果时的最后一个$endpointlable值,导致所有菜单项显示相同内容。同时,函数没有根据当前访问的具体Endpoint来匹配对应的数据库数据。
修复方案
修改内容输出逻辑,让函数能够识别当前访问的Endpoint,并输出对应数据库内容,同时修复SQL注入风险:
完整修复代码
function pa_custom_endpoint_keys() { global $wpdb; $pao = $wpdb->prefix . 'pao'; // 使用prepare确保查询安全 $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM %i", $pao)); $endpointsdata = array(); foreach($results as $row){ $endpointsdata[$row->pao_name] = $row->pao_value; } return $endpointsdata; } add_action( 'init', 'pa_custom_endpoint' ); function pa_custom_endpoint() { foreach(pa_custom_endpoint_keys() as $endpointkey=>$endpointlable){ add_rewrite_endpoint( $endpointkey, EP_ROOT | EP_PAGES ); } // 刷新重写规则(仅首次激活时需要,可注释或移除) flush_rewrite_rules(); } add_filter( 'query_vars', 'pa_custom_endpoint_query_vars', 0 ); function pa_custom_endpoint_query_vars( $vars ) { foreach(pa_custom_endpoint_keys() as $endpointkey=>$endpointlable){ $vars[] = $endpointkey; } return $vars; } add_filter( 'woocommerce_account_menu_items', 'pa_custom_endpoint_link_my_account' ); function pa_custom_endpoint_link_my_account( $items ) { foreach(pa_custom_endpoint_keys() as $endpointkey=>$endpointlable){ $items[$endpointkey] = $endpointlable; } return $items; } // 自定义Endpoint内容输出函数 function pa_custom_endpoint_content() { global $wp_query, $wpdb; $endpoints = pa_custom_endpoint_keys(); // 遍历所有Endpoint,匹配当前访问的项 foreach ($endpoints as $endpoint_key => $endpoint_label) { if (isset($wp_query->query_vars[$endpoint_key]) && $wp_query->query_vars[$endpoint_key]) { $pao = $wpdb->prefix . 'pao'; // 根据当前Endpoint的key查询对应数据库内容 $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM %i WHERE pao_name = %s", $pao, $endpoint_key)); if ($row) { // 输出内容,使用esc_html防止XSS风险 echo esc_html($row->pao_value); // 如需输出更多字段,可添加:echo esc_html($row->其他字段名); } else { echo '内容不存在'; } break; // 找到匹配项后终止循环 } } } // 为每个Endpoint绑定内容钩子 foreach (pa_custom_endpoint_keys() as $endpoint_key => $endpoint_label) { $hook_name = "woocommerce_account_{$endpoint_key}_endpoint"; add_action($hook_name, 'pa_custom_endpoint_content'); }
关键修改点
- 安全优化:所有数据库查询使用
$wpdb->prepare,避免SQL注入风险 - 内容匹配:通过
$wp_query->query_vars识别当前访问的Endpoint,动态输出对应数据库内容 - XSS防护:使用
esc_html过滤输出内容,防止跨站脚本攻击 - 重写规则刷新:首次激活代码时,
flush_rewrite_rules()会刷新WordPress重写规则,确保Endpoint生效(后续可注释或移除)
注意事项
- 代码添加后,需先访问一次后台的「设置-固定链接」页面,无需修改任何设置,直接保存即可刷新重写规则
- 确保你的
wp_pao表中pao_name字段的值是合法的Endpoint名称(仅包含小写字母、数字、连字符)
内容的提问来源于stack exchange,提问作者Behzad
相关产品推荐
相关产品推荐

