从数据库/字符串中获取模板
我将模板存储为文件,并且希望有机会将它们存储在 MySql 数据库中。
我的模板系统
//function of Template class, where $file is a path to a file
function fetch() {
ob_start();
if (is_array($this->vars)) extract($this->vars);
include($file);
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
function set($name, $value) {
$this->vars[$name] = is_object($value) ? $value->fetch() : $value;
}
用法:
$tpl = & new Template('path/to/template');
$tpl->set('titel', $titel);
模板示例:
<h1><?=titel?></h1>
<p>Lorem ipsum...</p>
我的方法
- 从数据库中选择模板作为
- 我的 字符串得到就像 $tpl = "<h1><?=$titel? >...";
- 现在我想将它传递给模板系统,所以我扩展了我的构造函数和 fetch 函数:
function fetch() {
if (is_array($this->vars)) extract($this->vars);
ob_start();
if(is_file($file)){
include($file);
}else{
//first idea: eval ($file);
//second idea: print $file;
}
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
'eval' 给了我一个解析异常,因为它将整个字符串解释为 php,而不仅仅是 php 部分。 “print”真的很奇怪:它不打印 之间的五线谱,但我可以在页面的源代码中看到它。 php 函数被忽略。
那么我应该尝试什么呢?
I store my templates as files, and would like to have the opportunity to store them also in a MySql db.
My template System
//function of Template class, where $file is a path to a file
function fetch() {
ob_start();
if (is_array($this->vars)) extract($this->vars);
include($file);
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
function set($name, $value) {
$this->vars[$name] = is_object($value) ? $value->fetch() : $value;
}
usage:
$tpl = & new Template('path/to/template');
$tpl->set('titel', $titel);
Template example:
<h1><?=titel?></h1>
<p>Lorem ipsum...</p>
My approach
- Selecting the the template from the database as a String
- what i got is like $tpl = "<h1><?=$titel? >...";
- Now I would like to pass it to the template system, so I extended my constructor and the fetch function:
function fetch() {
if (is_array($this->vars)) extract($this->vars);
ob_start();
if(is_file($file)){
include($file);
}else{
//first idea: eval ($file);
//second idea: print $file;
}
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
'eval' gives me an Parsing exception, because it interprets the whole String as php, not just the php part.
'print' is really strange: It doesn't print the staff between , but I can see it in the source code of the page. php function are beeing ignored.
So what should I try instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许不是最好的解决方案,但它很简单,应该可以工作:
如果将 Timestamp 列添加到模板表中,则可以使用文件系统作为缓存。只需比较文件和数据库的时间戳即可决定是否足以重用该文件。
Maybe not the best solution, but its simple and it should work:
If you add a Timestamp column to your template table, you can use the filesystem as a cache. Just compare the timestamps of the file and the database to decide if its sufficient to reuse the file.
如果您在 eval 前面添加
'?>'
,它应该可以工作。但你应该知道 eval() 是一个相当慢的事情。其生成的操作码无法缓存在 APC(或类似的)中。您应该找到一种方法将模板缓存在磁盘上。首先,您不必每次需要时都从数据库中提取它们。您还可以利用常规操作码缓存(由 APC 透明地完成)。
每当我看到一些半生不熟的本土“模板引擎”时,我都会问自己为什么作者不依赖现有的众多模板引擎中的一个?他们中的大多数已经解决了您可能遇到的大部分问题。 Smarty(以及 Twig、phpTAL 等)使您可以从任何您喜欢的地方提取模板源(同时尝试以保持最佳性能)。您有什么特殊原因不使用其中之一吗?
If you prepend
'?>'
to your eval, it should work.But you should know that eval() is a rather slow thing. Its resulting op-code cannot be cached in APC (or similar). You should find a way to cache your templates on disk. For one you wouldn't have to pull them from the database every time they're needed. And you could make use of regular op-code caching (done transparently by APC).
Every time I see some half-baked home-grown "template engine", I ask myself why the author did not rely on one of the many existing template engines out there? Most of them have already solved most of the problems you could possible have. Smarty (and Twig, phpTAL, …) make it a real charme to pull template sources from wherever you like (while trying to maintain optimal performance). Do you have any special reasons for not using one of these?
我会做与 tweber 几乎相同的事情,除了我更喜欢依赖本地文件时间戳而不是数据库。
类似这样:每个文件的 TTL(过期时间)为 60 秒。真正的原因是为了避免对数据库造成太大影响/通常是不必要的,您很快就会意识到文件系统访问比网络和 mysql 快得多,尤其是当 mysql 实例运行在远程服务器上时。
干杯,希望有用
I would do pretty much the same thing as tweber except I would prefer depending on the local file timestamps rather than the DB.
Something like this: Each file has a TTL ( expiration time ) of lets say 60 seconds. The real reason is to avoid hitting the DB too hard/often needlessly, you'll quickly realize just how much faster filesystem access is compared to network and mysql especially if the mysql instance is running on a remote server.
Cheers, hope thats useful