我正在使用Azure blob存储将巨大的pdf和zip文件存储在云端。 我通过azure sdk访问php并将文件直接推送给用户(当然用户不应该看到文件的来源,所以我不会将他重定向到Microsoft URL)。 我的代码如下所示:
$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($this->azureConfig['connectionString']);
$blob = $blobRestProxy->getBlob($container, $blobName);
$properties = $blobRestProxy->getBlobProperties($container, $blobName);
$size = $properties->getProperties()->getContentLength();
$mime = $properties->getProperties()->getContentType();
$stream = $blob->getContentStream();
header("Pragma:no-cache");
header("Cache-Control: no-cache, must-revalidate");
header("Content-type: $mime");
header("Content-length: $size");
fpassthru($stream);
对于小文件,完全没问题,对于较大的文件,我收到此错误:
Fatal error: Out of memory (allocated 93323264) (tried to allocate 254826985 bytes) in \vendors\azure-sdk-for-php\WindowsAzure\Common\Internal\Utilities.php on line 450
有没有更好的方法可以为用户提供云存储文件而无需识别它?
我已经找到了这个讨论https://github.com/Azure/azure-sdk-for-php/issues/729,但卷曲解决方案不起作用。
谢谢!
最佳Gesh
答案 0 :(得分:1)
根据我的理解,由于下载较大的文件,该程序会消耗更多内存。在这种情况下,我们可以采取这些操作来克服内存耗尽错误:
有一个名为memory_limit
的PHP env配置来限制可以分配的内存。我们可以使用代码
ini_set("memory_limit","200M");
如果您不想设置文件大小,可以将memory_limit值设置为“-1”,如:
ini_set("memory_limit","-1");
另一种方法,我们可以在配置文件中放大这个(比如php.ini)。这个official guide告诉你如何配置PHP环境。
我们还可以在chucks中下载大blob以减少内存开销。
要查看BlobRestProxy.php
中的SDK源代码,有一个函数用于获取Blob public function getBlob($container, $blob, $options = null)
,我们可以将其他参数设置为$options
,以便每次都将Blob分段。这是我的代码片段:
$properties = $blobRestProxy->getBlobProperties($container, $blobName);
$size = $properties->getProperties()->getContentLength();
$mime = $properties->getProperties()->getContentType();
$chunk_size = 1024 * 1024;
$index = 0;
//$stream = "";
header("Pragma: public");
header('Content-Disposition: attachment; filename="' . $blobName . '"');
header('Expires: 0');
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Transfer-Encoding: binary");
header("Content-type: $mime");
header("Content-length: $size");
ob_clean();
while ($index < $size) {
$option = new GetBlobOptions();
$option->setRangeStart($index);
$option->setRangeEnd($index + $chunk_size - 1);
$blob = $blobRestProxy->getBlob($container, $blobName, $option);
$stream_t = $blob->getContentStream();
$length = $blob->getProperties()->getContentLength();
$index += $length;
flush();
fpassthru($stream_t);
}
如有任何疑虑,请随时告诉我。