PHP 7.2
Не думал что с виду простейшая задача окажется на столько сложным делом и практически без примеров того как это реализовать в интернете, все что находил не работает...
Сейчас у меня файлы передаются одним куском с помощью такой конструкции:
$data = json_decode($data, true);
$stream = fopen(Cb::FILES_DIR . '/' . $taskId . '.' .$data['folder'] . '/' . $data['Name'], 'rb');
$curlOptions[CURLOPT_CONNECTTIMEOUT] = 2;
$curlOptions[CURLOPT_HEADER] = false;
$curlOptions[CURLOPT_BINARYTRANSFER] = 1;
$curlOptions[CURLOPT_URL] = $uri;
$curlOptions[CURLOPT_PUT] = true;
$curlOptions[CURLOPT_VERBOSE] = true;
$curl_log = fopen("curl.txt", 'a');
$curlOptions[CURLOPT_STDERR] = $curl_log;
$curlOptions[CURLOPT_INFILE] = $stream;
$curlOptions[CURLOPT_INFILESIZE] = filesize(Cb::FILES_DIR . '/' . $taskId . '.' .$data['folder'] . '/' . $data['Name']);
Но, файлы стали большими и сервис куда передаю, требует слать чанками файлы и что бы я не пытался сделать, не выходит.
Пример заголовка, который должен быть при отправке файлов чанками:
PUT https://portal5test.cbr.ru/back/rapi2/messages/c84bc346-d57c-482b-b19d-73234492034b/files/8dce3e13-ae01-4df0-ae69-87730a956bce HTTP/1.1
Accept: application/json, application/soap+xml
Authorization: Basic S0xETkVPTEFOVFxPU3ljaGV2YTo4ODkxZHJlYW1mYWxs
Content-Type: application/octet-stream
Content-Range: bytes 0-3207/3208
Content-Length: 3208
Пример моего кода отправки чанками, на который удаленный сервис возвращает ошибку 400:
$fragSize = 10485760;
$fileSize = filesize(Cb::FILES_DIR . '/' . $taskId . '.' . $data['folder'] . '/' . $data['Name']);
$numFragments = ceil($fileSize / $fragSize);
$bytesRemaining = $fileSize;
$i = 0;
$ch = curl_init($uploadUrl);
while ($i < $numFragments) {
$chunkSize = $numBytes = $fragSize;
$start = $i * $fragSize;
$end = $i * $fragSize + $chunkSize - 1;
$offset = $i * $fragSize;
if ($bytesRemaining < $chunkSize) {
$chunkSize = $numBytes = $bytesRemaining;
$end = $fileSize - 1;
}
if ($stream = fopen(Cb::FILES_DIR . '/' . $taskId . '.' . $data['folder'] . '/' . $data['Name'], 'r')) {
// get contents using offset
$result = stream_get_contents($stream, $chunkSize, $offset);
fclose($stream);
}
$headers['Accept'] = 'application/json, application/soap+xml';
$headers['Content-Type'] = 'application/octet-stream';
$headers['Content-Length'] = $numBytes;
$headers['Content-Range'] = $content_range;
curl_setopt($ch, CURLOPT_URL, $uploadUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
//curl_setopt($ch, CURLOPT_HEADER, false);
//curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
//curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
//curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $result);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERPWD, $this->apiAuthLogin . ":" . $this->apiAuthPassword);
$server_output = curl_exec($ch);
$info = curl_getinfo($ch);
$bytesRemaining = $bytesRemaining - $chunkSize;
$i++;
}