这是我的模板类的精简版,专注于在限制范围内执行文件$env
:
class Template {
/**
* Defines new scope for template execution using $evn variables and
* executes the template script in an output buffer.
*
* @param string $file File name (excluding file extension) relavite to the template directory.
* @param array $env Variables populated in the template scope.
* @return string Template output.
*/
public function render ($file, array $env = []) {
$env['template'] = $this;
return self::render($file, $env);
}
/**
* The additional static render method is used to prevent
* exposing $this and other Template properties to the template scope.
* Two variables (file and env) are captured using func_get_arg for
* the same reason of not exposing them to the template scope.
*
* @return string Template output.
*/
static private function render () {
extract(func_get_arg(1), \EXTR_REFS);
ob_start();
require func_get_arg(0);
return ob_get_clean();
}
private function test () { /* I do not want $template to have access to this */ }
}
在模板本身中,我想公开用于执行脚本的Template类的实例。这可以做到,例如
$template = new Template();
$template->render('foo', ['template' => $template]);
但是,这需要在构造Template对象时显式捕获并传递$template
实例。
但是,如果我在render
方法中执行此操作:
$env['template'] = $this;
然后$template
可以访问私有模板方法,例如test
。
有没有办法从只能访问公共方法的$this
对象实例派生出来?
答案 0 :(得分:0)
您可以创建一个完全独立的渲染上下文;这是它如何改变Template::render()
函数:
public function render ($file, array $env = []) {
return RenderContext::run($file, $this, $env);
}
这是shell类:
class RenderContext
{
static function run($file, $template, $env)
{
extract($env);
ob_start();
require $file;
return ob_get_clean();
}
}