本文概述
与广为人知的TCPDF致命错误作斗争?错误”某些数据已经输出, 无法发送PDF文件”是指PHP的输出缓冲区。众所周知, 作为PHP开发人员, 有一些代码会在PHP中生成输出, 而某些代码则不会, 例如, 假设有一个方法getId返回一个数字:
getId();
// [no output]
echo getId();
// Output: 1
因此, 与TCPDF的冲突在于, 一旦你尝试生成PDF并使用以下代码将其放入浏览器中, 库本身便会:
<?php
$pdf->Output('example_006.pdf', 'I');
在你的代码中肯定有一些内容在PDF之前将一些文本或数据发送到PHP的输出缓冲区, 因此引发了异常, 该异常由库自动生成, 以防止生成的PDF损坏。
错误示例
要使用TCPDF在某些代码中触发我们的错误, 将print_r或var_dump设置为某个值将触发该错误。如果使用echo或PHP引发警告, 弃用通知或其他类型的错误, 也会发生这种情况:
<?php
require __DIR__.'../vendor/autoload.php';
// Create new PDF
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetFont("helvetica", '', 10);
$pdf->AddPage();
// Important: this will prevent the generation of the PDF in the browser
// as we are filling the output buffer of PHP
var_dump(array(
"test" => "demo"
));
// create some HTML content
$html = '<h1>HTML Example</h1>
<h2>List</h2>
List example:
<ol>
<li><b>bold text</b></li>
<li><i>italic text</i></li>
<li><u>underlined text</u></li>
<li><b>b<i>bi<u>biu</u>bi</i>b</b></li>
<li><a href="http://www.tecnick.com" dir="ltr">link to http://www.tecnick.com</a></li>
<li>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.<br />Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</li>
<li>SUBLIST
<ol>
<li>row one
<ul>
<li>sublist</li>
</ul>
</li>
<li>row two</li>
</ol>
</li>
<li><b>T</b>E<i>S</i><u>T</u> <del>line through</del></li>
<li><font size="+3">font + 3</font></li>
<li><small>small text</small> normal <small>small text</small> normal <sub>subscript</sub> normal <sup>superscript</sup> normal</li>
</ol>
</div>';
// Output the HTML content
$pdf->writeHTML($html, true, false, true, false, '');
$pdf->lastPage();
$pdf->Output('example_006.pdf', 'I');
前面代码的执行将在浏览器中生成以下输出:
array(1) { ["test"]=> string(4) "demo" } TCPDF ERROR: Some data has already been output, can't send PDF file
解
第一个也是最常见的解决方案是在代码上搜索在TCPDF之前生成某些输出的行或代码, 然后将其删除(提到的方法如print_r, var_dump, echo等)。如果没有方法可以生成输出, 而是警告, 弃用声明或PHP中的错误, 则需要首先解决它们。完成此操作后, 应毫无问题地生成PDF。
如果由于某种原因, 你无法跟踪从何处生成输出, 那么可以使用一个非常简单的技巧(但是非常棘手), 该技巧在使用TCPDF的Output方法生成PDF之前先清理PHP的输出缓冲区:
// Clean any content of the output buffer
ob_end_clean();
// Send the PDF !
$pdf->Output('example_006.pdf', 'I');
这将立即起作用, 但是如果你要使用提到的在输出中生成内容的方法调试浏览器中变量的内容, 则将是一个问题。例如, 如果你清理输出缓冲区, 但要使用以下代码查看变量的内容:
// Debug the content of some variable
var_dump(array(
"data" => "demo"
));
// Clean any content of the output buffer
ob_end_clean();
// Send the PDF !
$pdf->Output('example_006.pdf', 'I');
在我们清理缓冲区之后, 你将永远看不到var_dump的输出。因此, 最好的解决方案是从输出缓冲区中填充不需要的数据, 然后将其删除。
编码愉快!