<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### 模板編譯流程,大概是: 1. 先獲取到View類實例(依賴注入也好,通過助手函數也好) 2. 使用View編譯方法fetch或display。都會通過engine方法獲取到當前的模板驅動 3. 把模板以及要編譯的數據傳入到驅動中對應的display方法或fetch方法 4. display和fetch差不多(個人感覺),這倆的大致流程都是 5. 判斷緩存文件失效沒,如果失效重新編譯放入緩存目錄。如果沒失效則直接讀取輸出或返回 ### 1、app\\controller\\Index->Index() 控制器方法 ``` public function index(View $view) { //定義一個data變量,是個關聯數組 $data = [ 'data'=>'我是變量data', 'msg'=>'我是變量msg' ]; //直接調用View實例中的fetch方法進行渲染。并把data傳入進去 return $view->fetch('index',$data); //第二種方式 $strings = "{$data}-{$msg}"; return $view->assign($data)->display($strings,$data); } ``` 上面代碼所示,tp的渲染模板。默認有兩種方式,一種是調用fetch直接進行渲染。第二種就是先調用assign方法傳入要渲染的數據。然后再調用display方法進行渲染。(還有助手函數view().這里就不過多描述了) ### 2、接下來就講講tp是如何將數據渲染到模板上。并且輸出①第一種方式首先會調用\\Think\\View視圖類中的fetch方法 ``` public function fetch(string $template = '', array $vars = []): string { //調用類中的getContent方法,并將模板文件、渲染的數據 //封裝成匿名函數傳入到getContent方法中 return $this->getContent(function () use ($vars, $template) { $this->engine()->fetch($template, array_merge($this->data, $vars)); }); } ``` ### 接下來看下getContent方法 ``` //這個方法,主要就是把傳入過來的匿名函數給運行一下 //通過ob_系列函數捕捉到緩沖區的輸出 //然后將捕捉到的緩沖區內容返回 protected function getContent($callback): string { //開啟緩存 ob_start(); //取消緩存輸出到頁面上 ob_implicit_flush(0); //開始渲染 try { //執行閉包 $callback(); } catch (\Exception $e) { //如果閉包函數執行失敗則清空緩存 ob_end_clean(); //然后彈出異常 throw $e; } //獲取并清空緩存 $content = ob_get_clean(); //如果filter有閉包。一般為替換當前頁面的什么東西。執行一下 if ($this->filter) { $content = call_user_func_array($this->filter, [$content]); } //最后直接返回 return $content; } ``` ### 傳入的閉包內容 ``` //大概就是獲取視圖驅動,然后傳入模板和數據,渲染模板 $this->engine()->fetch($template, array_merge($this->data, $vars)); ``` ``` ### 追蹤到engine方法//這個就不多解釋什么了,主要就是獲取視圖驅動的實例 public function engine(string $type = null) { return $this->driver($type); } ``` ### 3、再追蹤到tp默認視圖驅動中的fetch方法 ``` public function fetch(string $template, array $vars = []): void //判斷是否有數據如果有則合并this->data if ($vars) { $this->data = array_merge($this->data, $vars); } //判斷有沒有緩存,如果有。則直接輸出緩存 if (!empty($this->config['cache_id']) && $this->config['display_cache'] && $this->cache) { // 讀取渲染緩存 if ($this->cache->has($this->config['cache_id'])) { echo $this->cache->get($this->config['cache_id']); return; } } //解析傳入過來的模板名 $template = $this->parseTemplateFile($template); if ($template) { //這里生成一下緩存路徑+模板 $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($this->config['layout_on'] . $this->config['layout_name'] . $template) . '.' . ltrim($this->config['cache_suffix'], '.'); //判斷緩存文件是否還有效,或者存在 if (!$this->checkCache($cacheFile)) { // 緩存無效 重新模板編譯 //如果不存在,讀取模板。并調用compiler重新編譯 $content = file_get_contents($template); $this->compiler($content, $cacheFile); } //開啟頁面緩存 ob_start(); //禁止直接輸出 ob_implicit_flush(0); // 讀取編譯存儲 $this->storage->read($cacheFile, $this->data); // 獲取并清空緩存 $content = ob_get_clean(); if (!empty($this->config['cache_id']) && $this->config['display_cache'] && $this->cache) { // 緩存頁面輸出 $this->cache->set($this->config['cache_id'], $content, $this->config['cache_time']); } //輸出編譯后的內容 echo $content; } } ``` ### 這里主要是編譯模板的方法 compiler。主要就是把模板內的文件都替換掉 ``` private function compiler(string &$content, string $cacheFile): void { // 判斷是否啟用布局 if ($this->config['layout_on']) { if (false !== strpos($content, '{__NOLAYOUT__}')) { // 可以單獨定義不使用布局 $content = str_replace('{__NOLAYOUT__}', '', $content); } else { // 讀取布局模板 $layoutFile = $this->parseTemplateFile($this->config['layout_name']); if ($layoutFile) { // 替換布局的主體內容 $content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile)); } } } else { $content = str_replace('{__NOLAYOUT__}', '', $content); } //這里是替換模板內的tp語法例如 {$data} = echo $data //{if (1==1))} == <?php if (1==1): ?> //{/endif} == <?php endif;?> $this->parse($content); if ($this->config['strip_space']) { /* 去除html空格與換行 */ $find = ['~>\s+<~', '~>(\s+\n|\r)~']; $replace = ['><', '>']; $content = preg_replace($find, $replace, $content); } // 優化生成的php代碼 $content = preg_replace('/\?>\s*<\?php\s(?!echo\b|\bend)/s', '', $content); // 模板過濾輸出 $replace = $this->config['tpl_replace_string']; $content = str_replace(array_keys($replace), array_values($replace), $content); // 添加安全代碼及模板引用記錄 $content = '<?php /*' . serialize($this->includeFile) . '*/ ?>' . "\n" . $content; //寫入緩存 $this->storage->write($cacheFile, $content); $this->includeFile = []; } ``` ### 接著回到fetch方法中 ``` / 讀取編譯存儲 $this->storage->read($cacheFile, $this->data); ``` ### 這里是獲取到\\Think\\template\\driver\\File類實例并且將緩存文件和數據傳入到read方法中 ``` public function read(string $cacheFile, array $vars = []): void { $this->cacheFile = $cacheFile; if (!empty($vars) && is_array($vars)) { //通過extract方法,將數據寫到符號表內 extract($vars, EXTR_OVERWRITE); } //載入模版緩存文件 include $this->cacheFile; } ``` # 到這里,第一種方式流程就算是完了 第二種、display方法去渲染 ``` //這個和第一種流程第一步一樣,不多解釋 public function display(string $content, array $vars = []): string { return $this->getContent(function () use ($vars, $content) { //調用template中的display方法,并將content和數據傳入進去 $this->engine()->display($content, array_merge($this->data, $vars)); }); } ``` ### 追蹤到Template類中的display方法 ``` public function display(string $content, array $vars = []): void { //判斷有沒有要編譯的數據/如果有就和this->data叔祖1合并 if ($vars) { $this->data = array_merge($this->data, $vars); } //獲取到編譯后的緩存模板 $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . '.' . ltrim($this->config['cache_suffix'], '.'); //調用checkCahce把緩存模板傳入進去,查看是否過期 //或不存在 if (!$this->checkCache($cacheFile)) { //如果模板無效或不存在,就調用 //compiler方法重寫緩存 $this->compiler($content, $cacheFile); } // 讀取編譯存儲 $this->storage->read($cacheFile, $this->data); } ```
                  <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>

                              哎呀哎呀视频在线观看