Передайте файл/двоичный файл через бэкэнд laravel в laravel api

Из своего внешнего интерфейса Vue я загружаю файл .glb с почтовым запросом в свой бэкэнд Laravel. Файл прекрасно доходит туда, однако мне нужно передать его дальше API, который сохраняет его в базе данных в виде двоичного файла.

Вот много вариантов, которые я пробовал, а гораздо больше уже удалено. Сначала я пытался отправить сам файл, но потом я заметил, что исходный файл размером 5 МБ, который по-прежнему был 5 МБ на бэкэнде, был всего 1 байт на API, поэтому он не прошел. Затем я попытался опубликовать сами двоичные данные, чтобы API не нужно было получать содержимое файла, а просто сохранял входящие данные в базу данных. Я получал Malformed utf-8 characters от json_encode на бэкенде, теперь я получаю ту же ошибку на стороне API. И затем, когда, к счастью, в некоторых вариантах нет ошибки неправильного формата utf-8, я узнаю, что файл снова вернулся к 1B (пустой).

Внутренний код:

public function uploadBinary(Request $r, $id)
{
    $file = $r->file('file');
    $bin = $file->get();
    // $bin = mb_convert_encoding($bin, 'UTF-8', 'auto');

    // $file->storePubliclyAs('', 'glbtest.glb');

    $res = Http::withToken(config('api.key'))
        ->acceptJson()
        ->withHeaders([
            // 'Content-Type' => 'model/gltf-binary'
            'Content-Type' => 'application/octet-stream'
        ])
        // ->withBody($bin, 'application/octet-stream')
        ->asMultipart()
        // ->attach('file', asset('glbtest.glb'))
        // ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')));
        // ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')), $bin);
        ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')), [
            'file' => $bin
            // 'file' => file_get_contents(storage_path('app/glbtest.glb'))
        ]);

    return response()->json([
        'message' => 'uplo',
        'body' => $res->body(),
        'sizebe' => $file->getSize(),
        'pathbe' => $file->path(),
        'asset' => asset('glbtest.glb'),
    ]);
}

API-код:

public function uploadBinary($id, Request $request)
{
    // $request->setJson(null);
    $tdmodel = Tdmodel::findOrFail($id);

    // $binaryData = $request->getContent();
    // $file = $request->file('file');
    // $binaryData = $file->getContent();

    // $tdmodel->binary_file = $request->getContent();
    // $tdmodel->binary_file = $binaryData;
    $tdmodel->binary_file = $request->file;
    $tdmodel->save();

    return response()->json([
        'message' => 'Binary file uploaded successfully',
        // 'fileAPI' => $file->getSize()
    ]);
}

Могу ли я отправить сам файл, но я что-то упускаю? Могу ли я отправить двоичный файл без Http Laravel, пытающегося кодировать и декодировать данные json? Я чувствую, что у этого должно быть простое решение, но я уже потратил на это два дня. Спасибо.

редактировать:

После еще нескольких тестов я получил версию, которая загружает в API целых 5 МБ, однако в базу данных загружается только 16 МБ. Я также проверил свой файл my.ini, где достаточно большой колпачок с помощью max_allowed_packet=512M.

Серверная часть:

public function uploadBinary(Request $r, $id)
{
    $file = $r->file('file');
    $bin = $file->get();

    $res = Http::withToken(config('api.key'))
        ->acceptJson()
        ->withBody($bin, 'application/octet-stream')
        ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')));

    return response()->json([
        'message' => 'uplo',
        'body' => $res->body(),
        'sizebe' => $file->getSize(),
    ]);
}

API:

public function uploadBinary($id, Request $request)
{
    $tdmodel = Tdmodel::findOrFail($id);

    $binaryData = $request->getContent();
    $stream = fopen('php://memory', 'r+');
    fwrite($stream, $binaryData);
    rewind($stream);

    $tdmodel->binary_file = $stream;
    $tdmodel->save();

    return response()->json([
        'message' => 'Binary file uploaded successfully',
        'binlen' => strlen($binaryData),
        'fstat' => fstat($stream),
    ]);

sizebe из бэкенда имеет значение 5224096 затем из ответа API binlen:5224096fstat\":{\"0\":12,\"1\":0,\"2\":33206,\"3\":1,\"4\":0,\"5\":0,\"6\":-1,\"7\":5224096,\"8\":0,\"9\":0,\"10\":0,\"11\":-1,\"12\":-1,\"dev\":12,\"ino\":0,\"mode\":33206,\"nlink\":1,\"uid\":0,\"gid\":0,\"rdev\":-1,\"size\":5224096,\"atime\":0,\"mtime\":0,\"ctime\":0,\"blksize\":-1,\"blocks\":-1}}

что означает, что я, наконец, получаю правильный двоичный размер на стороне API, как в двоичном содержимом запроса, так и в потоке, в который я его перемещаю. а в базе пока только это:

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, я в конце концов просто использовал guzzle, и все заработало. 3 дня работы в мусорном ведре.

public function uploadBinary(Request $r, $id)
{
    if (!$r->hasFile('file')) {
        return response()->json([
            'message' => 'Binary data not found'
        ], 404);
    }

    $file = $r->file('file');
    $binary = $file->get();

    $client = new Client();

    $headers = [
        'Authorization' => config('api.key_bearer'),
        'Content-Type' => 'application/octet-stream',
    ];
    
    $res = $client->request('POST', replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')), [
        'headers' => $headers,
        'body' => $binary,
    ]);

    return response()->json([
        'message' => 'Uploaded successfully.',
    ]);
}

Другие вопросы по теме