使用 Laravel 请求在更新方法上传递空字段

Pass empty fields on the update method using Laravel Request

我正在通过经典提交的表单获取数据,但出于某种原因,我没有获得请求中的所有输入数据,它只更新收到的数据。

Model::find($id)->update($request->all());

这有点问题,因为我的数据库中有多个可为空的字段,有时我想传递空字段(即当用户清除输入然后提交表单时)

您是否也知道将空字段传递给请求的方法?

问题是,Laravel 默认通过 ConvertEmptyStringsToNull 中间件将 '' 值转换为 null。检查您的内核:

app/Http/Kernel.php

protected $middleware = [
    // ...
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    // ...
];

此中间件执行以下操作:

protected function transform($key, $value)
{
    return is_string($value) && $value === '' ? null : $value;
}

如您所见,如果给定属性的值为 '',它将被转换为 null

因此,为避免这种情况,您可以在内核文件中注释该中间件。但请注意这一点,因为这将应用于您的整个应用程序。

您可以使用 php array_merge() 就像我使用的代码一样

$contentCategory->update(array_merge($request->all(), ["FIELD1" => '',"FIELD2" => '']));

或测试此代码:

$request->request->add(['FIELD1' => '','FIELD2' => '']);

Input Trimming & Normalization
Laravel 版本 > 5.4 已包含以下功能:


对于 5.4 以下的版本: 使用以下代码制作一个新的中间件:

public function handle($request, Closure $next)
{
    foreach ($request->input() as $key => $value) {
        if (! $value) {
            $request->request->set($key, NULL);
        }
    }

    return $next($request);
}

并将其分配给您希望它发生的路由或控制器方法:

Route::post('/route/{id}', [
   'middleware' => NewMiddleware::class,
], function (Request $request, $id) {
    Model::find($id)->update($request->all());
});

记住: create()update() 等方法适用于模型中 $fillable 数组中的字段:

class User extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'contact', ];
}

或者,如果您想排除某些字段并包含其余字段,请改用 $guarded 数组:

class User extends Model
{
    /**
     * The attributes that aren't mass assignable.
     *
     * @var array
     */
    protected $guarded = ['details'];
}

如果你的字段不在"Model"class的$fillable数组中,update()方法将对该字段不起作用!!!

参考:Mass Assignment

我设法让它工作:在我的网络应用程序上我禁用了 ConvertEmptyStringsToNull 中间件(评论它)所以当我记录 $request 我得到空值 '' 和 API, $request 记录每个字段的 null 值。