如何在模板中提供变量?

use*_*029 7 php templates

我有以下课程:

abstract class TheView
{
  public $template = NULL;
  public $variables = array();

  public function set($name, $value)
  {
    $this->variables[$name] = $value;
  }
  public function display()
  {
    include($this->template);
  }
}
Run Code Online (Sandbox Code Playgroud)

模板文件是一个简单的PHP文件:

<?php
echo $Message;
?>
Run Code Online (Sandbox Code Playgroud)

如何使TheView::$variables模板中的所有变量都可用(每个项的键应该是变量的名称).

我已经尝试添加所有变量,$GLOBALS但这不起作用(我认为这是一个坏主意).

Dan*_*ugg 5

我总是这样做:

public function render($path, Array $data = array()){
    return call_user_func(function() use($data){
        extract($data, EXTR_SKIP);
        ob_start();
        include func_get_arg(0);
        return ob_get_clean();
    }, $path);
}
Run Code Online (Sandbox Code Playgroud)

注意匿名函数和func_get_arg()调用; 我用它们来防止$this和其他变量"污染"被传递到模板中.您也可以$data在包含之前取消设置.

如果你想$this使用,虽然,只是extract()include()直接的方法.

所以你可以:

$data = array('message' => 'hello world');
$html = $view->render('path/to/view.php', $data);
Run Code Online (Sandbox Code Playgroud)

path/to/view.php:

<html>
    <head></head>
    <body>
        <p><?php echo $message; ?></p>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

如果希望传递View对象,而不是从render()方法的范围传递,请按如下所示进行更改:

public function render($path, Array $data = array()){
    return call_user_func(function($view) use($data){
        extract($data, EXTR_SKIP);
        ob_start();
        include func_get_arg(1);
        return ob_get_clean();
    }, $this, $path);
}
Run Code Online (Sandbox Code Playgroud)

$view将是View对象的实例.它将在模板中提供,但仅公开成员,因为它来自render()方法范围之外(保留私有/受保护成员的封装)