Think/Template.php
public function parseTagLib(TagLib $tagLib, &$content)
    {
        $begin = $this->config['taglib_begin'];
        $end = $this->config['taglib_end'];
        $that = &$this;
        foreach ($tagLib->getTags() as $name => $val) {
            $tags = [$name];
            // 别名设置
            if (isset($val['alias'])) {
                $tags = explode(',', $val['alias']);
                $tags[] = $name;
            }
            $level = isset($val['level']) ? $val['level'] : 1;
            $closeTag = isset($val['close']) ? $val['close'] : true;
            foreach ($tags as $tag) {
                if (!method_exists($tagLib, '_'.$tag)) {
                    // 别名可以无需定义解析方法
                    $tag = $name;
                }
                $patternTail = empty($val['attr']) ? '(\s*?)' : '\s([^'.$end.']*)';

                if (!$closeTag) {
                    $patterns = '/'.$begin.$tag.$patternTail.'\/(\s*?)'.$end.'/is';
                    $content = preg_replace_callback(
                        $patterns,
                        function ($matches) use ($tagLib, $tag, $that) {
                            return $that->parseXmlTag($tagLib, $tag, $matches[1], $matches[2]);
                        },
                        $content
                    );
                } else {
                    $patterns = '/'.$begin.$tag.$patternTail.$end.'(.*?)'.$begin.'\/'.$tag.'(\s*?)'.$end.'/is';
                    for ($i = 0; $i < $level; $i++) {
                        $content = preg_replace_callback(
                            $patterns,
                            function ($matches) use ($tagLib, $tag, $that) {
                                return $that->parseXmlTag($tagLib, $tag, $matches[1], $matches[2]);
                            },
                            $content
                        );
                    }
                }
            }
        }
    }
public function parseTagLib(TagLib $tagLib, &$content)
    {
        $begin = $this->config['taglib_begin'];
        $end = $this->config['taglib_end'];
        $that = &$this;
        foreach ($tagLib->getTags() as $name => $val) {
            $tags = [$name];
            // 别名设置
            if (isset($val['alias'])) {
                $tags = explode(',', $val['alias']);
                $tags[] = $name;
            }
            $level = isset($val['level']) ? $val['level'] : 1;
            $closeTag = isset($val['close']) ? $val['close'] : true;
            foreach ($tags as $tag) {
                if (!method_exists($tagLib, '_'.$tag)) {
                    // 别名可以无需定义解析方法
                    $tag = $name;
                }
                $patternTail = empty($val['attr']) ? '(\s*?)' : '\s([^'.$end.']*)';

                if (!$closeTag) {
                    $patterns = '/'.$begin.$tag.$patternTail.'\/(\s*?)'.$end.'/is';
                    $content = preg_replace_callback(
                        $patterns,
                        function ($matches) use ($tagLib, $tag, $that) {
                            return $that->parseXmlTag($tagLib, $tag, $matches[1], $matches[2]);
                        },
                        $content
                    );
                } else {
                    $patterns = '/'.$begin.$tag.$patternTail.$end.'(.*?)'.$begin.'\/'.$tag.'(\s*?)'.$end.'/is';
                    for ($i = 0; $i < $level; $i++) {
                        $content = preg_replace_callback(
                            $patterns,
                            function ($matches) use ($tagLib, $tag, $that) {
                                return $that->parseXmlTag($tagLib, $tag, $matches[1], $matches[2]);
                            },
                            $content
                        );
                    }
                }
            }
        }
    }
TagLib库解析


@param TagLib $tagLib 要解析的标签库
@param string $content 要解析的模板内容

@return string