基本上,我面临以下问题:
我有一个大尺寸(4GB)的TAR容器(没有压缩)。这个TAR包含几个文件:
我应该提一下,我确实知道文件3的起始位置(起始索引)以及它的大小(文件长度),因为TAR格式相对容易解析。
我需要做的是上传文件3 ,使用PHP Curl到REST API.THE API端点是HTTP PUT并且标题已正确设置(如果我上传,它可以正常工作整个TAR文件)。
所以,INFILE = TAR容器。 文件3从第X个字节开始,长度为Y个字节。我已经知道了X和Y值。 我需要curl开始将数据从X发送到Y.
到目前为止,我所做的是:
$fileHandle = fopen($filePath, "rb"); //File path is the one of the TAR archive
fseek($fileHandle, $fileStartIndex, SEEK_CUR);
卷曲的设置是。
curl_setopt($curlHandle, CURLOPT_PUT, 1);
curl_setopt($curlHandle, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curlHandle, CURLOPT_INFILE, $fileHandle);
curl_setopt($curlHandle, CURLOPT_INFILESIZE, $fileSize);
我必须提到,此时不能将文件3解压缩到磁盘,因为磁盘空间是任务的主要目的。
我的第一个想法是查看CURLOPT_READFUNCTION,但是这个选项的回调应该返回一个字符串(在我的情况下非常大的一个:3 GB,它打破了PHP变量大小限制)。
有没有人成功处理过这种上传?关于CURLOPT_READFUNCTION的任何其他提示和技巧也是最好的选择。
谢谢!
答案 0 :(得分:2)
根据PHP curl doc:
CURLOPT_READFUNCTION
一个回调接受三个参数。该 第一个是cURL资源,第二个是提供的流资源 通过选项CURLOPT_INFILE来cURL,第三个是 要读取的最大数据量。回调必须返回一个字符串 长度等于或小于请求的数据量, 通常通过从传递的流资源中读取它。这应该 返回一个空字符串以表示EOF。
所以CURLOPT_INFILE
的组合给curl文件句柄,CURLOPT_INFILESIZE
告诉curl最终文件有多大,CURLOPT_READFUNCTION
允许curl从文件中读取看起来像它应该做你需要的。
虽然curl会使用CURLOPT_READFUNCTION
参数调用您的$length
,但您可以在规则中自由返回您想要的内容:
回调必须返回长度等于或小于的字符串 请求的数据量
因此,如果您返回的时间少于$length
,则curl会一直调用您的CURLOPT_READFUNCTION
,直到它返回EOF
(空字符串)。因此,您需要在CURLOPT_READFUNCTION
中阅读时跟踪文件中的位置,并从每次调用的最后一个阅读位置开始。