自分用のテンプレート解析プログラムV 0.1(プラグインと拡張機能をサポート)(構想の検討と使用体験)


前段階でphpを使用するプロジェクトがあり,3人組チームを組んで開発した.
プロジェクトではテンプレート解析を使用していますが、まず説明します.個人的には:
1、テンプレート解析はcmsのみではなく、中小規模企業や政府アプリケーション、特にOAのような自動化システムにも適用される.
2、ウェブサイトに運用する場合、テンプレートの解析速度と性能がより主要であり、ソフトウェアに応用する場合、より重要なのは便利で、多重性が強く、移植性が強い(この点は特に重要である)
3、テンプレート解析はあくまで変数置換であるが、ページは固定されたソフトウェアインタフェースに比べて複雑すぎるため、海外の複雑なテンプレートエンジンを使用することはお勧めできない.△国内のプログラマーの多くは「時間がない」.
4、テンプレートの解析の过程の中で往々にしていくつかのカスタム関数を必要として、国外の主なプログラムを修正するのは比较的に复雑で、依然として时间がありません.
そのため、チームメンバーにこのテンプレート解析プログラムを開発するのに少し時間がかかりました.効果はまあまあですが、性能は普通でしょう.しかし、私たちは中小規模企業のアプリケーションで使っています.
企業の応用が煩雑なのはフォームであり、リーダーはフォームに対する要求が高く、味も重く、同じテーブルの操作では、インタフェースの追加と修正が異なるため、テンプレートを使用してデータをロードすることが第一選択である.
このテンプレート解析プログラムの機能は比較的に簡単でバックグラウンドでデータのバインドを行った後、フロントは無限に循環データをネストすることができて、個人が比較的に好きなのは、コードプラグインをサポートして、例えば私はページの中でif elseの判断をサポートしたいと思って、自分で解析プログラムを書いてロードして、解析を行うことができて、同時にカスタム関数をサポートして、関数の作成はphpコードを直接使用すればよい.以下に説明します
まず、ページテンプレートは次のとおりです.
 <!--open_func-->            ,               ,
 <!--import_func="./tplfun.inc"--> //         ,      n 
 <!--import_plug="./plug_if.inc"--> //          ,      if else      ,     if else   
 <html>
<head>
 
         <!-- BEGIN commonHtml -->  //         ,      array        
         
           <plugin:IF> //         
              <!--if({miniui}==3)-->
                      
                <!--if("{default}"=="    ")-->
                         
                 <!--endif-->
               <!--else-->
                       
              <!--endif-->
             </plugin:IF>
           
           
           <!--include_file="./test.txt"--> //      include     ,                     
           
           <!-- END commonHtml --> //         
      
      <style>
       .table th{text-align:center;}
       .table td{
        line-height:25pt;height:25pt
       }
      </style>
       
     </head>
      
     <body>
     <plugin:IF>
      <!--if("{username}"=="admin888")-->
             
        <!--else-->
               
      <!--endif-->
     </plugin:IF>
    
         {setcolor(upper(username),"red")}
         <div id="main">
           <div style="padding-left:11px;padding-bottom:5px;">
            <!-- BEGIN commonHtml -->{setcolor(miniui,"red")}<!-- END commonHtml -->aa
            
            
         <!-- BEGIN datalist1 -->{setcolor(password,"red")}<!-- END datalist1 -->bb
         </div>
           <script>
          
 
     
         </body>
         </html>

ここで、変数はカッコを使用して{username}がkeyがusernameである変数を表す
このテンプレートを実行するにはメインプログラムが必要です
コードは次のとおりです.
 require("./navtpl.inc");
   $tpl=new navtemplate("./","test.tpl");
   
   $data=array();
   $data[]=array("default"=>"    ","miniui"=>"3");
   $tpl->initTpl();
   $data2=array();
   $data2[]=array("password"=>"123");
   $tpl->set_var("username",'admin888'); //      
     $tpl->set_block_var("commonHtml",$data);//         
   $tpl->set_block_var("datalist1",$data2);//         
    $tpl->parse(); //          

関数ライブラリを開いたので、以下のようにテストするために自分で関数ファイルを書きました.
<?php
 
  function len($str)
  {
    return "";
  }
  function lower($str)
  {
    return strtolower($str);
  }
  function upper($str)
  {
    return strtoupper($str);
  }
  function substring($str,$start,$length,$c="utf-8")
  {
    return mb_substr($str,$start,$length,$c);
  }
  function setcolor($st,$color)
  {
    return "<span style='color:$color'>$st</span>";
  }
?>

次はif else endifの文法解析です.このプラグインを書いてみましたが、メインテンプレートプログラムにロードしてみると、if elseだけをサポートしているのにelseifをサポートしていないので、時間がないので、elseifのサポートを書いていません.
興味のある方は自分で広げられる
コードは次のとおりです.
<?php
 
  class plugin_IF_ //    
  {
    var $tag="/\<plugin:IF\>(.*?)\<\/plugin:IF\>/s";
    function getLineCnt($begin,$end,$else,$list,$istrue)
    {
        if($begin==$end || $begin>$end || $begin<0) return "";//             
        $ret="";
       
        for($i=0;$i<=count($list)-1;$i++)
        {
          
            if($istrue)
            {
                $tmp=$list[$i];
                if($else>0)
                {
                     if($i>$else && $i<$end) continue;
                     
                }
                if($i==$begin)
                {
                   $tmp=preg_replace("/<!--if\((.*?)\)-->/s","",$tmp);
                }
                 if($i==$end)
                {
                    $tmp=preg_replace("/<!--endif-->/s","",$tmp);
                }
                if($i==$else)
                  $tmp=preg_replace("/<!--else-->/s","",$tmp);
                     if(trim($tmp)!="")
                    $ret.=chr(13).$list[$i];  
            }
            else //           begin  end      
            {
                 
                if($i<$begin || $i>$end || ($else>0 && $i>$else && $i<$end))
                {
                      $tmp=$list[$i];
                      if($i==$begin) $tmp=preg_replace("/<!--if\((.*?)\)-->/s","",$tmp);
                      if($i==$end) $tmp=preg_replace("/<!--endif-->/s","",$tmp);
                      if($i==$else) $tmp=preg_replace("/<!--else-->/s","",$tmp);
                       if(trim($tmp)!="")
                       $ret.=chr(13).$tmp;
                }
            }
            
        }
        return $ret;
        
    }
    function execFunc($cnt)
    {
       
        $list=explode(chr(13),$cnt);
        
         
        if(count($list)<2) return false;//   2             
           
        $copy=array_reverse($list);
        $firstIF="";
        $elseLinenum=0;
        $hasEndif=false;
        $beginLinenum=0;
        $endLinenum=0;
        $i=0;
      
        foreach($list as $line)
        {
            if(preg_match("/<!--if\((.*?)\)-->/s",$line,$match) && $firstIF=="")//        if   
            {
                if($match && count($match)>1)
                {
                    $firstIF=trim($match[1]);
                    $beginLinenum=$i;
                }
            }
            if(preg_match("/<!--else-->/s",$line,$match) && $elseLinenum==0)//        else   
            {
                    $elseLinenum=$i;   
            }
            if($firstIF!="" && $elseLinenum>0) break;//      
            $i++;
        }
        if(trim($firstIF)=="") return false;//               
        $i=count($list)-1;
         foreach($copy as $line)
        {
             if(preg_match("/<!--endif-->/s",$line))//         if   
            {
                $hasEndif=true;
                $endLinenum=$i;
                break;
            }
            $i--;
        }
        
        if(!$hasEndif) return false; //          if  
        try
        {
           eval("\$ifvalue=(".$firstIF.");");
           if(isset($ifvalue))
           {
              if($ifvalue)//   true         
              {
                return $this->getLineCnt($beginLinenum,$endLinenum,$elseLinenum,$list,true);
              }
              else
                return $this->getLineCnt($beginLinenum,$endLinenum,$elseLinenum,$list,false);
           }
           else return "";//               
        }
        catch(Exception $ex)
        {
            return "";//                  
        }
      
        
    }
    function getIfList($cnt)
    {
        preg_match_all($this->tag,$cnt,$match,PREG_SET_ORDER);
         
         if($match && count($match)>0)
           {
            foreach($match as $m)
            {
                $go=true;
                $i=0;
                $getresult=$m[1];
                while($go)
                {
                    if($i>=20) //    20         
                    {
                        $go=false;break;
                    }
                    $tmp=$this->execFunc($getresult);
                    if($tmp===false)
                    {
                        $go=false;break;
                    }
                    $getresult=$tmp;
               
                    $i++;
                    
                }
                $cnt=preg_replace($this->tag,$getresult,$cnt,1);
            }
           }
      
        return $cnt;
       
    }
    function clearTag($cnt)//                 
    {
         $cnt=preg_replace("/<!--if\((.*?)\)-->/s","",$cnt);
        $cnt=preg_replace("/<!--endif-->/s","",$cnt);
        return $cnt;
    }
    function parse($cnt)//                         
    {
      
       $list=explode(chr(13),$cnt);
      
       $cnt=$this->getIfList($cnt);
       
        $cnt=$this->clearTag($cnt);
        return $cnt;
     
    }
  }
?>

ここでプラグインはclassファイルであり、クラス名はplugin_に従う必要があることに注意してください.クラス名_このような形式で、テンプレートに変換すると
....//ここは大文字と小文字が敏感です.プラグインはparseメソッドを持って解析後の内容を返す必要があります.
個人的なメリット:
1、柔軟で、拡張性が良い
2、コアの修正に支障がない.
3、外国人のような書類やコードが山積みになっていないスタイルは、外国人が書いたものは牛だが、中国人のソフトウェアを開発しているのであれば、中国人のものを使うのが適当だ.
 
欠点は言わないで、バグはきっとあって、性能は外国人の良いことがなくて、達人はごみだと思って、smartyと同じものではありませんて、噴き出すな
興味のある良い友达がもっと良い文法のプラグインを提供することを歓迎します
以下に注意点を示します.
1、上記のプログラムを使用するにはphh 5を使用し、mb_を開く必要があります.stringはevalをサポートする必要があります
2、メインプログラムはutf-8なので、utf 8符号化を使用しなければなりません.理論的にはテンプレートがgb 2312でも大丈夫ですが、テストしていません.
3、プロジェクトがまだ交付されていないため、このテンプレートプログラムはまだ絶えず改善し、修正している.現在はv 0である.1,そのためテンプレートの主な解析プログラムは私が圧縮して、後で注釈のバージョンの純粋な元のファイルを放します.
4.このテンプレートは特に第一線の開発者に適用されます(忙しくて時間のない開発者)、初心者にはお勧めしません(初心者はまず基礎をマスターしたほうがいい)、上級者にはお勧めしません(上級者はゴミだと思っているかもしれません)
テストプログラムは私のネットディスクに入れました.http://url.cn/7dKBks(qqの微云).
ダウンロードできない場合はメールボックスを残してください