我发现了关于在PHP中加载模板文件的堆栈溢出的问题,这很好,但我希望循环一行的模板文件,多次。 我读过的文章就在这里 [PHP Content Separation。 该页面上的最佳答案来自prodigitalson和他的函数GetTemplate。
现在我想使用这样的东西,但是如果我把它的功能放在循环中那么它就不会非常有效,因为它会多次加载同一个文件。
所以我尝试了这个。我会得到html包括在内。然后将它存储在变量中,然后将其放入循环中。但它没有用。
这是我的代码。数据已经在一个名为$ result的数组中。
$salesTemp=$this->tempLine('salesTEM.php');
while($row = array_shift($result)):
echo $salesTemp;
endwhile;
private function tempLine($file){
ob_start();
require $file;
return ob_get_clean();
}
问题是我的变量没有在模板中更新。 这是我的模板
<li class="list-group-item"><?php echo $Customer;?><span class="label label-primary pull-right">SALES</span></li>
有没有办法重写这个,所以我的$ Customer变量已更新。
我这样做是为了尝试将php和html分开。
答案 0 :(得分:1)
我看到代码的主要问题是当声明$salesTemp
并通过tempLine()
方法运行时,会返回一个字符串(由于ob_get_clean())。模板中的变量已经解析,当循环中回显字符串时,模板中的变量不会更新,因为它们已经被解析并处理成字符串。为了解决这个问题,我会:
while ($row = array_shift($result)) {
echo $this->tempLine('salesTEM.php', $Customer);
}
/**
* @return string
*/
private function tempLine($file, $Customer) {
ob_start();
require $file;
return ob_get_clean();
}
这将是获得你想要的最短途径。如果您希望不在每次迭代中包含模板,请尝试:
$salesTEM = include 'salesTEM.php';
while ($row = array_shift($result)) {
echo sprintf($salesTEM, $Customer);
}
/**
* salesTEM.php
*/
<li class="list-group-item">
%s
<span class="label label-primary pull-right">SALES</span>
</li>
有许多框架可以提供开箱即用的功能,并且可以用于获取有关模板技术的其他信息。从本质上讲,通过函数(文件名和数据)传递信息总是很好的形式,并期望字符串退出。它也使单元测试变得容易。允许它被动地获取信息往往会使代码容易出错,例如:
while ($row = array_shift($result)) {
echo include 'salesTEM.php';
}
/**
* salesTEM.php
*/
<li class="list-group-item">
<?php echo $Customer;?>
<span class="label label-primary pull-right">SALES</span>
</li>
您可能会意外地包含该文件,并且未声明$Customer
变量导致难以发现的错误。定义所有进出的内容,这将使其在未来更容易管理。
答案 1 :(得分:0)
您应该将循环移动到模板文件中,因为您已经使用PHP作为其中的模板语言。这将使您的工作变得更加轻松,并为您提供最佳性能(无需重写整个模板系统)。
关于保持HTML和PHP分离的说法:它实际上不太准确,因为它是从原始目标的微妙重写。即将业务代码和演示文稿代码分开 通常,表示代码是纯HTML,但在动态网站的情况下,表示代码也需要动态元素。大多数情况下,这是通过使用提供自己的模板语言的模板引擎来解决的,但PHP也可以作为一个使用。事实上,PHP最初是作为模板语言开始的。 :)
因此,在您的视图中使用PHP非常好。前提是所说的PHP代码只控制输出,而不是业务操作。
答案 2 :(得分:0)
我有一个有效的答案。然而正如ChristianF所说,这可能不是最好的答案,但这确实解决了我的问题。
正确而不是在html中使用echo我将标记放在%%中,如此
<li class="list-group-item">%CUSTOMER%<span class="label label-primary pull-right">SALES</span></li>
然后是我课堂上的循环。我可以在上一行中构建对象以获得更好的可读性,或者像我一样内联它。
$salesTemp=$this->tempLine('salesTEM.php');
while($row = array_shift($result)):
echo $this->replaceTemp($salesTemp, $obj=(object)array ( 'CUSTOMER' => $row['CustomerName'] ));
endwhile;
和一个小功能
private function replaceTemp($file, $obj){
return preg_replace('~%(\w+)%~e', '$obj->$1', $file);
}
private function tempLine($file){
ob_start();
require $file;
return ob_get_clean();
}
该函数基本上替换了html中的所有内容,其中有%%符号与对象中的任何内容。
<强>更新强> 在发布这个之后我已经改进了我的答案,但是我会把它留在那里,因为这是我原来的答案。以下是改进上述答案的课程。在rTemplate函数中,我可以有一个或多个将在模板中替换的标记。对于示例,我只需要替换一个标记,但您可以添加许多标记。运行testLoad将列出数组,获取模板并使用rTemplate中的内容填充标记。
class testlist{
private $myfile;
public function __construct(){
$this->myfile=$this->loadTemplate('salesTEM.php');
}
public function testload(){
// At this point the array is populated from a database, but I haven't shown this.
// You can populate the array anyway you like.
while($row = array_shift($result)):
echo $this->rTemplate($row['CustomerName']);
endwhile;
}
// This loads in a file into a string and then returns it.
private function loadTemplate($file){
ob_start();
require $file;
return ob_get_clean();
}
// This makes the object to replace keywords, then replaces them
private function rTemplate($customer)
{
$obj = (object) array(
'CUSTOMER' => $id
);
return preg_replace('~%(\w+)%~e', '$obj->$1', $this->myfile);
}
}