info('Uploading file, size: ' . strlen($content)); $size = strlen($content); $offset = 0; // 文件本身小于分片大小,直接一个包发送 if ($size <= $this->buffer_size) { $obj = $this->ctx->sendAction('upload_file', [ 'type' => 'data', 'name' => $filename, 'data' => base64_encode($content), 'sha256' => hash('sha256', $content), ]); if (!$obj instanceof ActionResponse) { $this->err = 'prepare stage returns an non-response object'; return false; } if ($obj->retcode !== 0) { $this->err = 'prepare stage returns an error: ' . $obj->retcode; return false; } return $obj->data['file_id']; } // 其他情况,使用分片的方式发送,依次调用 prepare, transfer, finish $obj = $this->ctx->sendAction('upload_file_fragmented', [ 'stage' => 'prepare', 'name' => $filename, 'total_size' => strlen($content), ]); if (!$obj instanceof ActionResponse) { $this->err = 'prepare stage returns an non-response object'; return false; } if ($obj->retcode !== 0) { $this->err = 'prepare stage returns an error: ' . $obj->retcode; return false; } $file_id = $obj->data['file_id']; while ($offset < $size) { $data = substr($content, $offset, $this->buffer_size); $this->ctx->sendAction('upload_file_fragmented', [ 'stage' => 'transfer', 'file_id' => $file_id, 'offset' => $offset, 'data' => base64_encode($data), ]); if (strlen($data) < $this->buffer_size) { break; } $offset += $this->buffer_size; } $final_obj = $this->ctx->sendAction('upload_file_fragmented', [ 'stage' => 'finish', 'file_id' => $file_id, 'sha256' => hash('sha256', $content), ]); if (!$final_obj instanceof ActionResponse) { $this->err = 'finish error with non-object'; return false; } if ($final_obj->retcode !== 0) { $this->err = 'finish error: ' . $final_obj->retcode; return false; } return $final_obj->data['file_id']; } /** * 从本地路径上传一个文件 * * @throws \Throwable */ public function uploadFromPath(string $file_path): bool|string { if (file_exists($file_path)) { $name = pathinfo($file_path, PATHINFO_BASENAME); $content = file_get_contents($file_path); return $this->uploadFromString($name, $content); } $this->err = 'File from path ' . $file_path . ' does not exist.'; return false; } /** * 获取错误消息 */ public function getErr(): string { return $this->err; } }