我需要使用cURL和PHP来访问云存储中的大文件。 存储URL根据请求而变化。 PHP脚本使用库来使用cURL授予访问权限并返回文件。
但是,HTTP请求正在抛出500状态,因为PHP失败并出现错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 133700011 bytes)
那么,我该如何正确地重定向请求呢?字段Location:
也不起作用,因为它错过了HTTP标头中的额外参数。
这是脚本:
function fetch($url, $cookie=null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
任何提示?
答案 0 :(得分:0)
Sub Fill_from_above()
For Each c In Selection.Cells
If c.Value = "" Then
c.Value = c.Offset(-1, 0).Value
End If
Next c
End Sub
$ stream_resource是用fdopen()打开的,比如说。
答案 1 :(得分:0)
你的代码在将内容发送到客户端之前将其全部缓存在内存中,这既缓慢(因为在下载完成100%之前它不会开始发送到客户端)并且内存饥饿 (因为你将整个文件同时放在内存中),而是在下载时将文件批量发送到客户端,然后它更快,并且不会占用太多内存(因为你已经可以释放批量了发送给客户)。幸运的是,curl非常容易,甚至是默认模式,但是你在调用CURLOPT_RETURNTRANSFER
时明确告诉curl不要这样做,所以停止这样做。现在curl_exec($ ch)返回一个bool而不是一个字符串,并且传输被批量发送到客户端,这应该可以解决你的内存问题并且速度更快。还要注意curl_setopt和curl_exec如果出现错误则返回bool(false),不应忽略这些错误,因此我建议你用这些错误捕获的包装器替换它们:
function ecurl_setopt ( /*resource*/$ch , int $option , /*mixed*/ $value ):bool{
$ret=curl_setopt($ch,$option,$value);
if($ret!==true){
//option should be obvious by stack trace
throw new RuntimeException ( 'curl_setopt() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
}
return true;
}
function ecurl_exec ( /*resource*/$ch):bool{
$ret=curl_exec($ch);
if($ret!==true){
throw new RuntimeException ( 'curl_exec() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
}
return true;
}
function return_var_dump(/*...*/){
$args = func_get_args ();
ob_start ();
call_user_func_array ( 'var_dump', $args );
return ob_get_clean ();
}
另外,如果您正在下载的文件是可压缩的,并且目标服务器支持它(绝大多数Web服务器都支持),那么执行curl_setopt($ch,CURLOPT_ENCODING,'');
将允许下载所有已编译卷曲的压缩(通常为gzip
和deflate
),这应该会更快:)
还要注意,如果您要以这种方式运行大量的大型,慢速并发下载,那么PHP只是语言性能的一个糟糕选择,每次下载都会占用整个php进程(或者在Apache mod_php的情况下,线程)直到下载完成,并且通常允许并发运行的PHP进程数量非常有限,这可能会阻止整个网站(我自己在Go中编写下载代理,Goroutines会在附近 - 完成此类工作)