PHP如何在字符串的多个指定位置插入内容并拼接新字符串
WordPress导航菜单多位置插入自定义内容解决方案
修复后完整可运行代码
// 补充PHP原生不存在的strpos_all方法,用于匹配所有子串的位置 function strpos_all($haystack, $needle) { $offset = 0; $positions = array(); while (($pos = strpos($haystack, $needle, $offset)) !== false) { $positions[] = $pos; $offset = $pos + strlen($needle); } return $positions; } function add_submenu_back_item( $items, $args ){ if( 'top-menu' == $args->theme_location ){ $menu_item_back = '<a class="go-back"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left-short" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M12 8a.5.5 0 0 1-.5.5H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5a.5.5 0 0 1 .5.5z"/> </svg></a>'; $insert_len = strlen($menu_item_back); $arrayPos = strpos_all( $items, 'sub-menu' ); $fixed_offset = 10; $new_items = ''; $last_process_pos = 0; $total_insert_offset = 0; foreach ($arrayPos as $original_pos) { // 计算实际插入位置:原始匹配位置+固定偏移+已插入内容带来的总偏移 $actual_insert_pos = $original_pos + $fixed_offset + $total_insert_offset; // 拼接上一次处理结束到当前插入位置的原始内容 $new_items .= substr($items, $last_process_pos, $actual_insert_pos - $last_process_pos); // 插入返回按钮 $new_items .= $menu_item_back; // 更新处理标记位和偏移累计值 $last_process_pos = $actual_insert_pos; $total_insert_offset += $insert_len; } // 拼接最后一段未处理的原始内容 $new_items .= substr($items, $last_process_pos); return $new_items; } // 非目标位置直接返回原菜单内容 return $items; } add_filter( 'wp_nav_menu_items', 'add_submenu_back_item', 10, 2 );
核心修复说明
原有代码的两个核心问题已解决:
- 避免了每次循环都基于原始完整字符串插入输出导致的内容重复,改为逐步拼接片段构建新字符串
- 新增
$total_insert_offset累计已插入内容的总长度,修正后续插入位置,解决插入内容后位置错位的问题
内容的提问来源于stack exchange,提问作者Sambuxc
相关产品推荐
相关产品推荐

