我需要一种方法来加载一个外部URL的大文件,并上传到一个不同的目的地,而不是实际临时保存在本地。上载由接受资源或StreamInterface作为源的外部包处理。我已经看过了guzzle文档,但没有找到合适的解决方案。
到目前为止,我被这样的东西卡住了:
# Download
$client = new GuzzleHttp\Client(['base_uri' => 'https://host.com']);
$resource = fopen('tmp_file', 'w');
$stream = GuzzleHttp\Psr7\stream_for($resource);
$client->request('GET', '/test.zip', [
'sink' => $stream,
]);
# Upload
$uploadHandler->upload($stream);不幸的是,这无论如何都不起作用。文件正在完全下载,然后才开始上传。目标也没有收到可用的文件-我不能看到它到底收到了什么,但它要么是空的,要么是损坏的。
因此,总而言之,如果文件在下载时被“传递”(上传),这将是理想的。如果有一个小的本地缓冲区文件也没问题。
这是完全可行的吗?
发布于 2020-08-19 02:41:52
你有没有尝试过使用curl流式传输文件。我在这里写这篇文章,所以可能需要额外的测试,但如下所示:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://remote.server/file_handler.php");
curl_setopt($curl, CURLOPT_USERPWD, "user:pass");
// to return the result as a string and not output it directly
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_PUT, true);
// This is the remote file and if it is a stream you will need it's content length
// meta_data will provide you with this
$file = 'http://host.com/test.zip';
$fp = fopen($file, "r");
$meta = stream_get_meta_data($fp);
curl_setopt($curl, CURLOPT_INFILESIZE, $meta['unread_bytes']);
curl_setopt($curl, CURLOPT_INFILE, $fp);
curl_exec($curl);
curl_close($curl);
fclose($fp); 作为服务器密集型操作,您还可以查看由php:https://www.php.net/manual/en/ref.ftp.php提供的ftp服务,更准确地说,是ftp_append或ftp_put之类的服务。
但我的建议是先尝试上面的脚本。
P.S
$file变量表示您所说的远程文件,远程服务器是CURLOPT_URL中的字符串。至少在理论上,您正在将正在读取的流从一个远程服务器传递到另一个远程服务器。
P.S
通过这种方式,您可以在远程文件上向fopen添加标头。
$options = [
'http' => [
'method'=>"GET",
'header'=>"Accept-language: EN\r\n ANOTHER-HEADER: test=test"
]
];
$defineContext = stream_context_create($options);
$fp = fopen('http://host.com/test.zip', 'r', false, $defineContext);您可以参考以下内容了解更多详细信息:https://www.php.net/stream-context-create
https://stackoverflow.com/questions/63473973
复制相似问题