使用外部资源的 URL 在 Laravel 中下载文件

2022-08-30 13:01:03

我将所有上传内容保存在自定义的外部驱动器上。这些文件通过自定义 API 进行存储。

在Laravel 5.2中,我可以对本地文件执行此操作以下载它:

return response()->download('path/to/file/image.jpg');

不幸的是,当我传递URL而不是路径时,Laravel抛出了一个错误:

文件“https://my-cdn.com/files/image.jpg”不存在

(URL当然是假的)。

有没有办法使用Laravel的实现下载图像.jpg文件,或者我用普通的PHP来执行此操作?


答案 1

没有魔法,你应该使用copy()函数下载外部图像,然后在响应中将其发送给用户:

$filename = 'temp-image.jpg';
$tempImage = tempnam(sys_get_temp_dir(), $filename);
copy('https://my-cdn.com/files/image.jpg', $tempImage);

return response()->download($tempImage, $filename);

答案 2

TL;DR
如果您使用的是 5.6 或更高版本,请使用 streamDownload 响应。否则,请实现以下函数。

原始答案
与“下载”响应非常相似,Laravel有一个“流”响应,可用于执行此操作。看看API,这两个函数都是围绕Symfony的BinaryFileResponse和StreamedResponse类的包装器。在Symfony文档中,他们有关于如何创建StreamedResponse的很好的例子。

以下是我使用Laravel的实现:

<?php

use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

Route::get('/', function () {
    $response = response()->stream(function () {
        echo file_get_contents('http://google.co.uk');
    });

    $name = 'index.html';

    $disposition = $response->headers->makeDisposition(
        ResponseHeaderBag::DISPOSITION_ATTACHMENT,
        $name,
        str_replace('%', '', Str::ascii($name))
    );

    $response->headers->set('Content-Disposition', $disposition);

    return $response;
});

更新 2018-01-17

它现在已经合并到Laravel 5.6中,并已添加到5.6文档中。streamDownload 响应可以按如下方式调用:

<?php

Route::get('/', function () {
    return response()->streamDownload(function () {
        echo file_get_contents('https://my.remote.com/file/store-12345.jpg');
    }, 'nice-name.jpg');
});

推荐