lib/adapter/Wind.php
protected function compile($tplFile, $compiledFile)
    {
        if(false === ($template = @file_get_contents($tplFile))) {
            throw new \wf\template\Exception("'{$tplFile}' does not exists!");
        }
        
        $template = $this->clearCommentTag($template);
        $template = $this->parseExtend($template);
        
        // {tpl xx} 包含另一个模板
        $template = preg_replace_callback("/\\{tpl\\s+['\\\"]?(.*?)['\\\"]?\\}/is", [$this, 'subTpl'], $template);
        
        
        // START 处理不解析部分  ======================
        
        // 允许模板中使用 <?xml ... ？>标签，解决xml声明标签被当做php标识符
        $template = preg_replace_callback("/(<\\?xml(.*?)\\?>)/is", function($m) {
            $str = "<?php echo '" . str_replace("'", "\'", $m[1]) . "'?>";
            return "<![wf-hold-code[" . base64_encode($str) . "]wf-hold-code]>";
        }, $template);
            
            /* {# php-code #} => <?php ... ?> */
            $template = preg_replace("/\\{#(.+?)#\\}/s", "<?php \\1?>", $template);
            
            // 将php代码进行编码防止被当做模板标签解析
            $template = preg_replace_callback("/(<\\?.+?\\?>)/is", function($m){
                return "<![wf-hold-code[" . base64_encode($m[1]) . ']wf-hold-code]>';
            }, $template);
                
                // {static}不进行解析的内容{/static} => <![wf-hold-code[编码内容]wf-hold-code]>
                $template = preg_replace_callback("/\\{static\\}(.+?)\\{\\/static\\}/s", function($m){
                    return "<![wf-hold-code[" . base64_encode($m[1]). "]wf-hold-code]>";
                }, $template);
                    
                    // END 处理不解析部分  ======================
                    
                    // url
                    $template = preg_replace("/\\{\\{\\s*url\\s+['\"]?(.*?)['\"]?\\s*\\}\\}/is", "<?php echo url(\"\\1\");?>", $template);
                    
                    // lang 语言标签 {{lang key}}
                    $template = preg_replace_callback("/\\{\\{\\s*lang\\s+['\\\"]?(.+?)['\\\"]?\\s*\\}\\}/is", function($m) {
                        return lang(trim($m[1]));
                    }, $template);
                        
                        // {if 表达式}
                        $template = preg_replace_callback("/\\{if\\s+(.+?)\\}/is", function($m){
                            return $this->quote("<?php if({$m[1]}) : ?>");
                        }, $template);
                            
                            // {elseif 表达式} {else if 表达式}
                            $template = preg_replace_callback("/\\{else\\s*if\\s+(.+?)\\}/is", function($m){
                                return $this->quote("<?php elseif({$m[1]}) : ?>");
                            }, $template);
                                
                                // {else}
                                $template = preg_replace("/\\{else\\}/is", "<?php else : ?>", $template);
                                
                                // {/if} => endif
                                $template = preg_replace("/\\{\\/if\\}/is", "<?php endif; ?>", $template);
                                
                                // {for 表达式1; 表达式2; 表达式3}
                                $template = preg_replace_callback("/\\{for\\s+(.*?)\\}/is", function($m){
                                    return $this->quote("<?php for({$m[1]}) :?>");
                                }, $template);
                                    
                                    // {/for} => endfor
                                    $template = preg_replace("/\\{\\/for\\}/is", "<?php endfor; ?>", $template);
                                    
                                    // {loop $arr $v} => foreach($arr as $v)
                                    if(preg_match_all("/\\{loop\\s+?(\\S+?)\\s+?(\\S+?)\\}/s", $template, $matches)) {
                                        $search = [];
                                        $replace = [];
                                        foreach ($matches[0] as $k => $mat) {
                                            $search[$k] = $mat;
                                            $replaceStr = "<?php
                                            \$__loop__tmp__{$k} = @{$matches[1][$k]};
                                            if(!empty(\$__loop__tmp__{$k}) && !is_scalar(\$__loop__tmp__{$k})):
                                            foreach(\$__loop__tmp__{$k} as {$matches[2][$k]}) :
                                            ?>";
                                            $replace[$k] = $this->quote($replaceStr);
                                        }
                                        $template = str_replace($search, $replace, $template);
                                    }
                                    
                                    // {loop $arr $k $v} => foreach($arr as $k => $v)
                                    if(preg_match_all("/\\{loop\\s+?(\\S+?)\\s+?(\\S+)?\\s+?(\\S+?)\\}/s", $template, $matches)) {
                                        $search = [];
                                        $replace = [];
                                        foreach ($matches[0] as $k => $mat) {
                                            $search[$k] = $mat;
                                            $replaceStr = "<?php
                                            \$__loop__tmp__x_{$k} = @{$matches[1][$k]};
                                            if(!empty(\$__loop__tmp__x_{$k}) && !is_scalar(\$__loop__tmp__x_{$k})):
                                            foreach(\$__loop__tmp__x_{$k} as {$matches[2][$k]} => {$matches[3][$k]}) :
                                            ?>";
                                            $replace[$k] = $this->quote($replaceStr);
                                        }
                                        $template = str_replace($search, $replace, $template);
                                    }
                                    
                                    // {/loop} => endforeach
                                    $template = preg_replace("/\\{\\/loop\\}/", "<?php endforeach; endif; ?>", $template );
                                    
                                    // 外部变量先进行xss过滤
                                    $template = preg_replace("/\\{\\{\\s*,}(\\$\\_(GET|POST|REQUEST|COOKIE)\\[.*?\\])\\s*\\}\\}/", "{{htmlspecialchars(@$1)}}", $template);
                                    
                                    // echo 常量 {{CONST}}
                                    $template = preg_replace("/\\{\\{\\s*([A-Z_][A-Z0-9_]+)\\s*\\}\\}/", "<?php defined('\\1') && print \\1;?>", $template );
                                    
                                    // echo 变量/数组/函数/对象属性、方法/类静态属性、方法/类常量
                                    /* {{xxxx}} => <?php echo xxxx ?> */
                                    $template = preg_replace_callback("/\\{\\{\\s*([@a-z_\\$\\\\].+?)\\s*\\}\\}/i", function($m){
                                        return $this->quote("<?php echo @{$m[1]};?>");
                                    }, $template);
                                        
                                        // 还原不解析的内容<![wf-hold-code[编码内容]wf-hold-code]>
                                        $template = preg_replace_callback("/<\\!\\[wf-hold-code\\[(.+?)\\]wf-hold-code\\]>/s", function($m){
                                            return str_replace("\\\"", "\"", base64_decode($m[1]));
                                        }, $template);
                                            
                                            // 添加在模板顶部的文件说明信息
                                            $thisTplMsg = "<?php\n/**\n"
                                                . " * (Don't edit this file)\n"
                                                    . " * Windwork Template View\n"
                                                        . " * Make by Windwork template engine\n"
                                                            . " * \n"
                                                                . " * File: {$compiledFile}\n"
                                                                . " * From: {$tplFile}\n"
                                                                . " * Time: ". date('Y-m-d H:i:s') . "\n"
                                                                    . " */\n"
                                                                        . "defined('WF_IN') || die('Access Denied');\n"
                                                                            . "?>";
                                                                            
                                                                            // 保存“编译”后模板文件
                                                                            @file_put_contents($compiledFile, $thisTplMsg . $template);
                                                                            
                                                                            return true;
    }
protected function compile($tplFile, $compiledFile)
    {
        if(false === ($template = @file_get_contents($tplFile))) {
            throw new \wf\template\Exception("'{$tplFile}' does not exists!");
        }
        
        $template = $this->clearCommentTag($template);
        $template = $this->parseExtend($template);
        
        // {tpl xx} 包含另一个模板
        $template = preg_replace_callback("/\\{tpl\\s+['\\\"]?(.*?)['\\\"]?\\}/is", [$this, 'subTpl'], $template);
        
        
        // START 处理不解析部分  ======================
        
        // 允许模板中使用 <?xml ... ？>标签，解决xml声明标签被当做php标识符
        $template = preg_replace_callback("/(<\\?xml(.*?)\\?>)/is", function($m) {
            $str = "<?php echo '" . str_replace("'", "\'", $m[1]) . "'?>";
            return "<![wf-hold-code[" . base64_encode($str) . "]wf-hold-code]>";
        }, $template);
            
            /* {# php-code #} => <?php ... ?> */
            $template = preg_replace("/\\{#(.+?)#\\}/s", "<?php \\1?>", $template);
            
            // 将php代码进行编码防止被当做模板标签解析
            $template = preg_replace_callback("/(<\\?.+?\\?>)/is", function($m){
                return "<![wf-hold-code[" . base64_encode($m[1]) . ']wf-hold-code]>';
            }, $template);
                
                // {static}不进行解析的内容{/static} => <![wf-hold-code[编码内容]wf-hold-code]>
                $template = preg_replace_callback("/\\{static\\}(.+?)\\{\\/static\\}/s", function($m){
                    return "<![wf-hold-code[" . base64_encode($m[1]). "]wf-hold-code]>";
                }, $template);
                    
                    // END 处理不解析部分  ======================
                    
                    // url
                    $template = preg_replace("/\\{\\{\\s*url\\s+['\"]?(.*?)['\"]?\\s*\\}\\}/is", "<?php echo url(\"\\1\");?>", $template);
                    
                    // lang 语言标签 {{lang key}}
                    $template = preg_replace_callback("/\\{\\{\\s*lang\\s+['\\\"]?(.+?)['\\\"]?\\s*\\}\\}/is", function($m) {
                        return lang(trim($m[1]));
                    }, $template);
                        
                        // {if 表达式}
                        $template = preg_replace_callback("/\\{if\\s+(.+?)\\}/is", function($m){
                            return $this->quote("<?php if({$m[1]}) : ?>");
                        }, $template);
                            
                            // {elseif 表达式} {else if 表达式}
                            $template = preg_replace_callback("/\\{else\\s*if\\s+(.+?)\\}/is", function($m){
                                return $this->quote("<?php elseif({$m[1]}) : ?>");
                            }, $template);
                                
                                // {else}
                                $template = preg_replace("/\\{else\\}/is", "<?php else : ?>", $template);
                                
                                // {/if} => endif
                                $template = preg_replace("/\\{\\/if\\}/is", "<?php endif; ?>", $template);
                                
                                // {for 表达式1; 表达式2; 表达式3}
                                $template = preg_replace_callback("/\\{for\\s+(.*?)\\}/is", function($m){
                                    return $this->quote("<?php for({$m[1]}) :?>");
                                }, $template);
                                    
                                    // {/for} => endfor
                                    $template = preg_replace("/\\{\\/for\\}/is", "<?php endfor; ?>", $template);
                                    
                                    // {loop $arr $v} => foreach($arr as $v)
                                    if(preg_match_all("/\\{loop\\s+?(\\S+?)\\s+?(\\S+?)\\}/s", $template, $matches)) {
                                        $search = [];
                                        $replace = [];
                                        foreach ($matches[0] as $k => $mat) {
                                            $search[$k] = $mat;
                                            $replaceStr = "<?php
                                            \$__loop__tmp__{$k} = @{$matches[1][$k]};
                                            if(!empty(\$__loop__tmp__{$k}) && !is_scalar(\$__loop__tmp__{$k})):
                                            foreach(\$__loop__tmp__{$k} as {$matches[2][$k]}) :
                                            ?>";
                                            $replace[$k] = $this->quote($replaceStr);
                                        }
                                        $template = str_replace($search, $replace, $template);
                                    }
                                    
                                    // {loop $arr $k $v} => foreach($arr as $k => $v)
                                    if(preg_match_all("/\\{loop\\s+?(\\S+?)\\s+?(\\S+)?\\s+?(\\S+?)\\}/s", $template, $matches)) {
                                        $search = [];
                                        $replace = [];
                                        foreach ($matches[0] as $k => $mat) {
                                            $search[$k] = $mat;
                                            $replaceStr = "<?php
                                            \$__loop__tmp__x_{$k} = @{$matches[1][$k]};
                                            if(!empty(\$__loop__tmp__x_{$k}) && !is_scalar(\$__loop__tmp__x_{$k})):
                                            foreach(\$__loop__tmp__x_{$k} as {$matches[2][$k]} => {$matches[3][$k]}) :
                                            ?>";
                                            $replace[$k] = $this->quote($replaceStr);
                                        }
                                        $template = str_replace($search, $replace, $template);
                                    }
                                    
                                    // {/loop} => endforeach
                                    $template = preg_replace("/\\{\\/loop\\}/", "<?php endforeach; endif; ?>", $template );
                                    
                                    // 外部变量先进行xss过滤
                                    $template = preg_replace("/\\{\\{\\s*,}(\\$\\_(GET|POST|REQUEST|COOKIE)\\[.*?\\])\\s*\\}\\}/", "{{htmlspecialchars(@$1)}}", $template);
                                    
                                    // echo 常量 {{CONST}}
                                    $template = preg_replace("/\\{\\{\\s*([A-Z_][A-Z0-9_]+)\\s*\\}\\}/", "<?php defined('\\1') && print \\1;?>", $template );
                                    
                                    // echo 变量/数组/函数/对象属性、方法/类静态属性、方法/类常量
                                    /* {{xxxx}} => <?php echo xxxx ?> */
                                    $template = preg_replace_callback("/\\{\\{\\s*([@a-z_\\$\\\\].+?)\\s*\\}\\}/i", function($m){
                                        return $this->quote("<?php echo @{$m[1]};?>");
                                    }, $template);
                                        
                                        // 还原不解析的内容<![wf-hold-code[编码内容]wf-hold-code]>
                                        $template = preg_replace_callback("/<\\!\\[wf-hold-code\\[(.+?)\\]wf-hold-code\\]>/s", function($m){
                                            return str_replace("\\\"", "\"", base64_decode($m[1]));
                                        }, $template);
                                            
                                            // 添加在模板顶部的文件说明信息
                                            $thisTplMsg = "<?php\n/**\n"
                                                . " * (Don't edit this file)\n"
                                                    . " * Windwork Template View\n"
                                                        . " * Make by Windwork template engine\n"
                                                            . " * \n"
                                                                . " * File: {$compiledFile}\n"
                                                                . " * From: {$tplFile}\n"
                                                                . " * Time: ". date('Y-m-d H:i:s') . "\n"
                                                                    . " */\n"
                                                                        . "defined('WF_IN') || die('Access Denied');\n"
                                                                            . "?>";
                                                                            
                                                                            // 保存“编译”后模板文件
                                                                            @file_put_contents($compiledFile, $thisTplMsg . $template);
                                                                            
                                                                            return true;
    }
编译模板

@param string $tplFile
@param string $compiledFile
@return bool
@throws \wf\template\Exception 如果模板文件不存在则抛出异常