【问题标题】:Ill formatted HTML from a PHP loop来自 PHP 循环的格式错误的 HTML
【发布时间】:2023-03-26 15:23:01
【问题描述】:

我正在遍历一个数组并构建表格。然后将 HTML 发送到 DOMPDF。但是,如果 HTML 格式错误,DOMPDF 将不会创建 PDF。我认为这就是我的情况。这是我的循环:

<?php foreach($credits as $credit) : ?>
        <?php if($credit['credit_type'] == "short") : ?> 
            <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0px 0px 15px 0px;"> 
                <tr> 
                    <td><strong><?php echo $credit['category_title']; ?></strong></td> 
                </tr> 
                <tr> 
                    <td><?php echo $credit['credit_heading']; ?></td> 
                </tr> 
            </table> 
        <?php endif; ?> 

        <?php if($credit['credit_type'] == "long") : ?>
            <?php if($credit['category_title'] != $oldvalue) : ?>
                <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0px 0px 15px 0px;">
                <tbody>
            <?php endif; ?> 
                <tr>
                    <?php if($credit['category_title'] != $oldvalue) : ?>
                          <td width="25%"><strong><?php echo trim($credit['category_title']); ?></strong></td>                 
                          <td width="25%"><strong>Title</strong></td>
                          <td width="25%"><strong>Role</strong></td>
                          <td width="25%"><strong>Director</strong></td>
                    <?php endif; ?>
                </tr>
                <tr>
                    <td width="25%"><?php echo $credit['credit_heading'];?></td>
                    <td width="25%"><?php echo $credit['credit_title']; ?></td>
                    <td width="25%"><?php echo $credit['credit_role']; ?></td>
                    <td width="25%"><?php echo $credit['credit_director']; ?></td>
                </tr>
                <?php if($credit['category_title'] != $oldvalue) : ?>
                    </tbody>
                    </table>
                <?php endif; ?>
                <?php $oldvalue = $credit['category_title']; ?>
        <?php endif; ?> 
    <?php endforeach; ?>

我这辈子都无法弄清楚我没有关闭哪个标签。如果有人能提供一些见解,那就太棒了!

具体来说,循环正在创建显示一些标题的行,然后在类别标题发生变化时吐出更多行。

【问题讨论】:

  • 最简单的方法就是使用ob_start()ob_end() 获取整个HTML,但是为什么您的PDF 库不能使用“格式错误的HTML”...?
  • 那会做什么?我将如何使用它?
  • 您使用的是哪个版本的 dompdf? dompdf 可以处理格式错误的 HTML,尽管有一些格式问题会破坏渲染。另外,如果 HTML 在结构上不正确,则呈现可能不是您所期望的。
  • 此外,从 dompdf 0.6.0(目前为 beta 2)开始,您可以调用 $dompdf->output_html() 来查看 HTML dompdf 试图解析的内容。但我同意 leo 的观点,如果你需要检查你的 HTML,你应该在将它传递给 dompdf 之前进行。

标签: php html loops foreach dompdf


【解决方案1】:

在不了解您的数据的情况下解析有点困难。例如,为什么“短”信用表随记录打开和关闭,但“长”信用表以前一条记录为条件?是因为你有一个扁平的数据结构,所以相关数据显示为一系列连续的行吗?如果是这种情况,如果数据更加规范化,事情会更容易。 IE。您可以遍历每个信用记录,然后分别遍历详细信息。是否有可能修复您的数据结构?

分析您拥有的代码,您的问题似乎出在代码第二部分的逻辑中。您正在循环结束时设置变量 $oldvalue 的值。这是在关闭表的逻辑之后。因此,如果您解析具有相同类别标题的两条记录,则第二条记录将完全在表之外输出它的表行(不要介意它也会有一个完全空的行)。此外,如果您在做多之后有一个做空信用类型,则该表将永远不会关闭。

话虽如此,我猜你可能需要以下内容:

// build a dummy "previous" record for the first iteration so the conditionals don't break.
<?php $previous_credit = array('credit_type'=>null,'category'=>null); ?>
<?php foreach($credits as $credit) : ?>
    <?php if($credit['credit_type'] == "short" || ($previous_credit['credit_type'] == "long" && $previous_credit['category'] != $credit['category'])) : ?>
              </tbody>
              </table>
    <?php endif; ?> 

    <?php if($credit['credit_type'] == "short") : ?> 
        <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0px 0px 15px 0px;"> 
            <tr> 
                <td><strong><?php echo $credit['category_title']; ?></strong></td> 
            </tr> 
            <tr> 
                <td><?php echo $credit['credit_heading']; ?></td> 
            </tr> 
        </table> 
    <?php endif; ?> 

    <?php if($credit['credit_type'] == "long") : ?>
        <?php if($credit['category_title'] != $previous_credit['category_title']) : ?>
            <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0px 0px 15px 0px;">
            <tbody>
            <tr>
                <td width="25%"><strong><?php echo trim($credit['category_title']); ?></strong></td>                 
                <td width="25%"><strong>Title</strong></td>
                <td width="25%"><strong>Role</strong></td>
                <td width="25%"><strong>Director</strong></td>
            </tr>
        <?php endif; ?> 
            <tr>
                <td width="25%"><?php echo $credit['credit_heading'];?></td>
                <td width="25%"><?php echo $credit['credit_title']; ?></td>
                <td width="25%"><?php echo $credit['credit_role']; ?></td>
                <td width="25%"><?php echo $credit['credit_director']; ?></td>
            </tr>
    <?php endif; ?>
    <?php $previous_credit = $credit; ?>
<?php endforeach; ?>

<!-- one last table close for the last record -->
</tbody></table>

(那是一些丑陋的代码,我没有时间继续修改它,所以......社区维基,以防其他人想要清理它。)

【讨论】:

    【解决方案2】:

    这可能是一个简单的解决方案,但也许不是最好的:

    我建议你使用 PHP 的 Tidy 类(最终你必须先安装它...)
    Here is the link for the Tidy class Manual.

    在第一行:

    ob_start();
    

    此命令会缓冲以下脚本输出的所有内容。
    下面的代码应添加到文件末尾,或者您要显示输出的位置。
    它首先使用ob_get_contents() 获取缓冲区,然后清理代码。
    请注意,您最终必须根据需要更改配置参数,确实有很多。

    $raw_output = ob_get_clean();
    
    $config = array('indent' => true, 'output-xhtml' => true, 'wrap' => 0);
    $tidy = new Tidy;
    $tidy->parseString($raw_output, $config, 'utf8');
    $tidy->cleanRepair();
    
    echo $tidy;
    

    此示例代码由the example on php.net 的原始版本修改。

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 2012-07-09
      • 2023-03-15
      • 2020-03-18
      • 2022-01-22
      相关资源
      最近更新 更多