Laravel验证会覆盖我的值吗?

问题描述 投票:1回答:1

我有一个Laravel 5.8(也已通过Laravel 6.1.0测试)作业,该作业会定期从NOAA Spacer Weather Prediction Centre下载文件。作为工作的一部分,我想先验证一些属性,然后再将它们插入数据库,如果情况不对,则使工作失败。

SWPC文件是一个JSON文件,其中包含如下所示的对象数组:

  [{
    time_tag: "2019-10-02T13:39:00",
    bt: 4.45,
    bz_gsm: 0.09,
    // (there are lots of other, irrelevant fields here)
  }, {
    // (more of the same data here, repeated dozens of times)
  }]

我工作的主要部分如下:


  $request = $guzzle->request('GET', 'https://services.swpc.noaa.gov/json/rtsw/rtsw_mag_1m.json');
  $imf = collect(json_decode($request->getBody()->__toString()));

  Validator::make($imf->all(), [
    '*.time_tag' => 'required|date', // Must be a valid date
    '*.bt' => 'required', // Bt must be present
    '*.bz_gsm' => 'required', // Bz must be present
  ])->validate();

  dd($imf->first());


根据the documentation,在手动创建的Validator上调用validate()的行为应与您验证请求对象的行为相同(即:“如果验证失败,则用户将被自动重定向,或者,如果验证失败, AJAX请求,将返回JSON响应“)

然而,以上代码通过了验证,但是time_tagbtbz_gsm字段为空。如果删除time_tag验证规则,则time_tag不再为null(但btbz_gsm为null)。与btbz_gsm字段相同。基本上任何经过验证的字段都为空。

如果我将验证码更改为此:

  $validator = Validator::make($imf->all(), [
    '*.time_tag' => 'required|date', 
    '*.bt' => 'required|file', // Bt is not an uploaded file! Validation should fail.
    '*.bz_gsm' => 'required',
  ]);

  dd($validator->fails());

然后failsfalse(即验证通过)。如果I dd($imf->first()),则time_tagbtbz_gsm再次为空,而$imf中的所有其他元素均为原始值。

据我所知,我的匹配是正确的,因为之前的dd($imf->all())给出了很多如下所示的输出:

array:2031 [
  0 => {#922
    +"time_tag": "2019-10-02T23:55:00"
    +"active": true
    +"source": "ACE"
    +"range": null
    +"scale": null
    +"sensitivity": null
    +"manual_mode": false
    +"sample_size": 60
    +"bt": 3.48
    +"bx_gse": -3.13
    +"by_gse": 0.58
    +"bz_gse": 1.4
    +"theta_gse": 23.73
    +"phi_gse": 169.57
    +"bx_gsm": -3.13
    +"by_gsm": 0.9
    +"bz_gsm": 1.23
    +"theta_gsm": 20.65
    +"phi_gsm": 164.0
    +"max_telemetry_flag": 0
    +"max_data_flag": 0
    +"overall_quality": 0
  }
// ... a few thousand more lines of output here

经过验证后dd($imf->all())给了我:

array:2032 [
  0 => {#922
    +"time_tag": null
    +"active": true
    +"source": "ACE"
    +"range": null
    +"scale": null
    +"sensitivity": null
    +"manual_mode": false
    +"sample_size": 60
    +"bt": null
    +"bx_gse": -3.16
    +"by_gse": 0.94
    +"bz_gse": 1.2
    +"theta_gse": 20.01
    +"phi_gse": 163.43
    +"bx_gsm": -3.15
    +"by_gsm": 1.2
    +"bz_gsm": null
    +"theta_gsm": 15.69
    +"phi_gsm": 159.09
    +"max_telemetry_flag": 0
    +"max_data_flag": 0
    +"overall_quality": 0
  }
// ... a few thousand more lines of output here

因此,它正在查找所需的密钥,而只是在保留其余信息的同时将其覆盖。

是否存在一些用于验证数据数组或在Laravel作业中验证数据的隐藏技巧?

php laravel
1个回答
0
投票

您可以在dd()中看到,传递给验证器的是stdObjects数组(当它看到json_decode()时,这是{}的默认值)。但是,验证器的'*.blah'符号实际上是用于验证数组的数组。显然,您发现将对象或数组传递给它时会遇到奇怪的行为。

简单的解决方法是将second argumenttrue传递给json_decode(),这会将对象转换为关联数组,以便验证程序可以正确解析它们。

$imf = collect(json_decode($request->getBody()->__toString(), true));
© www.soinside.com 2019 - 2024. All rights reserved.