【问题标题】:advanced php templating using str_replace arrays使用 str_replace 数组的高级 php 模板
【发布时间】:2012-11-20 20:17:28
【问题描述】:

我创建了一些模板系统来帮助我以可换肤的方式输出数据库项目。它的工作原理是这样的:

$tpl = "<html>
<body>
<div><span class="item">Favourite food:</span><span class="content">{item1}</span></div>
<div><span class="item">Hobby:</span><span class="content">{item2}</span></div>
<div><span class="item">Allergies:</span><span class="content">{item3}</span></div>
// up to 500 more lines like this
</body>
</html>";

$output = str_replace( 
array('{item1}','{item2}','{item3}') ) , 
array($database['item1'],$database['item2'],$database['item3']) , 
$tpl );

echo $output;

现在我的问题是:并非每个数据库项目都必然有内容 - 所以,目前我得到这样的输出

最喜欢的食物:香蕉 爱好:{item2} 过敏:苹果

有什么方法可以使用这种系统并省略没有数据库条目的行?输出应该是这样的:

最喜欢的食物:香蕉 过敏:苹果

我怎样才能做到这一点?

更新:描述文本也可能有所不同,因此我更新了示例代码。而且我想避免使用 foreach 或 for-loops,因为那样模板本身就被破坏了。我希望能够插入随机 HTML。目前使用 smarty 或其他模板系统是不可行的。但我可以提供带有描述的第三个数组。

更新 2:我认为 $output 上的 preg_replace 可能会起作用?所以这意味着“如果在 $output 的某处有一个包含 {} 括号的 html 标签,那么将整个标签从 to 擦除(我相应地更新了我的代码) 你怎么看?你知道任何 reg_expression 可以做到这一点吗?

【问题讨论】:

  • 但是如何将它合并到数组中以便我可以使用一个字符串作为模板 ($tpl)?
  • 您是否考虑过使用“真正的”模板引擎?类似:smarty.net(免责声明:我不隶属于 Smarty)
  • 是的,最后,我在我的项目中使用了 edenPHP,他们提供了相当不错的模板系统。

标签: php str-replace templating


【解决方案1】:

此代码将起作用:

<?php

$database = array(
"item1" => "banana",
"item2" => "apple",
"item3" => "cherry",
);

$output = '<html>
<body>';

for($i=1;$i<500;$i++) //change 500 with the desired number or setup a dynamic variable
{
    if(isset($database['item'.$i])) //if the current item is set
    {
$output .= '<span class="item">Description for item '.$i.': </span><span class="content">'.$database['item'.$i].'</span>'; //append to $output
$output .= '<br />'; //Here I add a line break, remove if you don't want
    }
}
$output .= '</body></html>';

echo $output;

?>

您会看到,如果 $database 数组中不存在某项,则不会打印出来。 当然你可以去掉代码开头的$database数组(这里用于测试),使用自己生成的$database数组。

在您的特定情况下:如果您想开发自己的模板引擎,您可以在模板中使用特殊字符串(您发明的)(例如 {--ITEMS--}),然后在读取模板的第二个 PHP 文件中处理这些字符串,找到字符串并用一些输出替换它们。为此,您在此处发布的代码中缺少的要点是输出的“构造”,它将替换模板中的固定字符串。您可以通过处理您的数据库并将结果(使用 .= )附加到一个变量来构建输出固定字符串。

【讨论】:

  • 嘿albz!谢谢,您的方法让我想到了在结果输出上使用正则表达式的想法。你认为有这样的表达方式吗?
  • 当然,原则上您可以通过模板运行正则表达式并将特殊字符串替换为结果输出。这意味着将整个模板加载到一个变量中(或逐行),这可能不是最优化的选择。然而,这可能对你有用(一个 HTML 模板通常只有几 KB:它不应该让你的 PHP 应用程序这么慢,除非你同时有成千上万的用户)。您可以查看这个免费脚本作为示例:podcastgen.sf.net(在 /themes 文件夹中您会找到模板,在 /core/themes.php 中您会看到它们是如何被替换的)
【解决方案2】:

我倾向于维护一个你想要的值的数组(也可以来自一个数据库),并让它控制是否显示你的数据库结果(这里显示为 $row )。这样,您还可以组合在找到匹配项时显示的标签

$row= array(
"item1" => "banana",
"item2" => "apple",
"item3" => "cherry",
);

$items = array(
'item1'=>'Favourite Food', 
'item2'=>'Hobbies:',
'item3'=> 'Allergies'
);

foreach($items as $k=>$item){

if (isset($row[$k]) {
// concat a variable
$html .= $item . ' ' . $row[$k] . '<br />';
}


}

echo $html; // or whatever

与回复中显示的其他想法结合使用。

【讨论】:

    【解决方案3】:

    【讨论】:

      【解决方案4】:

      使用此代码:

      $tpl = "<html><body>";
      for($i=1;$i<500;$i++)
      {
          if(isset($database['item'.$i]))
          {
          $tpl = $tpl.'<span class="item">Description for item '.$i.':</span><span class="content">{item'.$i.'}</span>';
          }
      }    
      $tpl = $tpl."</body></html>";
      
      echo str_replace( 
      array('{item1}','{item2}','{item3}') ) , 
      array($database['item1'],$database['item2'],$database['item3']) , 
      $tpl );
      

      【讨论】:

        【解决方案5】:

        我实际上建议在数据库上使用 foreach 循环

        $tpl = '';
        foreach($database as $itemName => $value)
        {
        $tpl .= '<span class="item">Description for item '.$i.':</span><span class="content">{item'.$i.'}</span>';
        }
        

        可能需要适应它,否则应该很好

        【讨论】:

          猜你喜欢
          • 2010-10-03
          • 1970-01-01
          • 1970-01-01
          • 2014-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多