使用 PHP 将二进制流写入浏览器

Posted

技术标签:

【中文标题】使用 PHP 将二进制流写入浏览器【英文标题】:Write binary stream to browser using PHP 【发布时间】:2011-02-17 02:07:48 【问题描述】:

背景

尝试通过 php 将使用 iReport 编写的 PDF 报告流式传输到浏览器。一般的问题是:如何使用 PHP 将二进制数据写入浏览器?

工作代码

header('Cache-Control: no-cache private');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment, filename=climate-report.pdf');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');

$path = realpath( "." ) . "/output.pdf";

$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );

$fh = fopen( $path, 'w' );
fwrite( $fh, $result );
fclose( $fh );

readfile( $path );

无效代码

header('Cache-Control: no-cache private');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment, filename=climate-report.pdf');
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');

$path = realpath( "." ) . "/output.pdf";

$em = java('net.sf.jasperreports.engine.JasperExportManager');
$result = $em->exportReportToPdf($pm);
header('Content-Length: ' . strlen( $result ) );

echo $result;

问题

如何去掉写入文件的中间步骤,直接写入浏览器,这样PDF才不会损坏?

更新

PDF 文件大小:

工作:594778 字节 非工作:1059365 字节

谢谢!

【问题讨论】:

是否添加了您从第一个工作中删除的所有标题? @Casey:在这两种情况下,标题总是相同的。查看修改后的问题。 啊,这是气候报告!不用担心,这很正常。他们总是buggy ;) 我们一直在回显二进制数据,所以这不是您的问题。您从“Content-Length”哪里获得 PDF 文件大小? @ZZ:将两个文件保存到磁盘,然后运行ls 【参考方案1】:

我之前遇到过使用 Java 编写的问题,因为它将使用 UTF-16。来自http://zeronine.org/lab/index.php 的函数outputPDF 使用java_set_file_encoding("ISO-8859-1");。因此:

  java_set_file_encoding("ISO-8859-1");

  $em = java('net.sf.jasperreports.engine.JasperExportManager');
  $result = $em->exportReportToPdf($pm);

  header('Content-Length: ' . strlen( $result ) );

  echo $result;

【讨论】:

你是对的。对不起,我没有尝试。无论如何,我确实通过 file_get_contents 尝试了使用 PDF 红色的代码,并且 echo 可以正常工作。唯一值得一提的是(我认为)Java 和 PHP 的混合。我以前遇到过用 Java 编写的问题,因为它会使用 UTF-16,因此会在字符串中插入大量噪音/空气。也许,写入文件消除了这种编码,这解释了大小的差异以及如果直接执行它为什么不起作用。我没有安装 PHP-Java 桥,所以很抱歉我无法提供更多见解。 嘿...实际上谷歌搜索我想这可能是它。看看这个:php.net/manual/es/function.pdf-utf16-to-utf8.php 更多(抱歉……一旦您知道要查找的内容,请继续在 Google 中寻找好东西):检查:zeronine.org/lab/index.php/Using_Jasper_report_with_PHP 特别是名为 outputPDF 的函数。它使用 java_set_file_encoding("ISO-8859-1");然后是一些额外的魔法:) 希望这会有所帮助【参考方案2】:

您只需编写输出。确保:

已设置正确的标题 在二进制文件之前或之后没有意外打印其他字符(包括空格)。

【讨论】:

标题对我来说看起来是正确的。没有写入其他字符。 并注意意外换行。包含文件中 ?> 之后的换行符会发生这种情况。

以上是关于使用 PHP 将二进制流写入浏览器的主要内容,如果未能解决你的问题,请参考以下文章

C语言二进制流写入文件

如何从 BluetoothChat 的输入/输出流中读取/写入原始十六进制字节?

将 ReadOnlyCollection<byte> 写入流

如何使用 .NET 2.0 将 PDF 文件作为二进制流传输到浏览器

C#将文件转成16进制码流写入数据库存起来,访问的时候再还原成PDF文件。

php Base64编码文件二进制流主要使用