使用 PHP CURL 将包含的 TAR 文件上传到 REST PUT API,无需解压

Upload TAR contained file to REST PUT API using PHP CURL without extracting

基本上,我面临以下问题:

我有一个 TAR 大容量 (4GB) 容器(无压缩)。这个TAR包含几个文件:

我应该提一下,我确实知道文件 3 从哪里开始(起始索引)以及它有多大(文件长度),因为 TAR 格式相对容易解析。

我需要做的是 上传文件 3 通过使用 PHP Curl 到 REST API.THE API 端点是 HTTP PUT 和headers 已正确设置(如果我正在上传整个 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的设置是

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 提取到磁盘,因为磁盘 space 是任务的主要目的。

我的第一个想法是查看 CURLOPT_READFUNCTION,但此选项的回调应该 return 一个字符串(在我的例子中非常大:3 GB,它打破了 PHP 变量大小限制).

有人成功处理过这种上传吗?关于 CURLOPT_READFUNCTION 的任何其他提示和技巧也非常感谢。

谢谢!

根据 PHP curl doc:

CURLOPT_READFUNCTION
A callback accepting three parameters. The first is the cURL resource, the second is a stream resource provided to cURL through the option CURLOPT_INFILE, and the third is the maximum amount of data to be read. The callback must return a string with a length equal or smaller than the amount of data requested, typically by reading it from the passed stream resource. It should return an empty string to signal EOF.

所以组合 CURLOPT_INFILE 给 curl 文件句柄,CURLOPT_INFILESIZE 告诉 curl 最终文件有多大,CURLOPT_READFUNCTION 允许 curl 从文件中读取看起来应该可以满足您的需求。

尽管 curl 将使用 $length 参数调用您的 CURLOPT_READFUNCTION,但您可以根据规则自由 return 您想要的内容:

The callback must return a string with a length equal or smaller than the amount of data requested

所以如果你 return 小于 $length,curl 将继续调用你的 CURLOPT_READFUNCTION 直到它 returns EOF(一个空字符串)。因此,您需要在读取 CURLOPT_READFUNCTION 时跟踪您在文件中的位置,并从每次调用的最后读取位置开始。