讨论数量:
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
//远程文件路径
$remoteFileUrl="http://www.gov.cn/zhengce/pdfFile/2021_PDF.pdf";
//本地存储路径绝对地址
$saveFilePath=__DIR__ . "/test_download.pdf";
try {
$pdfFileResource = fopen($saveFilePath, 'w+');
$httpClient = new Client();
$response = $httpClient->get(
$remoteFileUrl,
[RequestOptions::SINK => $pdfFileResource]
);
if ($response->getStatusCode() === 200) {
echo "下载成功:".$saveFilePath;
}
echo "下载失败";
}catch (\Throwable $e){
var_dump($e->getMessage());
}
如果文件的 URL 有规律的话,可以单独搞一台服务器用 Nginx 做反向代理。不过还是推荐直接在 CDN 上做回源到远端服务器,这样用户访问的是你的域名,但是下载的是第三方的文件!
例如我们的测试服 OSS 用的是 MinIO,生产环境用的是 AWS S3,为了避免有些静态资源在开发环境和生产环境需要上传两次,我们将开发环境响应为 404 的请求转发到 S3 上去。
这样只需要在生产环境上传图片,就能兼容开发和生产两个环境的请求!
$filePath = "http://www.baidu.com/测试.pdf";
$filename = "ceshi.pdf";
header("Content-Encoding: UTF-8");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".'"'.$filename.'"');
$old = fopen($filePath,"r");
$new = fopen("php://output","w+");
stream_copy_to_stream($old,$new);
fclose($old);
fclose($new);
exit();
symfony/src/Symfony/Component/HttpFoundation/BinaryFileResponse
你看下 这个文件,能不能解决, 不支持远程文件调用
根据 BinaryFileResponse::prepare(Request $request)
封装下
最简单的用例
// routes/web.php
Route::get('/test', function (){
return BinaryFileResponse::create(__FILE__, 200, [
'Content-Type' => 'application/octet-stream'
]);
});
我是这么处理的 ResponseFactoryMacro.php
<?php
namespace App\Macros;
use GuzzleHttp\Client;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* @see https://github.com/TitasGailius/laravel-stream-remote
*
* @mixin \Illuminate\Routing\ResponseFactory
*/
class ResponseFactoryMacro
{
/**
* ```
* return response()->streamRemoteDownload(
* 'https://example.com/remote/file.zip',
* 'archive.zip',
* ['Content-Type' => 'application/zip'],
* 'attachment',
* 1024
* );
* ```
*/
public function streamRemoteDownload(): \Closure
{
return function (
string $url,
?string $name = null,
array $headers = [],
?string $disposition = 'attachment',
int $chunk = 2048,
?Client $client = null
): StreamedResponse {
$client ??= new Client();
return $this->streamDownload(function () use ($client, $url, $chunk) {
$body = $client->get($url, ['stream' => true])->getBody();
while (! $body->eof()) {
echo $body->read($chunk);
}
}, $name, $headers, $disposition);
};
}
}
推荐文章: