<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] * * * * * # 1 標簽庫 >>標簽庫,可以用來自定義模板文件中的標簽解析方式 >在tp5中自定義了內置標簽庫(Cx.php) ### $taglib->__construct() >>標簽庫構造函數,創建標簽庫對象 ~~~ public function __construct($template) { $this->tpl = $template; } ~~~ # 2 標簽庫的標簽解析 ## 2-1 標簽庫的標簽解析 >>標簽庫可以用來解析模板文件中的自定義標簽 ### $taglib->parseTag() ~~~ public function parseTag(&$content, $lib = '') { $tags = []; $lib = $lib ? strtolower($lib) . ':' : ''; foreach ($this->tags as $name => $val) { $close = !isset($val['close']) || $val['close'] ? 1 : 0; $tags[$close][$lib . $name] = $name; if (isset($val['alias'])) { // 別名設置 $array = (array) $val['alias']; foreach (explode(',', $array[0]) as $v) { $tags[$close][$lib . $v] = $name; } } } // 閉合標簽 if (!empty($tags[1])) { $nodes = []; $regex = $this->getRegex(array_keys($tags[1]), 1); if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { $right = []; foreach ($matches as $match) { if ('' == $match[1][0]) { $name = strtolower($match[2][0]); // 如果有沒閉合的標簽頭則取出最后一個 if (!empty($right[$name])) { // $match[0][1]為標簽結束符在模板中的位置 $nodes[$match[0][1]] = [ 'name' => $name, 'begin' => array_pop($right[$name]), // 標簽開始符 'end' => $match[0], // 標簽結束符 ]; } } else { // 標簽頭壓入棧 $right[strtolower($match[1][0])][] = $match[0]; } } unset($right, $matches); // 按標簽在模板中的位置從后向前排序 krsort($nodes); } $break = '<!--###break###--!>'; if ($nodes) { $beginArray = []; // 標簽替換 從后向前 foreach ($nodes as $pos => $node) { // 對應的標簽名 $name = $tags[1][$node['name']]; $alias = $lib . $name != $node['name'] ? ($lib ? strstr($node['name'], $lib) : $node['name']) : ''; // 解析標簽屬性 $attrs = $this->parseAttr($node['begin'][0], $name, $alias); $method = 'tag' . $name; // 讀取標簽庫中對應的標簽內容 replace[0]用來替換標簽頭,replace[1]用來替換標簽尾 $replace = explode($break, $this->$method($attrs, $break)); if (count($replace) > 1) { while ($beginArray) { $begin = end($beginArray); // 判斷當前標簽尾的位置是否在棧中最后一個標簽頭的后面,是則為子標簽 if ($node['end'][1] > $begin['pos']) { break; } else { // 不為子標簽時,取出棧中最后一個標簽頭 $begin = array_pop($beginArray); // 替換標簽頭部 $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']); } } // 替換標簽尾部 $content = substr_replace($content, $replace[1], $node['end'][1], strlen($node['end'][0])); // 把標簽頭壓入棧 $beginArray[] = ['pos' => $node['begin'][1], 'len' => strlen($node['begin'][0]), 'str' => $replace[0]]; } } while ($beginArray) { $begin = array_pop($beginArray); // 替換標簽頭部 $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']); } } } // 自閉合標簽 if (!empty($tags[0])) { $regex = $this->getRegex(array_keys($tags[0]), 0); $content = preg_replace_callback($regex, function ($matches) use (&$tags, &$lib) { // 對應的標簽名 $name = $tags[0][strtolower($matches[1])]; $alias = $lib . $name != $matches[1] ? ($lib ? strstr($matches[1], $lib) : $matches[1]) : ''; // 解析標簽屬性 $attrs = $this->parseAttr($matches[0], $name, $alias); $method = 'tag' . $name; return $this->$method($attrs, ''); }, $content); } return; } ~~~ ### $taglib->getRegex() >>標簽的正則表達式 ~~~ private function getRegex($tags, $close) { $begin = $this->tpl->config('taglib_begin'); $end = $this->tpl->config('taglib_end'); $single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false; $tagName = is_array($tags) ? implode('|', $tags) : $tags; if ($single) { if ($close) { // 如果是閉合標簽 $regex = $begin . '(?:(' . $tagName . ')\b(?>[^' . $end . ']*)|\/(' . $tagName . '))' . $end; } else { $regex = $begin . '(' . $tagName . ')\b(?>[^' . $end . ']*)' . $end; } } else { if ($close) { // 如果是閉合標簽 $regex = $begin . '(?:(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)|\/(' . $tagName . '))' . $end; } else { $regex = $begin . '(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)' . $end; } } return '/' . $regex . '/is'; } ~~~ ### $taglib->parseAttr() >> 使用正則表達式分析標簽屬性 ~~~ public function parseAttr($str, $name, $alias = '') { $regex = '/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?P<value>(?:(?!\\2).)*)\\2/is'; $result = []; if (preg_match_all($regex, $str, $matches)) { foreach ($matches['name'] as $key => $val) { $result[$val] = $matches['value'][$key]; } if (!isset($this->tags[$name])) { // 檢測是否存在別名定義 foreach ($this->tags as $key => $val) { if (isset($val['alias'])) { $array = (array) $val['alias']; if (in_array($name, explode(',', $array[0]))) { $tag = $val; $type = !empty($array[1]) ? $array[1] : 'type'; $result[$type] = $name; break; } } } } else { $tag = $this->tags[$name]; // 設置了標簽別名 if (!empty($alias) && isset($tag['alias'])) { $type = !empty($tag['alias'][1]) ? $tag['alias'][1] : 'type'; $result[$type] = $alias; } } if (!empty($tag['must'])) { $must = explode(',', $tag['must']); foreach ($must as $name) { if (!isset($result[$name])) { throw new Exception('tag attr must:' . $name); } } } } else { // 允許直接使用表達式的標簽 if (!empty($this->tags[$name]['expression'])) { static $_taglibs; if (!isset($_taglibs[$name])) { $_taglibs[$name][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $name); $_taglibs[$name][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\')); } $result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]); // 清除自閉合標簽尾部/ $result['expression'] = rtrim($result['expression'], '/'); $result['expression'] = trim($result['expression']); } elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) { throw new Exception('tag error:' . $name); } } return $result; } ~~~ ## 2-2 標簽庫的其他輔助解析函數 ### $taglib->getTags() >>獲取標簽定義 ~~~ public function getTags() { return $this->tags; } ~~~ # 3 內置標簽庫 >> TP5在\template\tablig\Cx.php中,定義了內置標簽的解析方式 >每個標簽的解析實現為相應標簽的tagxx()方法 ### $cx->tagPhp() ### $cx->tagVolist() ### $cx->tagForeach() ### $cx->tagIf() ### $cx->tagElseif() ### $cx->tagElse() ### $cx->tagSwitch() ### $cx->tagCase() ### $cx->tagDefault() ### $cx->tagCompare() ### $cx->tagRange() ### $cx->tagPresent() ### $cx->tagNotPresent() ### $cx->tagEmpty() ### $cx->tagNotempty() ### $cx->tagDefined() ### $cx->tagNotdefined() ### $cx->tagLoad() ### $cx->tagAssign() ### $cx->tagDefine() ### $cx->tagFor() ### $cx->tagUrl() ### $cx->tagFunction()
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看