Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在smarty中处理递归的最佳方法是什么?_Php_Templates_Recursion_Smarty - Fatal编程技术网

Php 在smarty中处理递归的最佳方法是什么?

Php 在smarty中处理递归的最佳方法是什么?,php,templates,recursion,smarty,Php,Templates,Recursion,Smarty,我在Smarty中找到了几种处理递归的方法,主要是基于将模板包含在模板中,这似乎是对资源的荒谬浪费。我找到了一个解决方案,由Smarty的Messju提供,它似乎恰到好处,但它在Smarty的最新版本中不受支持且失败:( 如果有人问:我希望smarty打印的是一个由条目数组定义的讨论线程。如果条目有一个或多个答案,则这些答案将列为数组中所述条目的子条目,依此类推 array( array( 'id'=>0, 'headline'=>"My pa

我在Smarty中找到了几种处理递归的方法,主要是基于将模板包含在模板中,这似乎是对资源的荒谬浪费。我找到了一个解决方案,由Smarty的Messju提供,它似乎恰到好处,但它在Smarty的最新版本中不受支持且失败:(

如果有人问:我希望smarty打印的是一个由条目数组定义的讨论线程。如果条目有一个或多个答案,则这些答案将列为数组中所述条目的子条目,依此类推

array(
    array(
        'id'=>0,
        'headline'=>"My parent headline",
        'body'    =>"My parent body",
        'children'=>array(
            array(
                'id'=>1,
                'headline'=>"My firstChild headline",
                'body'    =>"My firstChild body",
                'children'=>array()
            ),
            array(
                'id'=>2,
                'headline'=>"My secondChild headline",
                'body'    =>"My secondChild body",
                'children'=>array()
            )
        )
    ),
);

嵌套数组有任意深度,每个条目都有任意数量的子。对我来说,这是我想在模板范围内做的事情,因为我认为它是纯显示逻辑。我不想处理HTML或模板外的某种类型的HTML占位符。

我希望smarty将其打印为嵌套列表:

<ul>
    <li>
        <h1>My parent headline</h1>
        <p>My parent body</p>
        <ul>
            <li>
                <h1>My firstChild headline</h1>
                <p>My firstChild body</p>
            </li>
            <li>
                <h1>My secondChild headline</h1>
                <p>My secondChild body</p>
            </li>
        </ul>
    </li>
</ul>
  • 我父母的头条新闻 我父母的身体

    • 我的第一个孩子 我的第一个孩子的身体

    • 我的第二个孩子 我的第二个孩子的身体

我开始意识到这可能是一个非常具体的问题,所以我想我只需要编写一个smarty插件来专门处理这个问题,尽管我更希望有一个全面的解决方案


有办法吗?

最好的办法就是不要这样做


SimTy应该是简单的。这听起来不正确。

< P>你可能想考虑为StfTy创建自定义函数/修改器/插件。 将数组传递给自定义函数,同时定义函数应该使用的模板。如果这么简单,只需在特定位置插入文本,就可以在函数中加载模板,并在PHP中使用regexes/str_replace/…使用模板

或者直接在PHP中执行,而不使用smarty模板,因为您只需要h1、ul、li和p标记,要更改布局,请使用CSS

或者,如果您关心的是Smarty中打开和关闭文件的开销,请估计90%情况下的级别数量,并创建将覆盖这90%的模板。对于其他情况,请通过包含模板本身来使用递归…

“为了理解递归,您必须首先理解递归…”

只是开玩笑。这应该满足你的要求:

<?php
/*
* Smarty plugin
* ————————————————————-
* File:     function.recurse_array.php
* Type:     function
* Name:     recurse_array
* Purpose:  prints out elements of an array recursively
* ————————————————————-
*/

function smarty_function_recurse_array($params, &$smarty)
{

if (is_array($params['array']) && count($params['array']) > 0) {
   $markup = '';

   $markup .= '<ul>';

   foreach ($params['array'] as $element) {
      $markup .= '<li>';

      $markup .= '<h1>' . $element['headline'] . '</h1>';
      $markup .= '<p>' . $element['body'] . '</p>';

      if (isset($element['children'])) {
         $markup .= smarty_function_recurse_array(array('array' => $element['children']), $smarty);
      }

       $markup .= '</li>';
   }

   $markup.= '</ul>';

   return $markup;

} else {
   return 'not array';
}
}
下面是制作自定义Smarty函数的精彩教程:


请注意此示例对基础数据结构的依赖性。此外,请记住,异常长或嵌套深度高的数据集可能会非常慢。管理您的复杂性,将事情记录在案,您应该会没事的。祝您好运!

对于Smarty 3,这可以使用{function}完成。以下代码将生成所需的输出

{function name=printList}
<ul>
    {foreach $items as $item}
    <li>
        <h1>{$item['headline']}</h1>
        <p>{$item['body']}</p>
        {if $item['children']}
            {call name=printList items=$item['children']}
        {/if}
    </li>
    {/foreach}
</ul>
{/function}

{call name=printList items=$comments}
{function name=printList}
    {foreach$items作为$item}
  • {$item['headline']} {$item['body']}

    {如果$item['children']} {call name=printList items=$item['children']} {/if}
  • {/foreach}
{/函数} {调用名称=打印列表项=$comments}
有关更多信息,请访问


旁注:复杂或递归的东西并不意味着它不能在模板中。看在上帝的份上,HTML ul li结构自然是递归的,通过隐藏它或将它移到其他地方(只是因为它对于模板来说太复杂)您给应用程序带来了额外的复杂性。

这样想,应用程序需要显示任意嵌套的内容列表。这是一种复杂性。您需要管理复杂性。将本质上是显示逻辑的内容放入其中(循环数组并吐出标记)是有意义的在模板中。仅仅是递归并不意味着它是邪恶的。这很公平,但与使用一次性函数进行递归相比,聪明的解决方案将是复杂的。太棒了!我知道这是一个老问题,但这种方法非常出色。+1
{function name=printList}
<ul>
    {foreach $items as $item}
    <li>
        <h1>{$item['headline']}</h1>
        <p>{$item['body']}</p>
        {if $item['children']}
            {call name=printList items=$item['children']}
        {/if}
    </li>
    {/foreach}
</ul>
{/function}

{call name=printList items=$comments}