在我的页面上,人们可以选择查看pdf文件(在屏幕上)或下载它。 (稍后在他们离线时查看)
当用户选择下载时,代码会执行一次。我用计数器跟踪这个,每次下载都会增加1。所以,这个选项工作正常,可以在下面的if-block中看到 当用户选择查看文件时,会显示pdf文件 - 这样就可以了 - 但是对于每个视图,计数器会递增2。此代码从下面的else-block运行。
我还检查过" Yii trace"并且它实际上经历了两次,但仅在查看文件时...
if ($mode==Library::DOWNLOAD_FILE){
//DOWNLOAD
Yii::app()->getRequest()->sendFile($fileName, @file_get_contents( $rgFiles[0] ) );
Yii::app()->end();
}
else {
//VIEW
// Set up PDF headers
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $rgFiles[0] . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($rgFiles[0]));
header('Accept-Ranges: bytes');
// Render the file
readfile($rgFiles[0]);
Yii::app()->end();
}
}
我尝试了一些其他选项,只是为了看看它会如何导致它运行两次:
所以,只有在通过else-block时才会执行所有这些(Yii请求)执行两次...
提前感谢任何建议......
答案 0 :(得分:0)
我认为这是因为使用sendFile()
方法只打开文件一次,而在else分支中你实际打开它两次。
在if分支中,使用file_get_contents()
打开文件一次,并将文件作为字符串传递给sendFile()
方法,然后计算此字符串的大小,输出标题等:{ {3}}
在else分支中,首先使用filesize()
打开文件,然后使用readfile()
方法打开文件。
我认为你可以通过重写类似于sendFile()方法的else分支来解决这个问题:
基本上将带有file_get_contents()
的文件读入字符串,然后使用mb_strlen()
计算此字符串的长度。输出标题后,只需回显文件内容而不重新打开它。
您甚至可以将整个sendFile()
方法复制粘贴到else分支中,只需将中的“attachment”更改为“inline”(或者使用sendFile方法替换整个if / else语句,更改附件/内联选项以下载或查看,更优雅的方法是覆盖此方法并使用其他参数进行扩展,以查看或下载给定文件):
header("Content-Disposition: attachment; filename=\"$fileName\"");
所以我觉得这样的事情会成为一个解决方案:
// open the file just once
$contents = file_get_contents(rgFiles[0]);
if ($mode==Library::DOWNLOAD_FILE){
//DOWNLOAD
// pass the contents of file to the sendFile method
Yii::app()->getRequest()->sendFile($fileName, $contents);
} else {
//VIEW
// calculate length of file.
// Note: the sendFile() method uses some more magic to calculate length if the $_SERVER['HTTP_RANGE'] exists, you should check it out if this does not work.
$fileSize=(function_exists('mb_strlen') ? mb_strlen($content,'8bit') : strlen($content));
// Set up PDF headers
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $rgFiles[0] . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . $fileSize);
header('Accept-Ranges: bytes');
// output the file
echo $contents;
}
Yii::app()->end();
我希望这能解决你的问题,我的解释是可以理解的。