如何模拟模板类
我正在为自己的项目编写基本模板类。基本用法是这样的:如何模拟模板类
$template = new Template('template_file.php');
$template->assignVariable('pageTitle', 'Home page');
$template->render();
'template_file.php' 的内容:
<?php print $pageTitle; ?>
这一步什么模板类确实步:在私人阵列
- 房屋变量当调用assignVariable方法时
- 当调用render方法时,提取存储的变量,包含模板文件
ob_start()
和ob_end_clean()
块。将输出存储在变量ob_get_contents()
中,然后打印存储的输出。
我知道这是一个非常简单的模板类,但按预期工作。问题是我应该将包含模板文件委托给另一个类?我在为这堂课写单元测试时遇到了这个问题。我认为应该封装文件系统交互。你怎么看?如果你认为它不应该,我怎么可以在我的测试中包含一个文件?
也许我只是通过模板文件的内容到类像这样:
$templateContent = file_get_contents('template_file.php');
$template = new Template($templateContent);
...
编辑:我决定来封装模板类的输入过程,写出更好的单元测试的缘故和封装。但正如johannes指出的那样,我需要使用eval()
来达到这个目的,这看起来并不正确。 Johannes向我指出了在单元测试中嘲笑包含的流式封装的方向。但是这给我一个新想法。这是我要做的事情;我将继续在我的模板类中使用include()
,但这次使用流封装。初始化时,我会将协议处理程序传递给我的模板类。通过这种方式,我可以创建自己的流封装以从数据库获取模板数据或使用局部变量。以下是示例:
$template = new Template('file://template_file.php');
stream_wrapper_register('database', 'My_Database_Stream');
$template = new Template('database://templates/3'); // templates table, row id 3
stream_wrapper_register('var', 'My_Var_Stream');
$myTemplate = '<?php print "Hello world!"; ?>';
$template = new Template('var://myTemplate');
我已经为本地变量实现了自定义流包装。那就是:
class My_Var
{
protected $position;
protected $variable;
function stream_open($path, $mode, $options, &$openedPath) {
$url = parse_url($path);
global $$url['host'];
$this->variable = $$url['host'];
$this->position = 0;
return true;
}
public function stream_read($count) {
$ret = substr($this->variable, $this->position, $count);
$this->position = strlen($ret);
return $ret;
}
public function stream_eof() {
return $this->position >= strlen($this->variable);
}
}
stream_wrapper_register('var', 'My_Var');
$myvar = '<?php print "mert"; ?>';
include 'var://myvar';
exit;
使用的file_get_contents传递()的内容和这样的,你必须使用eval()执行这是坏的多种方式。其中最重要的一点是操作码缓存不能缓存文件。做一个include('template_file.php');让我们APC或其他人缓存编译的脚本。无论EVAL VS使用包括,回答你的问题的万恶之
,我不得不同意,并使用一个单独的类来封装解决方案的I/O方面。
虽然这似乎有点小题大做(因为这将是在大多数情况下),这可能是唯一明智的方式提供控制/依赖注入的,你是以后的隔离。
我一直很喜欢这个家伙的办法:
http://www.massassi.com/php/articles/template_engines/
此方法采用的是PHP已经开始为模板引擎的事实。 (作者还指出,在PHP中编写一个臃肿的模板引擎是愚蠢的,因为它实际上本身就是一个模板引擎。)它可能不会直接回答你的问题,但也许它可以帮助你。
是的,但是当使用include函数时,我需要一个虚拟模板文件在我的测试文件夹中。我也不应该只测试模板类吗?另外我将如何模拟包含功能? – matte 2010-01-17 13:19:01
您可以使用自定义流包装器或数据提供程序来发送模拟数据。 http://php.net/stream_wrapper_register http://php.net/manual/en/wrappers.data.php – johannes 2010-01-17 13:44:36
嗨Johannes,谢谢!你为我启发了一个新想法。我编辑了这个问题,并添加了我提出的解决方案。 – matte 2010-01-17 18:40:47