我有一个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_tag
,bt
和bz_gsm
字段为空。如果删除time_tag
验证规则,则time_tag
不再为null(但bt
和bz_gsm
为null)。与bt
和bz_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());
然后fails
为false
(即验证通过)。如果I dd($imf->first())
,则time_tag
,bt
和bz_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作业中验证数据的隐藏技巧?
您可以在dd()
中看到,传递给验证器的是stdObjects数组(当它看到json_decode()
时,这是{}
的默认值)。但是,验证器的'*.blah'
符号实际上是用于验证数组的数组。显然,您发现将对象或数组传递给它时会遇到奇怪的行为。
简单的解决方法是将second argument的true
传递给json_decode()
,这会将对象转换为关联数组,以便验证程序可以正确解析它们。
$imf = collect(json_decode($request->getBody()->__toString(), true));