PHP:拆分WordPress内容数组,包含所有标签(不限于段落)
解决方案
原代码仅以<p>标签作为分割依据,忽略了标题、图片等其他内容块,导致计数不准确。我们可以通过DOM解析来遍历所有内容单元,把标题、段落、图片容器等都纳入计数范围,再按间隔插入图片。
以下是修改后的代码:
<?php $content = apply_filters('the_content', get_the_content()); // 初始化DOM文档,处理HTML标签 $dom = new DOMDocument(); // 防止DOM解析时出现编码问题 libxml_use_internal_errors(true); $dom->loadHTML('<?xml encoding="UTF-8">' . $content); libxml_clear_errors(); $xpath = new DOMXPath($dom); // 选取所有顶级内容块:段落、标题、图片容器、列表等可作为独立内容单元的标签 $contentNodes = $xpath->query('//body/*[self::p or self::h1 or self::h2 or self::h3 or self::h4 or self::h5 or self::h6 or self::figure or self::ul or self::ol]'); $insertPositions = [3, 6, 9, 12, 15]; // 要插入图片的位置(从1开始计数) $spots = [$spot1, $spot2, $spot3, $spot4, $spot5]; // 图片内容数组 $spotIndex = 0; // 遍历内容节点,按位置插入图片 foreach ($contentNodes as $index => $node) { // 数组索引从0开始,所以位置要减1 if (in_array($index + 1, $insertPositions) && isset($spots[$spotIndex])) { // 将图片内容转为DOM节点 $imgDom = new DOMDocument(); libxml_use_internal_errors(true); $imgDom->loadHTML('<?xml encoding="UTF-8">' . $spots[$spotIndex]); libxml_clear_errors(); $imgNode = $dom->importNode($imgDom->getElementsByTagName('body')->item(0)->firstChild, true); // 在当前节点之后插入图片 $node->parentNode->insertBefore($imgNode, $node->nextSibling); $spotIndex++; } } // 输出处理后的内容 echo $dom->saveHTML($dom->getElementsByTagName('body')->item(0)->firstChild); ?>
关键说明:
- DOM解析替代字符串分割:用
DOMDocument和DOMXPath准确识别所有内容单元,避免字符串分割的局限性。 - 自定义内容单元范围:XPath查询里的
self::p or self::h1 ...可以根据需求调整,比如添加self::div来包含特定的div容器。 - 插入逻辑:按内容单元的计数(从1开始)匹配插入位置,把图片内容转为DOM节点后插入到目标位置的下一个节点前。
- 编码处理:添加
<?xml encoding="UTF-8">前缀防止中文等非ASCII字符乱码。
内容的提问来源于stack exchange,提问作者Paul VI
相关产品推荐
相关产品推荐

