英文:
Laravel Excel `prepareForValidation` method being called twice per row
问题
我目前正在使用Laravel Excel包开发Excel导入功能。我正在实现OnEachRow
、WithHeadingRow
、WithValidation
、SkipsEmptyRows
、SkipsOnFailure
、SkipsOnError
和WithEvents
接口。
我的类使用prepareForValidation
方法在数据被验证之前准备和操作数据。然而,似乎在导入过程中,prepareForValidation
方法对每一行都被调用了两次。这导致了意外的结果。
以下是我在prepareForValidation
方法中使用的代码段:
public function prepareForValidation($data, $index)
{
dump($index, $data); // 调试
$rules = $this->rules();
foreach ($data as $key => $value) {
if (empty($rules[$key]))
continue;
if (in_array('date', $rules[$key])) {
$data[$key] = Date::excelToDateTimeObject($value);
}
if (in_array('boolean', $rules[$key])) {
$data[$key] = human2Bool($value);
}
}
unset($data['']);
dump($data); //调试
return $data;
}
如你所见,在prepareForValidation
方法中,我将Excel日期转换为DateTime对象,将一些布尔值从人类可读格式转换为布尔格式。然而,奇怪的是,如果我删除Date::excelToDateTimeObject
的转换,这种行为就不会发生...
第一次prepareForValidation
调用:
"行索引:" 3
"函数开始时的数据:"
array:8 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"" => 1
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => "n"
"end_at" => 45056
"duration" => null
"methodological_status" => null
]
"函数结束时的数据:"
array:7 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => false
"end_at" => "2023-05-10"
"duration" => null
"methodological_status" => null
]
第二次prepareForValidation
调用:
"行索引:" 3
"函数开始时的数据:"
array:8 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"" => "1"
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => "n"
"end_at" => "45056"
"duration" => null
"methodological_status" => null
]
"函数结束时的数据:"
array:7 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => false
"end_at" => "2023-05-10"
"duration" => null
"methodological_status" => null
]
如上所示,在第一次prepareForValidation
调用期间,'end_at'字段是一个整数(Excel的数字日期格式)。转换后,它变成了一个DateTime对象("2023-05-10")。然而,在第二次prepareForValidation
调用期间,'end_at'字段再次变成了字符串("45056")。
我尝试将'end_at'验证规则更改为date_format:Y-m-d
,但问题仍然存在。
有人之前遇到过这个问题吗?有没有解释为什么prepareForValidation
会对每一行调用两次的情况,以及如何防止这种情况发生?
我正在使用Laravel Excel版本3.1
。
非常感谢任何帮助。
英文:
I'm currently working on an Excel import feature using the Laravel Excel package. I'm implementing OnEachRow
, WithHeadingRow
, WithValidation
, SkipsEmptyRows
, SkipsOnFailure
, SkipsOnError
, and WithEvents
interfaces.
My class uses prepareForValidation
method to prepare and manipulate the data before it's validated. However, it seems that prepareForValidation
is being called twice for each row during the import process. This is leading to unexpected results.
Here's an excerpt of my class where I'm using prepareForValidation
:
public function prepareForValidation($data, $index)
{
dump($index, $data); // debug
$rules = $this->rules();
foreach ($data as $key => $value) {
if (empty($rules[$key]))
continue;
if (in_array('date', $rules[$key])) {
$data[$key] = Date::excelToDateTimeObject($value);
}
if (in_array('boolean', $rules[$key])) {
$data[$key] = human2Bool($value);
}
}
unset($data['']);
dump($data); //debug
return $data;
}
As you can see, in the prepareForValidation
method, I'm converting Excel dates into a DateTime object and some booleans from human readable format to boolean format. However, it seems that the function is called again with the same row data, after the initial data transformation. The strange thing is, that if I remove the Date::excelToDateTimeObject
transformation, this behavior does not happen...
First prepareForValidation
call:
"row index:" 3
"data at the beginning of the function:"
array:8 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"" => 1
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => "n"
"end_at" => 45056
"duration" => null
"methodological_status" => null
]
"data at the end of the function:"
array:7 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => false
"end_at" => "2023-05-10"
"duration" => null
"methodological_status" => null
]
Second prepareForValidation
call:
"row index:" 3
"data at the beginning of the function:"
array:8 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"" => "1"
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => "n"
"end_at" => "45056"
"duration" => null
"methodological_status" => null
]
"data at the end of the function:"
array:7 [
"name" => "Test one"
"uuid" => "656e9c21-b77a-4a9a-ba3d-e2490effcadd"
"execution_structure_id" => "fc1fbdf8-ea73-4d0a-a9a5-f1530a3d49b8"
"is_locked" => false
"end_at" => "2023-05-10"
"duration" => null
"methodological_status" => null
]
As seen above, during the first call of prepareForValidation
, the 'end_at' field is an integer (Excel's numeric date format). After conversion, it turns into a DateTime object ("2023-05-10"). However, in the second call of prepareForValidation
, the 'end_at' field has reverted to being a string again ("45056").
I tried changing the 'end_at' validation rule to date_format:Y-m-d
but the issue persists.
Has anyone experienced this before? Is there any explanation for why prepareForValidation
would be called twice per row and how can I prevent this from happening?
I'm using the Laravel Excel version 3.1
.
Any help would be much appreciated.
答案1
得分: 0
在我的 public function onRow(Row $row)
中,我使用了 $row->toCollection()
和 $row->toArray()
。这些会重新触发验证过程,从而再次调用 prepareForValidation
...
英文:
Okay, I got it! In my public function onRow(Row $row)
I use $row->toCollection()
and $row->toArray()
. Those are retriggering the validation process and with that the prepareForValidation
gets also called again...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论