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

les*_*gar 14 php laravel

我将所有上传内容保存在自定义外置硬盘上.这些文件是通过自定义API存储的.

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

return response()->download('path/to/file/image.jpg');
Run Code Online (Sandbox Code Playgroud)

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

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

(当然,URL是虚拟的).

有没有办法可以使用Laravel的实现下载image.jpg文件,还是用普通的PHP代替?

Lim*_*nte 27

没有魔力,您应该使用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);
Run Code Online (Sandbox Code Playgroud)

  • 我现在看到,在某个时候 Laravel 在下载响应中添加了一个 `->deleteFileAfterSend()` 方法。 (4认同)

The*_*lis 17

与"下载"响应非常相似,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;
});
Run Code Online (Sandbox Code Playgroud)

更新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');
});
Run Code Online (Sandbox Code Playgroud)


Val*_*Shi 12

至于 2020 年,这一切都很容易。

2 行代码下载到您的服务器,2 行代码上传到浏览器(如果需要)。

假设您希望将 google 主页的 HTML 本地保存到您的服务器上,然后返回 HTTP 响应以启动浏览器以在客户端幻灯片下载文件:

// Load the file contents into a variable.
$contents = file_get_contents('www.google.com');

// Save the variable as `google.html` file onto
// your local drive, most probably at `your_laravel_project/storage/app/` 
// path (as per default Laravel storage config)
Storage::disk('local')->put('google.html', $contents);

// -- Here your have savde the file from the URL 
// -- to your local Laravel storage folder on your server.
// -- By default this is `your-laravel-project/storage/app` folder.

// Now, if desired, and if you are doing this within a web application's
// HTTP request (as opposite to CLI application)
// the file can be sent to the browser (client) with the response
// that instructs the browser to download the file at client side:

// Get the file path within you local filesystem
$path = Storage::url('google.html');

// Return HTTP response to a client that initiates the file downolad
return response()->download($path, $name, $headers);
Run Code Online (Sandbox Code Playgroud)

查找 Laravel存储外观文档以获取有关磁盘配置和put方法的详细信息,以及使用文件下载文档的响应以返回带有 HTTP 响应的文件。


Jam*_*g56 7

为什么不使用简单的重定向?

return \Redirect::to('https://my-cdn.com/files/image.jpg');
Run Code Online (Sandbox Code Playgroud)

  • 这将重定向到外部资源 - 并留在页面上,这绝对不是我需要的 ;) (3认同)

mas*_*ood 5

试试这个脚本:

// $main_url is path(url) to your remote file
$main_url = "http://dl.aviny.com/voice/marsieh/moharram/92/shab-02/mirdamad/mirdamad-m92-sh2-01.mp3";
header("Content-disposition:attachment; filename=$main_url");
readfile($main_url);
Run Code Online (Sandbox Code Playgroud)

如果您不希望最终用户可以在标题中看到 main_url,请尝试以下操作:

$main_url = "http://dl.aviny.com/voice/marsieh/moharram/92/shab-02/mirdamad/mirdamad-m92-sh2-01.mp3";
$file = basename($main_url);
header("Content-disposition:attachment; filename=$file");
readfile($main_url);
Run Code Online (Sandbox Code Playgroud)