我有以下课程:
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但这不起作用(我认为这是一个坏主意).
我总是这样做:
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()方法范围之外(保留私有/受保护成员的封装)