我想允许我的用户通过提供图像的 URL 来上传文件。
与imgur非常相似,您输入http://something.com/image.png,脚本会下载文件,然后将其保存在服务器上并发布。
我尝试使用file_get_contents()
and getimagesize()
。但我认为会有问题:
- 如何保护脚本免受 100 个用户向大图像提供 100 个 URL 的影响?
- 我如何确定下载过程是否会花费或已经花费太长时间?
我想允许我的用户通过提供图像的 URL 来上传文件。
与imgur非常相似,您输入http://something.com/image.png,脚本会下载文件,然后将其保存在服务器上并发布。
我尝试使用file_get_contents()
and getimagesize()
。但我认为会有问题:
这实际上很有趣。
看来您实际上可以跟踪和控制cURL
转移的进度。请参阅关于和的文档CURLOPT_NOPROGRESS
CURLOPT_PROGRESSFUNCTION
CURLOPT_WRITEFUNCTION
我找到了这个例子并将其更改为:
<?php
file_put_contents('progress.txt', '');
$target_file_name = 'targetfile.zip';
$target_file = fopen($target_file_name, 'w');
$ch = curl_init('http://localhost/so/testfile2.zip');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_NOPROGRESS, FALSE);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress_callback');
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'write_callback');
curl_exec($ch);
if ($target_file) {
fclose($target_file);
}
$_download_size = 0;
function progress_callback($download_size, $downloaded_size, $upload_size, $uploaded_size) {
global $_download_size;
$_download_size = $download_size;
static $previous_progress = 0;
if ($download_size == 0) {
$progress = 0;
}
else {
$progress = round($downloaded_size * 100 / $download_size);
}
if ($progress > $previous_progress) {
$previous_progress = $progress;
$fp = fopen('progress.txt', 'a');
fputs($fp, $progress .'% ('. $downloaded_size .'/'. $download_size .")\n");
fclose($fp);
}
}
function write_callback($ch, $data) {
global $target_file_name;
global $target_file;
global $_download_size;
if ($_download_size > 1000000) {
return '';
}
return fwrite($target_file, $data);
}
write_callback
检查数据的大小是否大于指定的限制。如果是,它会返回一个空字符串来中止传输。我分别在 80K 和 33M 的 2 个文件上进行了测试,限制为 1M。在您的情况下,progress_callback
超出第二行毫无意义,但我将所有内容都保留在那里以进行调试。
获取数据大小的另一种方法是发出HEAD
请求,但我认为不需要服务器发送Content-length
标头。
要回答问题一,您只需在代码中添加适当的限制。定义您希望在给定时间内接受多少请求,在数据库中跟踪您的请求,然后从那里开始。还要限制文件大小。
对于问题二,如果您使用 cURL ,您可以设置适当的超时。