我在应用程序的不同位置重复相同的数据库查询和相同的相关 HTML 的情况。
那么干燥这个的通常/最佳实践方法是什么?
包含非常适合这种情况,但是如果我采用它作为 DRYing 的方法,我最终会不会因为包含太多而减慢应用程序的速度?
我通常使用静态方法制作实用程序类来处理重复块的回显。例如看看我的课程social plugins
您可以尝试拥有一个用于数据库查询的中央文件,并且只在您需要的地方包含它。同样对于 html 片段。
您可能会发现 MVC 模式在这种情况下很有用(请参阅http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)
如果你真的想自己动手——至少是部分地,而不是使用一个完整的框架,你可以混合一些成熟的库并将逻辑与模板分离。
例如,我所做的是使用 Smarty - 一个完善的模板引擎 - 并扩展它的基类来执行廉价查询。
通常你会以这种方式使用 Smarty,将你的逻辑与模板分开:
$Smarty = new Smarty();
$Smarty->assign( 'myvariable', array( ... ) ); // usually a database query return
$Smarty->display( 'template.tpl' );
所以我已经扩展它来做查询:
class QSmarty extends Smarty {
function query( $sql ) {
$args = func_get_args();
$sql = array_shift( $args );
foreach( $args as $k => $v ) $args[$k] = mysql_escape_string( $v );
$safe_sql = vsprintf( $sql, $args );
// assuming this will be manageable (paginated or reasonably sized)
$ret = array();
$t = mysql_query( $safe_sql );
while( $r = mysql_fetch_assoc( $t ) ) {
$ret[] = $r;
}
return( $ret );
}
}
因此,您可以一遍又一遍地懒惰地使用它:
$Smarty = new QSmarty();
$Smarty->assign( 'users', $Smarty->query(
"select * from users where group=%s",
$_GET['group'] // gets sanitized automatically
));
$Smarty->display( 'users.tpl' );
模板文件 users.tpl 可能如下所示:
<ul>
{foreach $users as $user}
<li class="{cycle values='odd,even'} {if $user@last}last_user{/if}">
{$users.id}: {$users.username|lower}
</li>
{/foreach}
</ul>
由于 Smarty 支持模板继承、自定义模板函数和一系列其他功能,因此您可以将可重用的 HTML 分段到它们自己的单独文件中,并在其他模板中使用诸如 {include users.tpl} 之类的模板标记,如您所见分配和重新分配变量合身。非常干燥。
说实话,是的,这几乎是 Smarty 的推销,展示或强调了它的一些功能。除了查询之外,Smarty 在这里完成了所有繁重的工作。试一试,或者其他模板引擎。