我有以下 PHP 函数,可以转换短代码,例如
[column]
[row]
[column][/column]
[/row]
[/column]
到嵌套数组
Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => row
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] =>
)
)
)
)
)
)
如果我有一个[列]作为子项,但如果我有多个列作为子项,则效果很好
[column]
[row]
[column][/column]
[column][/column]
[/row]
[/column]
然后它给了我不正确的嵌套数组,即
Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => row
[attributes] => Array
(
)
[content] => Array
(
[0] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] =>
)
)
)
)
)
[1] => Array
(
[tag] => column
[attributes] => Array
(
)
[content] =>
)
)
这是我的 PHP 函数
protected function shortCodeToArray($inputString)
{
$itemArray = [];
$openingTag = '/\[(\w+)(?:\s+([^\]]*))?\](.*?)(\[\/\1\]|$)/s';
preg_match_all($openingTag, $inputString, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$tagName = $match[1];
$paramString = isset($match[2]) ? $match[2] : '';
$content = $match[3];
$nestedShortcodes = $this->shortCodeToArray($content);
$itemArray[] = [
'tag' => $tagName,
'attributes' => $this->parseShortcodeParameters($paramString),
'content' => is_array($nestedShortcodes) && !empty($nestedShortcodes) ? $nestedShortcodes : $content,
];
}
return $itemArray;
}
protected function parseShortcodeParameters($paramString)
{
$params = [];
preg_match_all('/(\w+)\s*=\s*["\']([^"\']+)["\']/', $paramString, $matches);
for ($i = 0; $i < count($matches[0]); $i++) {
$paramName = $matches[1][$i];
$paramValue = $matches[2][$i];
$params[$paramName] = $paramValue;
}
return $params;
}
我哪里出错了?
将其转换为 HTML 标签并使用 DOM 解析器的想法怎么样?
$codes = <<<'CODES'
[column]
[row]
[column][/column]
[column][/column]
[/row]
[/column]
CODES;
$html = str_replace(['[', ']'], ['<', '>'], $codes);
libxml_use_internal_errors(true);
$dom = new \DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
echo $dom->saveHTML();
输出
<column>
<row>
<column></column>
<column></column>
</row>
</column>
现在你可以按照你想要的方式遍历 DOMDocument,甚至以简单的方式进行操作。
foreach($dom->getElementsByTagName('row') as $row) {
foreach($row->getElementsByTagName('column') as $column) {
$column->appendChild($dom->createTextNode('test'));
$column->setAttribute('class', 'test');
}
}
echo $dom->saveHTML();
<column>
<row>
<column class="test">test</column>
<column class="test">test</column>
</row>
</column>