存储在BLOB中的PDF文件不会显示“Content-Length”响应标题

时间:2016-06-13 18:27:13

标签: php pdf blob

以下示例用于在请求时显示PDF文件。

$sql = "SELECT file FROM file_upload WHERE id=:id and file_type in('pdf')";
$query = $conn->prepare($sql);
$query->execute(array(':id' => $_GET['id']));

$query->bindColumn("file", $file, PDO::PARAM_LOB);
$query->fetch(PDO::FETCH_BOUND);

$finfo = new finfo(FILEINFO_MIME);
$mimeType = $finfo->buffer($file);

header("Content-type: $mimeType");
header('Content-Description: PDF document');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
//header('Content-Length: '.strlen($file));
header('Expires: 0');
header('Pragma: no-cache');
header('Cache-Control: no-cache, must-revalidate, max-age=0');

ob_clean();
flush();
echo $file;

显示请求的PDF文件,但添加以下行时

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

浏览器不显示请求的PDF文件。浏览器发出消息。

enter image description here

可能是什么原因? strlen()返回的长度似乎不是确切的长度。 strlen()但是,对于大小为506,296字节(约495 KB)的uploaed PDF文件,返回451295

使用PHP 5.4尝试使用最新版本的Google Chrome和Mozilla FireFox。

1 个答案:

答案 0 :(得分:1)

如果启用了mbstring扩展名,strlen函数将返回字符串的长度,而不是字节。解决方法是在运行时检测扩展情况并使用适当的方法。

处理此问题的一种方法是始终返回字节的函数,无论是否存在mb扩展名。例如:

if (2 & ini_get('mbstring.func_overload')) {
    function bytes($string) {
        return mb_strlen($string, '8bit');
    }
} else {
    function bytes($string) {
        return strlen($string);
    }
}

当然,您可以重写该条件以将条件置于函数内,而不是具有条件函数。对于持续检查会产生运行时惩罚,因此使条件函数更有效。但是,这取决于你的需求。

您也可以使用第三方库。上面的示例取自haldayne/boost。免责声明:我是haldayne / boost的作者。