You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel向API端点发送变量为空的问题排查求助

问题描述

我尝试从Laravel控制器向API端点发送表单数据(含文件),但API端检查变量时所有值均为null。已通过dd($multipart)确认提交时表单数据完整,相关代码片段如下:

后台控制器(CulinaryController.php)

public function update(Request $request, Culinary $culinary)
{
    $client = new Client();
    $token = Session('token');

    try {
        $multipart = [];

        foreach ($request->except('cover_photo') as $key => $value) {
            $multipart[] = [
                'name' => $key,
                'contents' => $value,
            ];
        }
        
        if ($request->hasFile('cover_photo')) {
            $coverPhoto = $request->file('cover_photo');
            $multipart[] = [
                'name' => 'cover_photo',
                'contents' => fopen($coverPhoto->getRealPath(), 'r'),
                'filename' => $coverPhoto->getClientOriginalName(),
            ];
        }
        dd($multipart);
        
        $url = 'http://localhost/api/v1/culinary/'.$culinary->id;
        $response = $client->put($url, [
            'multipart' => $multipart,
            'headers' => [
                'Authorization' => 'Bearer '.$token,
                'Accept' => 'application/json',
            ]
        ]);
    } catch (Exception $e) {
        return redirect()->back()->withErrors(['errors' => $e->getMessage()])->withInput();
    }
}

API控制器(api/v1/CulinaryController.php)

public function update(Request $request, Culinary $culinary)
{
    return response()->json([
        'status' => 'test',
        'request' => $request->all(),
        'foo' => request('title'),
        'file' => $request->file('cover_photo'),
        'culinary' => $culinary,
    ]);
}

API路由(routes/api.php)

Route::apiResource('culinary', CulinaryController::class);

dd($multipart)输出的数据示例

array:9 [▼ // app\Http\Controllers\AdminCulinaryController.php:198
  0 => array:2 [▼
    "name" => "_token"
    "contents" => "TwpS0e7OJH1jhhR1dr8RBpCiYKW4vhVyuk3CRZWC"
  ]
  1 => array:2 [▼
    "name" => "_method"
    "contents" => "PUT"
  ]
  2 => array:2 [▼
    "name" => "title"
    "contents" => "Et in quia ut et illo harum."
  ]
  3 => array:2 [▼
    "name" => "old_cover_photo"
    "contents" => "https://via.placeholder.com/640x480.png/0022bb?text=distinctio"
  ]
  4 => array:2 [▼
    "name" => "country_id"
    "contents" => "188"
  ]
  5 => array:2 [▼
    "name" => "category_name"
    "contents" => "vegetarian"
  ]
  6 => array:2 [▼
    "name" => "prologue"
    "contents" => "Adipisci iure nihil sit voluptatem rerum voluptatibus. Qui aperiam et magnam corrupti quia eius reprehenderit. Sunt non aut dolores. Dolorem nesciunt atque ipsa ▶"
  ]
  7 => array:2 [▼
    "name" => "body"
    "contents" => "Autem iure qui magni excepturi hic. Laudantium adipisci saepe odio quod cupiditate. Blanditiis occaecati sint at sint incidunt optio illum nihil."
  ]
  8 => array:2 [▼
    "name" => "opening_hours"
    "contents" => "Qui et magnam labore a ea corrupti."
  ]
]
问题排查与解决

核心原因:Laravel默认仅解析POST方法的multipart/form-data请求体,直接用PUT方法发送multipart请求时,框架无法自动解析表单数据,导致所有值为null。

方案一:改用POST方法伪造PUT请求(推荐)

调整Guzzle请求方法为POST,同时保留_method=PUT的字段(已包含在multipart中):

// 替换原PUT请求代码
$response = $client->post($url, [
    'multipart' => $multipart,
    'headers' => [
        'Authorization' => 'Bearer '.$token,
        'Accept' => 'application/json',
    ]
]);

Laravel会识别_method字段,自动将请求视为PUT请求,同时正常解析multipart数据。

方案二:添加中间件支持PUT/PATCH的multipart解析

创建中间件app/Http/Middleware/ParseMultipartPut.php:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ParseMultipartPut
{
    public function handle(Request $request, Closure $next)
    {
        if (in_array($request->method(), ['PUT', 'PATCH']) && $request->isMultipartContent()) {
            $request->merge($request->all());
            foreach ($request->files->all() as $key => $file) {
                $request->files->set($key, $file);
            }
        }

        return $next($request);
    }
}

在app/Http/Kernel.php的api中间件组中注册该中间件:

protected $middlewareGroups = [
    'api' => [
        // 原有中间件...
        \App\Http\Middleware\ParseMultipartPut::class,
    ],
];

验证修复效果

修改API控制器返回内容,确认数据是否正常获取:

public function update(Request $request, Culinary $culinary)
{
    return response()->json([
        'status' => 'success',
        'all_data' => $request->all(),
        'title' => $request->input('title'),
        'has_cover_photo' => $request->hasFile('cover_photo'),
        'culinary_id' => $culinary->id
    ]);
}

内容的提问来源于stack exchange,提问作者dapidmini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:09:52