在数据库行模板的循环中,include()的替代方法是什么?

时间:2012-04-18 11:34:56

标签: php

我正在用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()在性能方面不是一个好主意,特别是在渲染大量行时。有没有什么我可以替换它同时保持模板行的能力?这里几乎没有类似的问题,但所有建议的解决方案都涉及将逻辑与表示混合,这是我想要避免的。我正在考虑在第一次迭代期间创建一个匿名函数,然后在所有后续迭代中调用它,但也许我正在过度思考它或重新发明轮子。有什么想法吗?

5 个答案:

答案 0 :(得分:1)

或许使用php的printf()/ sprintf()函数代替?

因此,您的模板文件将包含以下代码:

<div class="row">
    <div class="foo">%s</div>
    <div class="bar">%s</div>
</div>

您只需将一次加载到变量中,然后再循环:

$tmpl = file_get_contents( $row_template_file);

在循环内部,您只需将变量放入模板中:

printf( $tmpl, $row['foo'], $row['bar']);

请参阅上面链接中的示例#3和#4,了解“参数交换” - 在模板中使用编号位置的方法 - 不用担心不同模板中不同的参数顺序。

希望对你有用。

答案 1 :(得分:1)

建议的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”: - )

我一直在玩我在问题中提到的匿名函数解决方案,即使它看起来不太漂亮,但它的工作速度明显快于多个包含,所以我将其添加为可能的答案之一:

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);
        }
    }
}

答案 2 :(得分:0)

这几乎感觉就像一个太简单的解决方案,也许我只是没有得到大问题,但是使用PHP函数怎么样?

function outputRow($row) {
    echo '<div class="row">';
    echo '<div class="foo">' . $row['foo'] . '</div>';
    echo '<div class="bar">' . $row['bar'] . '</div>';
    echo '</div>';
}

而不是包含,请致电outputRow($row)

答案 3 :(得分:0)

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

然后,您只需要决定如何获得字符串的最佳方式 - 通过file_get_contents(我会这样做)或者只是将其硬编码到某个“模板”类中,从中提取一个接口 - 然后传递它。

答案 4 :(得分:0)

可以尝试使用eval功能。这个关于php.net的评论可能对您有所帮助: http://www.php.net/manual/ru/function.eval.php#108091