PHP中的超轻模板系统,不允许在模板内部使用php代码或使用eval

Ale*_*lex 14 php parsing templates template-engine

我正在寻找一个非常基本的PHP模板系统.现在我正在使用:

/**
 * Renders a single line. Looks for {{ var }}
 *
 * @param string $string
 * @param array $parameters
 *
 * @return string
 */
function renderString($string, array $parameters)
{
    $replacer = function ($match) use ($parameters)
    {
        return isset($parameters[$match[1]]) ? $parameters[$match[1]] : $match[0];
    };

    return preg_replace_callback('/{{\s*(.+?)\s*}}/', $replacer, $string);
}
Run Code Online (Sandbox Code Playgroud)

(从这里:PHP - 极轻的模板系统)

但我只能分配和显示变量.我还需要一种方法来使用IF和循环数组等条件.

我找到了Rain TPL - http://www.raintpl.com/Quick-Start/#if - 这与我正在寻找的非常接近,但有些事我不喜欢它:

  • 它允许正在编写模板的家伙运行PHP函数(在IF条件内).
  • 它写缓存和PHP文件,我不想要

那么,有没有类似的东西,但更"基本",严格,更安全?

Pek*_*ica 15

Twig可能适合你.

它可以执行条件,并具有不受信任的代码的沙箱模式.

它进行编译和缓存,但似乎可以关闭.


Dav*_*cea 7

PHP 还有一个Mustache端口.PHP端口在这里.语法类似于您正在执行的操作,并支持简单的IF和FOREACH类型循环.

并且,它没有eval.


sat*_*n77 4

根据您的要求,我猜测您希望网站用户编写一些基本的 php 脚本。您可能找不到可以做到这一点的免费模板引擎。

我认为如果您根据需要更改现有的模板引擎,这对您来说会更好。

您可以更改 Rain TPL 以禁用某些您不需要的功能。例如你可以做...

  1. 禁用 IF 语句中的函数使用
    :找到elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){

    B. 替换$this->function_check( $tag );为新方法,例如$this->ifcondition_function_check( $tag );

    c. 创建将禁用 IF 语句中的所有函数的新方法。

    private function ifcondition_function_check($code)
    {
        $preg = '/[a-zA-z0-9]+\((.*?)\)/';
        if (preg_match( $preg, $code, $match ) ){
            // find the line of the error
            $line = 0;
            $rows=explode("\n",$this->tpl['source']);
            while( !strpos($rows[$line],$code) )
                    $line++;
    
            // draw the error line
            $error = str_replace( array('<','>'), array( '&lt;','&gt;' ), array($code,$rows[$line]) );
            $error = str_replace( $code, "<font color=red>$code</font>", $rows[$line] );
    
            // debug the error and stop the execution of the script
            die( "<div>RainTPL Sandbox Error in template <b>{$this->tpl['tpl_filename']}</b> at line $line : <i>$error</i></b>" );
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    d. 现在功能被禁用。

    1. 删除缓存文件。(Rain TPL中的缓存文件是一个PHP文件,其中模板标签被PHP代码替换
      )转到方法draw()
      b。找到unset( $this->tpl );
      c. 在此行之前删除已编译的(缓存)文件@unlink($this->tpl['compiled_filename']);
      d. 现在缓存文件只是执行 PHP 代码的临时文件。

希望这可以帮助