自己的 php 模板引擎的 if 标签


If-tags for own php template engine

我正在尝试在PHP中制作自己的模板引擎。

为此,我

创建了一个类,该类解析模板文件并查找我事先设置的分隔符(f.e. {})。它适用于变奏曲和包括文件。

现在,我想添加一些功能,例如 if 标签,我可以在其中转发一个布尔变量,它决定是否显示 if 标签内的模板部分。我在这个小问题上工作了两天多,但我就是无法解决它。

编辑:Sry似乎我没有提供足够的信息。这是我的模板引擎:

class EZmanly {
private $templateDir = 'templates/';
private $leftDelimiter = '{$';
private $rightDelimiter = '}';
private $leftDelimiterFunc = '{';
private $rightDelimiterFunc = '}';
private $leftDelimiterCom = ''{'*';
private $rightDelimiterCom = ''*'}';
private $leftDelimiterIf = ''{if';
private $rightDelimiterIf = ''}';
private $elseDemlimiter = ''{else'}';
private $endDelimitirIf = ''{end if'}';
/* Der Pfad der Datei*/
private $templateFile = '';
/* Der Dateiname */
private $templateName = '';
/* Der Inhalt des Tempaltes in der Datei */
private $template = '';
public function __construct(/*$tplDir*/) {
    #if( !empty($tplDir) ) {
        $this->templateDir = 'templates/'/*$tplDir*/;
    #}
}
public function loadTpl($file) {
    $this->templateName = $file.".tpl";
    $this->templateFile = $this->templateDir.$file.".tpl";
    if( !empty($this->templateFile) ) {
        if( file_exists($this->templateFile) ) {
            $this->template = file_get_contents($this->templateFile);
        }
        else {
            return fase;
        }
    }
    else {
        return false;
    }
    $this->parseFunctions();
}
public function assign($replace, $replacement) {
    $this->template = str_replace($this->leftDelimiter.$replace.$this->rightDelimiter, $replacement, $this->template);
}
public function parseFunctions() {
    while(preg_match( "/".$this->leftDelimiterFunc."include file='"(.*)'.(.*)'"".$this->rightDelimiterFunc."/", $this->template)) {
        $this->template = preg_replace("/" .$this->leftDelimiterFunc."include file='"(.*)'.(.*)'"".$this->rightDelimiterFunc."/isUe", "file_get_contents('$this->templateDir.'''1'.'.'.'''2')", $this->template);
    }
    while(preg_match( "/".$this->leftDelimiterFunc."include file='"(.*)'.(.*)'"".$this->rightDelimiterFunc."/", $this->template)) {
        $this->template = preg_replace("/" .$this->leftDelimiterFunc."include file='"(.*)'.(.*)'"".$this->rightDelimiterFunc."/isUe", "file_get_contents('$this->templateDir.'''1'.'.'.'''2')", $this->template);
    }
    while(preg_match_all("/'{IF(.*?)'}['s]*?(.*)['s]*?('{ELSE'}['s]*?(.*?)['s]*?)'{ENDIF'}/i",$this->template, $matches, PREG_PATTERN_ORDER)) {
        for($i=0; $i < count($matches[4][$i]); $i++) {
            $condition = $matches[1][$i];
            $trueval = $matches[2][$i];
            $falseval = isset($matches[4][$i]) ? $matches[4][$i] : false;
            $result = eval("return(".$condition.");");
            if($result===true) {
                $this->template = str_replace($matches[0][$i], $trueval, $this->template);
            }
            else {
                $this->template = str_replace($matches[0][$i], $falseval, $this->template);
            }
        }
    }
    while(preg_match_all("/'{IF(.*?)'}['s]*?(.*)['s]*?'{ENDIF'}/i", $this->template, $matches, PREG_PATTERN_ORDER)) {
        for($i=0; $i < count($matches[0]); $i++) {
            $condition = $matches[1][$i];
            $trueval = $matches[2][$i];
            $result = eval("return(".$condition.");");
            if($result==true) {
                $this->template = str_replace($matches[0][$i], $trueval, $this->template);
            }
            else {
                $this->template = str_replace($matches[0][$i], "", $this->template);
            }
        }
    }
    # TODO: if functions in the templates for flags (true/false OR 1/0)
    $this->template = preg_replace("/".$this->leftDelimiterCom."(.*)".$this->rightDelimiterCom."/", "", $this->template);
}
public function display() {
    echo $this->template;
}

}

下面是一个关于 php 的示例:

$flgEmpty = true;
$flgMail = true;
$flgUrl = false;
$newManly = new EZmanly();
$newManly->loadTpl('advertPost');
$newManly->assign('title', 'Anzeige aufgeben');
$newManly->assign('filepath', 'http://localhost/webdev');
$newManly->assign('flgMail', $flgMail);
$newManly->display();

这里是 tpl:

{IF $flgMail==true}
    <p>Dies ist ein Test</p>
{ENDIF}

但它不起作用:(如果我只是显示变量或使用包含文件工作

试试这个。

语法:

  • {variable_name}
    变量名是 PHP 变量名。例如 {var1} 对应于 PHP 脚本中的 $var 1
  • {IF?condition} ... {ELSE} ... {ENDIF}
    condition 必须是有效的 PHP 条件术语。它在运行时进行评估。因此,所有 PHP 构造和引用 ($-变量) 都是有效的,在脚本本身中也是有效的。
  • {IF?condition} ... {ENDIF}

注意:

  • 在运行时使用 eval() 命令评估条件。这可能是一个安全问题。要小心,并确保不要从您不知道或不能绝对信任的来源导入模板。
  • IF-构造可能不是嵌套的。

<?php
    $a = 22;
    $b = 33;
    $var1 = 99999;
    $var2 = 'Variable2';
    $template = 'Variable 1 = {var1}, variable 2 = {var2}
{IF?$a == 22}A = 22{ELSE}A != 22{ENDIF}<br />
<div>{IF?$a >= 22}
A = 22
{ELSE}
A != 22
{ENDIF}</div>
{IF?$b<0}B > 0{ENDIF}';
    echo '<h3>Template before</h3><pre>'.htmlentities($template).'</pre>';
    // IF - ELSE - ENDIF
    preg_match_all('/'{IF'?(.*?)'}['s]*?(.*)['s]*?('{ELSE'}['s]*?(.*?)['s]*?)'{ENDIF'}/i', $template, $regs, PREG_PATTERN_ORDER);
    for ($i = 0; $i < count($regs[0]); $i++) {
        $condition = $regs[1][$i];
        $trueval   = $regs[2][$i];
        $falseval  = (isset($regs[4][$i])) ? $regs[4][$i] : false;
        $res = eval('return ('.$condition.');');
        if ($res===true) {
            $template = str_replace($regs[0][$i],$trueval,$template);
        } else {
            $template = str_replace($regs[0][$i],$falseval,$template);
        }
    }
    // IF - ENDIF
    preg_match_all('/'{IF'?(.*?)'}['s]*?(.*)['s]*?{ENDIF'}/i', $template, $regs, PREG_PATTERN_ORDER);
    for ($i = 0; $i < count($regs[0]); $i++) {
        $condition = $regs[1][$i];
        $trueval   = $regs[2][$i];
        $res = eval('return ('.$condition.');');
        if ($res===true) {
            $template = str_replace($regs[0][$i],$trueval,$template);
        } else {
            $template = str_replace($regs[0][$i],'',$template);
        }
    }
    // Variables
    preg_match_all('/'{(.*?)'}/i', $template, $regs, PREG_SET_ORDER);
    for ($i = 0; $i < count($regs[0]); $i++) {
        $varname = $regs[$i][1];
        if (isset($$varname)) {
            $value = $$varname;
            $template = str_replace($regs[$i][0],$$varname,$template);
        } else {
            $template = str_replace($regs[$i][0],'',$template);
        }
    }
    echo '<h3>Template after</h3><pre>'.htmlentities($template).'</pre>';
?>

输出:

之前的模板

Variable 1 = {var1}, variable 2 = {var2}
{IF?$a == 22}A = 22{ELSE}A != 22{ENDIF}<br />
<div>{IF?$a >= 22}
A = 22
{ELSE}
A != 22
{ENDIF}</div>
{IF?$b<0}B > 0{ENDIF}

之后的模板

Variable 1 = 99999, variable 2 = Variable2
A = 22<br />
<div>    A = 22
</div>

而且,顺便说一句,还有更多拥抱和更复杂的模板引擎可用。在我看来,最好的之一,请参阅 http://twig.sensiolabs.org/。