PHP cURL 实时代理(流文件)
Posted
技术标签:
【中文标题】PHP cURL 实时代理(流文件)【英文标题】:PHP cURL Realtime proxy (stream file) 【发布时间】:2016-11-19 22:01:33 【问题描述】:目前我有如下脚本:
<?php
$filename = "http://someurl.com/file.ext";
header('Content-Type: application/octet-stream');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$filename);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 500);
$data=curl_exec($ch);
curl_close($ch);
echo $data;
?>
问题是服务器在下载整个文件后才发送响应。我想让它像“流”一样工作,在下载文件时发送数据块作为响应。
用 PHP 和 cURL 可以实现吗?
【问题讨论】:
This 可能就是您要找的。span> 我以前从未使用过composer,我在共享主机中,但我会搜索更多。 【参考方案1】:这是可能的。您可以使用 curl 选项 CURLOPT_WRITEFUNCTION
指定一个回调,您将在其中接收数据块,以便您可以在 curl 下载文件时直接将它们发送到客户端。
<?php
$filename = "http://someurl.com/file.ext";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$filename);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 500);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data)
echo $data;
return strlen($data);
);
curl_exec($ch);
curl_close($ch);
【讨论】:
使用 5 mb 文件对其进行了测试。我相信它不会只是逐渐发送块,而是发送已经从开始多次传输的数据,或者它在某种程度上已损坏。这需要特定的php版本? write 函数不应该两次接收相同的数据。最低 PHP 版本为 5.3,以允许将匿名函数提供给 CURLOPT_WRITEFUNCTION。否则没有要求。我再次尝试了从 5 MB 到 480 MB 的各种文件,它几乎立即开始在我的计算机上下载,文件校验和匹配并正常打开。 我终于找到了问题,是由cloudflare引起的...代码按预期工作。谢谢。 工作正常..!谢谢@drew010 @SuperNova 不保证发送长度。如果他们发送内容长度标头,则很容易使用CURLOPT_HEADERFUNCTION
获取并在发送任何数据之前发送它。您也可以从this 我的其他答案中借用一些逻辑,该答案显示了如何获取远程资源的内容长度。【参考方案2】:
Curl 默认会直接输出响应,除非你指定CURLOPT_RETURNTRANSFER
。
您的代码只需删除CURLOPT_RETURNTRANSFER
和最后一个echo
即可工作:
<?php
$filename = "http://someurl.com/file.ext";
header('Content-Type: application/octet-stream');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$filename);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 500);
$data=curl_exec($ch);
curl_close($ch);
?>
【讨论】:
CURLOPT_RETURNTRANSFER
是阻止该默认行为的几个选项之一。其他包括:CURLOPT_NOBODY
和 CURLOPT_FILE
和 CURLOPT_WRITEFUNCTION
以上是关于PHP cURL 实时代理(流文件)的主要内容,如果未能解决你的问题,请参考以下文章