【问题标题】:Dynamically ordering HTML output from PHP从 PHP 动态排序 HTML 输出
【发布时间】:2014-10-17 06:13:57
【问题描述】:

我对 PHP 有基本的了解,但我觉得我想要做的事情可以通过一种更简单的方式来完成。我正在使用 PHP 来显示 Wordpress 主题的 HTML 内容。我希望用户能够确定 HTML“块”的显示顺序。目前我正在使用if/elseif 设置。这是一个过于简化的例子:

if ( $layout == 'layout_one' ) {
   echo '<div class="header">Header</div>';
   echo '<div class="content">Content</div>';
   echo '<div class="footer">Footer</div>';
} elseif ( $layout == 'layout_two' ) {
   echo '<div class="content">Content</div>';
   echo '<div class="header">Header</div>';
   echo '<div class="footer">Footer</div>';
} elseif ( $layout == 'layout_three' ) {
   echo '<div class="footer">footer</div>';
   echo '<div class="header">Header</div>';
   echo '<div class="content">Content</div>';
}

现在,由于布局选项(排列)的剪切数量,这种技术成为绝对的熊市。因此,在我看来,您将为每个 HTML 内容块编写一个单独的函数,然后以某种方式拥有另一个函数,以用户指定的顺序呈现它们。或者也许将所有块放入一个数组中,然后根据布局选择对数组重新排序......

无论如何,我已经在如何实际做到这一点上碰壁了。任何指导将不胜感激。谢谢

【问题讨论】:

  • 一般方法(准备块内容,然后对块排序)似乎是合理的。问题是什么——你不知道如何编写函数来准备块内容?或者您不确定使用 if/else 循环或其他方式是否更好?
  • 另一个快速评论——如果你在代码中选择了令人眼花缭乱的不同布局,用户也可能会发现不同布局选择的数量也令人眼花缭乱。

标签: php


【解决方案1】:

switch case 可以用来代替长的elseif 条件。因为 switch 比elseif 更高效,并且会支持大量的条件。你的代码的确切替换将如下所示。

switch ($layout) {
    case 'layout_one':

        echo '<div class="header">Header</div>';
        echo '<div class="content">Content</div>';
        echo '<div class="footer">Footer</div>';

        break;
    case 'layout_two':

        echo '<div class="content">Content</div>';
        echo '<div class="header">Header</div>';
        echo '<div class="footer">Footer</div>';

        break;
    case 'layout_three':

        echo '<div class="footer">footer</div>';
        echo '<div class="header">Header</div>';
        echo '<div class="content">Content</div>';

        break;
}

另外一个由 php include 函数完成的棘手工作。您可以将模板创建为与 if 语句中使用的名称相同的 php 文件,并在 include 语句中使用该变量。示例代码如下所示。

include("/path_to/layout/".$layout.".php");

示例 HTML 布局将如下所示,并带有相关名称。

layout_one.php

<div class="header">Header</div>
<div class="content">Content</div>
<div class="footer">Footer</div>

【讨论】:

  • 是的,但我仍然需要为每个案例手动复制订单。也许没有办法绕过复制......嗯
【解决方案2】:

这个呢:

<?php
$h = '<div class="header">Header</div>';
$c = '<div class="content">Content</div>';
$f = '<div class="footer">Footer</div>';

if ($layout == 'layout_one') {
    echo $h.$c.$f;
} elseif($layout == 'layout_two') {
    echo $c.$h.$f;
} elseif($layout == 'layout_three') {
    echo $f.$h.$c;
}

【讨论】:

    【解决方案3】:

    这不是一个小问题;随着布局部件数量的增加,它变得越来越难以维护。不过,我将尝试为此提供一个“简单”的解决方案。

    假设您有 3 个部分,如您的示例所示。但是,这应该适用于 N 部分。您将它们设置在一个数组中:

    $parts = [
      0 => '<div class="header">Header</div>',
      1 => '<div class="content">Content</div>',
      2 => '<div class="footer">Footer</div>'
      ]
    

    然后您希望以一种确定的方式组合。这是我想出的,虽然我确定有some algorithm to do all possible combinations(算法的一个例子)所以这一步是自动的:

    $layout_combinations = [
      0 => [0, 1, 2],
      1 => [0, 2, 1],
      2 => [1, 0, 2],
      3 => [1, 2, 0],
      4 => [2, 0, 1],
      5 => [2, 1, 0]
      ];
    

    你真的有$layout == 'layout_one'吗?我们必须转换它:

    $layout_number = [
      'layout_one'   => 0,
      'layout_two'   => 1,
      'layout_three' => 2,
      'layout_four'  => 3,
      'layout_five'  => 4,
      'layout_six'   => 5
      ];
    

    要使用它,在定义了上面的部分之后,只需这样做:

    $layout = 'layout_four';
    
    if (!array_key($layout, $layout_number))
      throw new Exception('Invalid layout');
    
    $layout_number = $layout_number[$layout];
    
    $layout_structure = $layout_combinations[$layout_number];
    
    foreach ($layout_structure as $part_number) {
      echo $parts[$part_number];
      }
    

    主要优点是它很容易扩展。如果要放另一部分,只需将其添加到$parts 数组中,添加对应的新$layout_combinations 和“english => number”转换即可。

    注意:如果使用$layout = 4 而不是$layout = 'layout_four',则可能会阻止一个步骤。这是非常可取的,因为它允许您使其自动化,只需在 $parts 数组的末尾添加一个元素。

    【讨论】:

    • 这真是太好了!也许 ndiego 应该考虑让它更简单:不需要 $layout_number 数组,他应该使用整数作为 layout_numbers。例如:$layout = 1 而不是 $layout = 'layout_one'。然后他就不再需要数组 layout_number 了。你怎么看?
    • 我完全同意,我只是添加了一条注释。它使向布局中添加新部分的过程就像在$parts 中添加新元素一样简单(:
    • 这正是我的想法!太感谢了。我只是很难把它们放在一起。是的,我喜欢你简化流程的想法。再次感谢!
    • 这可能过于复杂了——您可以通过编程方式生成不同的组合和布局编号。
    • 感谢@girlwithglasses,我在I'm sure there's some algorithm to do the same so it doesn't become difficult to maintain for N &gt; 3 中注意到了这一点,我希望$layout 能够通过更改OP 中的一些先前代码从一开始就成为一个数字,所以不需要也为那一步。
    【解决方案4】:

    为每个布局创建一个标识符,指示组件的顺序,例如h_c_f 表示页眉、内容、页脚,c_f_h 表示内容、页脚、页眉。

    将部分的内容存储在由相应字母索引的数组中:

    $section_stuff = array(
       'h' => '<div>Header</div>',
       'c' => '<div>Contents</div>',
       'f' => '<div>Footer</div>',
    );
    

    使用布局标识符组装您的输出以计算顺序:

    // $order is the layout name, e.g. c_f_h, f_c_h, etc.
    // split $order by "_" to get the appropriate order
    
    $ordered = explode( '_', $order );
    foreach ($ordered as $section) {
        echo $section_stuff[$section];
    }
    

    显然您需要添加错误检查等。

    这种方法的优点是您可以使用诸如拖放界面之类的东西来设置部分的顺序;标识符名称指示布局,而不是任意值。

    如果你想提前生成所有可能的布局,the PHP cookbook 有一些合适的建议。

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多