Php 在DB行模板化的循环中包含()的替代方法?

Php 在DB行模板化的循环中包含()的替代方法?,php,Php,我正在用PHP编写一个数据提供程序类,以帮助我加快多行SQL查询结果的呈现速度。基本上,该类有一系列与SQL相关的属性和方法来帮助分页、排序和最终呈现数据。对于后者,我希望能够轻松地对行进行模板化,因此我编写了一个名为render()的方法,该方法可以从视图文件(在MVC模型中)中使用行模板文件作为参数进行调用。它看起来像这样: public function render($row_template_file) { if($result = mysql_query($this->

我正在用PHP编写一个数据提供程序类,以帮助我加快多行SQL查询结果的呈现速度。基本上,该类有一系列与SQL相关的属性和方法来帮助分页、排序和最终呈现数据。对于后者,我希望能够轻松地对行进行模板化,因此我编写了一个名为render()的方法,该方法可以从视图文件(在MVC模型中)中使用行模板文件作为参数进行调用。它看起来像这样:

public function render($row_template_file) {
    if($result = mysql_query($this->query)) {
        while($row = mysql_fetch_array($result)) {
            include $row_template_file;
        }
    }
}
实际的方法比这更复杂(它检查模板文件是否存在,使用数据抽象类而不是mysql_*函数等),但您已经了解了总体思路。行模板文件基本上是直接进入输出的HTML,即:

<div class="row">
    <div class="foo"><?php echo $row['foo']; ?></div>
    <div class="bar"><?php echo $row['bar']; ?></div>
</div>


这种方法工作得很好,唯一的问题是循环中的include()在性能方面不是一个好主意,特别是在渲染大量行时。在保持对行进行模板化的能力的同时,有什么东西可以替换它吗?这里几乎没有类似的问题,但所有建议的解决方案都涉及到将逻辑与表示相结合,这正是我想要避免的。我想在第一次迭代中创建一个匿名函数,然后在所有后续迭代中调用它,但可能我想得太多了,或者在这里重新发明了轮子。有什么想法吗?

这感觉像是一个太简单的解决方案,也许我不明白问题出在哪里,但是使用PHP函数怎么样

function outputRow($row) {
    echo '<div class="row">';
    echo '<div class="foo">' . $row['foo'] . '</div>';
    echo '<div class="bar">' . $row['bar'] . '</div>';
    echo '</div>';
}
函数输出流($row){
回声';
回显“.$row['foo']”;
回显'.$row['bar'].';
回声';
}
您可以调用
outputRow($row)

而不是include,或者改用php的printf()/函数

因此,模板文件将包含如下代码:

<div class="row">
    <div class="foo">%s</div>
    <div class="bar">%s</div>
</div>
在循环中,您只需将变量放入模板中:

printf( $tmpl, $row['foo'], $row['bar']);
有关“参数交换”(在模板中使用编号位置的方法)的信息,请参见上面链接中的示例3和示例4,以避免担心不同模板中参数的不同顺序


希望对您有用。

将模板创建为带有占位符的字符串,并将值替换到其中。将其传递给
render()
方法

然后,您只需决定如何最好地获取字符串—通过
文件获取内容(我同意这样做),或者简单地将其硬编码到某个“模板”类中,从中提取一个接口—并将其传递。

建议的
printf()
/
sprintf()
解决方案非常简洁,但不允许在模板中包含特定于表示的逻辑,例如:

<div class="gender">
    <?php if($row['gender'] == 'f') : ?>
    <img src="female_icon.gif" />
    <?php else : ?>
    <img src="male_icon.gif" />
    <?php endif; ?>
</div>

我知道,我不应该写模板是“基本上是HTML”:-)

我一直在玩我在问题中提到的匿名函数解决方案,尽管它看起来不太漂亮,但它工作起来比多个include快得多,因此我添加了以下内容作为可能的答案之一:

public function render($row_template_file) {
    if($result = mysql_query($this->query)) {
        $render_row = create_function('$row', '?>'.file_get_contents($row_template_file).'<?php ');
        while($row = mysql_fetch_array($result)) {
            $render_row($row);
        }
    }
}
公共函数渲染($row\u模板\u文件){
如果($result=mysql\u query($this->query)){

$render_row=create_函数('$row','?>'.file_get_contents($row_template_file)。“可以尝试使用eval函数。php.net上的此注释可能会帮助您:

您可以在模板文件中循环?正如其他人教给我的:eval通常会产生比它解决的问题更多的问题。此外,您建议他应该如何处理它?应该如何使用它?“尝试使用eval函数”没有说太多。从技术上讲,这是一个正确的答案。如果你包括,你可以评估,在PHP中两者之间没有太大的区别。实际上,在内部,它是相同的“函数”。仅供参考:一个简单的函数就可以完成这项工作。性能无关,它将被缓存,否则请参阅-这是PHP中
include
的字符串变体。
public function render($row_template_file) {
    if($result = mysql_query($this->query)) {
        $render_row = create_function('$row', '?>'.file_get_contents($row_template_file).'<?php ');
        while($row = mysql_fetch_array($result)) {
            $render_row($row);
        }
    }
}